]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/DpTrace.c
Refine code to make code follow the coding style.
[mirror_edk2.git] / PerformancePkg / Dp_App / DpTrace.c
1 /** @file
2 * Trace reporting for the Dp utility.
3 *
4 * Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 **/
13
14 #include <Library/BaseLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/TimerLib.h>
20 #include <Library/PeCoffGetEntryPointLib.h>
21 #include <Library/PerformanceLib.h>
22 #include <Library/PrintLib.h>
23 #include <Library/HiiLib.h>
24 #include <Library/PcdLib.h>
25
26 #include <Guid/Performance.h>
27
28 #include "Dp.h"
29 #include "Literals.h"
30 #include "DpInternal.h"
31
32 /**
33 Collect verbose statistics about the logged performance measurements.
34
35 General Summary information for all Trace measurements is gathered and
36 stored within the SummaryData structure. This information is both
37 used internally by subsequent reporting functions, and displayed
38 at the end of verbose reports.
39
40 @pre The SummaryData and CumData structures must be initialized
41 prior to calling this function.
42
43 @post The SummaryData and CumData structures contain statistics for the
44 current performance logs.
45 **/
46 VOID
47 GatherStatistics(
48 VOID
49 )
50 {
51 MEASUREMENT_RECORD Measurement;
52 UINT64 Duration;
53 UINTN LogEntryKey;
54 INTN TIndex;
55
56 LogEntryKey = 0;
57 while ((LogEntryKey = GetPerformanceMeasurement (
58 LogEntryKey,
59 &Measurement.Handle,
60 &Measurement.Token,
61 &Measurement.Module,
62 &Measurement.StartTimeStamp,
63 &Measurement.EndTimeStamp)) != 0)
64 {
65 ++SummaryData.NumTrace; // Count the number of TRACE Measurement records
66 if (Measurement.EndTimeStamp == 0) {
67 ++SummaryData.NumIncomplete; // Count the incomplete records
68 continue;
69 }
70
71 if (Measurement.Handle != NULL) {
72 ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles
73 }
74
75 if (IsPhase( &Measurement)) {
76 ++SummaryData.NumSummary; // Count the number of major phases
77 }
78 else { // !IsPhase(...
79 if(Measurement.Handle == NULL) {
80 ++SummaryData.NumGlobal;
81 }
82 }
83
84 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
85 ++SummaryData.NumPEIMs; // Count PEIM measurements
86 }
87
88 Duration = GetDuration (&Measurement);
89 TIndex = GetCumulativeItem (&Measurement);
90 if (TIndex >= 0) {
91 CumData[TIndex].Duration += Duration;
92 CumData[TIndex].Count++;
93 if ( Duration < CumData[TIndex].MinDur ) {
94 CumData[TIndex].MinDur = Duration;
95 }
96 if ( Duration > CumData[TIndex].MaxDur ) {
97 CumData[TIndex].MaxDur = Duration;
98 }
99 }
100 }
101 }
102
103 /**
104 Gather and print ALL Trace Records.
105
106 Displays all "interesting" Trace measurements in order.<BR>
107 The number of records displayed is controlled by:
108 - records with a duration less than mInterestThreshold microseconds are not displayed.
109 - No more than Limit records are displayed. A Limit of zero will not limit the output.
110 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
111 displayed.
112
113 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
114 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
115 They must not be in use by a calling function.
116
117 @param[in] Limit The number of records to print. Zero is ALL.
118 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
119
120 **/
121 VOID
122 DumpAllTrace(
123 IN UINTN Limit,
124 IN BOOLEAN ExcludeFlag
125 )
126 {
127 MEASUREMENT_RECORD Measurement;
128 UINT64 ElapsedTime;
129 UINT64 Duration;
130 const CHAR16 *IncFlag;
131 UINTN LogEntryKey;
132 UINTN Count;
133 UINTN Index;
134 UINTN TIndex;
135
136 EFI_HANDLE *HandleBuffer;
137 UINTN Size;
138 EFI_HANDLE TempHandle;
139 EFI_STATUS Status;
140
141 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);
142 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
143 (IncFlag == NULL) ? ALit_UNKNOWN: IncFlag);
144
145 // Get Handle information
146 //
147 Size = 0;
148 HandleBuffer = &TempHandle;
149 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
150 if (Status == EFI_BUFFER_TOO_SMALL) {
151 HandleBuffer = AllocatePool (Size);
152 ASSERT (HandleBuffer != NULL);
153 if (HandleBuffer == NULL) {
154 return;
155 }
156 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
157 }
158 if (EFI_ERROR (Status)) {
159 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
160 }
161 else {
162 // We have successfully populated the HandleBuffer
163 // Display ALL Measurement Records
164 // Up to Limit lines displayed
165 // Display only records with Elapsed times >= mInterestThreshold
166 // Display driver names in Module field for records with Handles.
167 //
168 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR) );
169 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
170
171 LogEntryKey = 0;
172 Count = 0;
173 Index = 0;
174 while ( WITHIN_LIMIT(Count, Limit) &&
175 ((LogEntryKey = GetPerformanceMeasurement (
176 LogEntryKey,
177 &Measurement.Handle,
178 &Measurement.Token,
179 &Measurement.Module,
180 &Measurement.StartTimeStamp,
181 &Measurement.EndTimeStamp)) != 0)
182 )
183 {
184 ++Index; // Count every record. First record is 1.
185 ElapsedTime = 0;
186 if (Measurement.EndTimeStamp != 0) {
187 Duration = GetDuration (&Measurement);
188 ElapsedTime = DurationInMicroSeconds ( Duration );
189 IncFlag = STR_DP_COMPLETE;
190 }
191 else {
192 IncFlag = STR_DP_INCOMPLETE; // Mark incomplete records
193 }
194 if ((ElapsedTime < mInterestThreshold) ||
195 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
196 ) { // Ignore "uninteresting" or excluded records
197 continue;
198 }
199 if (Measurement.EndTimeStamp == 0) {
200 ElapsedTime = Measurement.StartTimeStamp;
201 }
202 ++Count; // Count the number of records printed
203
204 // If Handle is non-zero, see if we can determine a name for the driver
205 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default
206 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
207 if (Measurement.Handle != NULL) {
208 // See if the Handle is in the HandleBuffer
209 for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) {
210 if (Measurement.Handle == HandleBuffer[TIndex]) {
211 GetNameFromHandle (HandleBuffer[TIndex]);
212 break;
213 }
214 }
215 }
216 // Ensure that the argument strings are not too long.
217 mGaugeString[31] = 0;
218 mUnicodeToken[18] = 0;
219
220 PrintToken( STRING_TOKEN (STR_DP_ALL_STATS),
221 Index, // 1 based, Which measurement record is being printed
222 IncFlag,
223 Measurement.Handle,
224 mGaugeString,
225 mUnicodeToken,
226 ElapsedTime
227 );
228 }
229 }
230 if (HandleBuffer != &TempHandle) {
231 FreePool (HandleBuffer);
232 }
233 }
234
235 /**
236 Gather and print Raw Trace Records.
237
238 All Trace measurements with a duration greater than or equal to
239 mInterestThreshold are printed without interpretation.
240
241 The number of records displayed is controlled by:
242 - records with a duration less than mInterestThreshold microseconds are not displayed.
243 - No more than Limit records are displayed. A Limit of zero will not limit the output.
244 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
245 displayed.
246
247 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
248
249 @param[in] Limit The number of records to print. Zero is ALL.
250 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
251
252 **/
253 VOID
254 DumpRawTrace(
255 IN UINTN Limit,
256 IN BOOLEAN ExcludeFlag
257 )
258 {
259 MEASUREMENT_RECORD Measurement;
260 UINT64 ElapsedTime;
261 UINT64 Duration;
262 UINTN LogEntryKey;
263 UINTN Count;
264 UINTN Index;
265
266 EFI_STRING StringPtr;
267
268 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);
269 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
270 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);
271
272 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR) );
273 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES) );
274
275 LogEntryKey = 0;
276 Count = 0;
277 Index = 0;
278 while ( WITHIN_LIMIT(Count, Limit) &&
279 ((LogEntryKey = GetPerformanceMeasurement (
280 LogEntryKey,
281 &Measurement.Handle,
282 &Measurement.Token,
283 &Measurement.Module,
284 &Measurement.StartTimeStamp,
285 &Measurement.EndTimeStamp)) != 0)
286 )
287 {
288 ++Index; // Count every record. First record is 1.
289 ElapsedTime = 0;
290 if (Measurement.EndTimeStamp != 0) {
291 Duration = GetDuration (&Measurement);
292 ElapsedTime = DurationInMicroSeconds ( Duration );
293 }
294 if ((ElapsedTime < mInterestThreshold) ||
295 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
296 ) { // Ignore "uninteresting" or Excluded records
297 continue;
298 }
299 ++Count; // Count the number of records printed
300 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS),
301 Index, // 1 based, Which measurement record is being printed
302 Measurement.Handle,
303 Measurement.StartTimeStamp,
304 Measurement.EndTimeStamp,
305 Measurement.Token,
306 Measurement.Module
307 );
308 }
309 }
310
311 /**
312 Gather and print Major Phase metrics.
313
314 @param[in] Ticker The timer value for the END of Shell phase
315
316 **/
317 VOID
318 ProcessPhases(
319 UINT64 Ticker
320 )
321 {
322 MEASUREMENT_RECORD Measurement;
323 UINT64 BdsTimeoutValue;
324 UINT64 SecTime;
325 UINT64 PeiTime;
326 UINT64 DxeTime;
327 UINT64 BdsTime;
328 UINT64 ShellTime;
329 UINT64 ElapsedTime;
330 UINT64 Duration;
331 UINT64 Total;
332 EFI_STRING StringPtr;
333 UINTN LogEntryKey;
334
335 BdsTimeoutValue = 0;
336 SecTime = 0;
337 PeiTime = 0;
338 DxeTime = 0;
339 BdsTime = 0;
340 ShellTime = 0;
341 //
342 // Get Execution Phase Statistics
343 //
344 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);
345 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
346 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);
347
348 LogEntryKey = 0;
349 while ((LogEntryKey = GetPerformanceMeasurement (
350 LogEntryKey,
351 &Measurement.Handle,
352 &Measurement.Token,
353 &Measurement.Module,
354 &Measurement.StartTimeStamp,
355 &Measurement.EndTimeStamp)) != 0)
356 {
357 if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
358 Measurement.EndTimeStamp = Ticker;
359 }
360 if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records
361 continue;
362 }
363 Duration = GetDuration (&Measurement);
364 if ( Measurement.Handle != NULL
365 && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)
366 )
367 {
368 BdsTimeoutValue = Duration;
369 } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {
370 SecTime = Duration;
371 } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {
372 PeiTime = Duration;
373 } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {
374 DxeTime = Duration;
375 } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {
376 BdsTime = Duration;
377 } else if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
378 ShellTime = Duration;
379 }
380 }
381
382 Total = 0;
383
384 // print SEC phase duration time
385 //
386 if (SecTime > 0) {
387 ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds
388 Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds
389 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE), ElapsedTime);
390 }
391
392 // print PEI phase duration time
393 //
394 if (PeiTime > 0) {
395 ElapsedTime = DivU64x32 (
396 PeiTime,
397 (UINT32)TimerInfo.Frequency
398 );
399 Total += ElapsedTime;
400 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_PEI, ElapsedTime);
401 }
402
403 // print DXE phase duration time
404 //
405 if (DxeTime > 0) {
406 ElapsedTime = DivU64x32 (
407 DxeTime,
408 (UINT32)TimerInfo.Frequency
409 );
410 Total += ElapsedTime;
411 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_DXE, ElapsedTime);
412 }
413
414 // print BDS phase duration time
415 //
416 if (BdsTime > 0) {
417 ElapsedTime = DivU64x32 (
418 BdsTime,
419 (UINT32)TimerInfo.Frequency
420 );
421 Total += ElapsedTime;
422 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_BDS, ElapsedTime);
423 }
424
425 if (BdsTimeoutValue > 0) {
426 ElapsedTime = DivU64x32 (
427 BdsTimeoutValue,
428 (UINT32)TimerInfo.Frequency
429 );
430 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO), ALit_BdsTO, ElapsedTime);
431 }
432
433 // print SHELL phase duration time
434 //
435 if (ShellTime > 0) {
436 ElapsedTime = DivU64x32 (
437 ShellTime,
438 (UINT32)TimerInfo.Frequency
439 );
440 Total += ElapsedTime;
441 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_SHELL, ElapsedTime);
442 }
443
444 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION), Total);
445 }
446
447 /**
448 Gather and print Handle data.
449
450 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
451
452 @return Status from a call to gBS->LocateHandle().
453 **/
454 EFI_STATUS
455 ProcessHandles(
456 IN BOOLEAN ExcludeFlag
457 )
458 {
459 MEASUREMENT_RECORD Measurement;
460 UINT64 ElapsedTime;
461 UINT64 Duration;
462 EFI_HANDLE *HandleBuffer;
463 EFI_STRING StringPtr;
464 UINTN Index;
465 UINTN LogEntryKey;
466 UINTN Count;
467 UINTN Size;
468 EFI_HANDLE TempHandle;
469 EFI_STATUS Status;
470
471 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
472 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
473 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);
474
475 Size = 0;
476 HandleBuffer = &TempHandle;
477 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
478 if (Status == EFI_BUFFER_TOO_SMALL) {
479 HandleBuffer = AllocatePool (Size);
480 ASSERT (HandleBuffer != NULL);
481 if (HandleBuffer == NULL) {
482 return;
483 }
484 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
485 }
486 if (EFI_ERROR (Status)) {
487 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
488 }
489 else {
490 #if DP_DEBUG == 2
491 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));
492 #endif
493
494 PrintToken (STRING_TOKEN (STR_DP_HANDLE_GUID) );
495 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
496
497 LogEntryKey = 0;
498 Count = 0;
499 while ((LogEntryKey = GetPerformanceMeasurement (
500 LogEntryKey,
501 &Measurement.Handle,
502 &Measurement.Token,
503 &Measurement.Module,
504 &Measurement.StartTimeStamp,
505 &Measurement.EndTimeStamp)) != 0)
506 {
507 Count++;
508 Duration = GetDuration (&Measurement);
509 ElapsedTime = DurationInMicroSeconds ( Duration );
510 if ((ElapsedTime < mInterestThreshold) ||
511 (Measurement.EndTimeStamp == 0) ||
512 (Measurement.Handle == NULL) ||
513 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
514 ) { // Ignore "uninteresting" or excluded records
515 continue;
516 }
517 mGaugeString[0] = 0; // Empty driver name by default
518 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
519 // See if the Handle is in the HandleBuffer
520 for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) {
521 if (Measurement.Handle == HandleBuffer[Index]) {
522 GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString
523 break;
524 }
525 }
526 // Ensure that the argument strings are not too long.
527 mGaugeString[31] = 0;
528 mUnicodeToken[18] = 0;
529 if (mGaugeString[0] != 0) {
530 // Display the record if it has a valid handle.
531 PrintToken (
532 STRING_TOKEN (STR_DP_HANDLE_VARS),
533 Count, // 1 based, Which measurement record is being printed
534 Index + 1, // 1 based, Which handle is being printed
535 mGaugeString,
536 mUnicodeToken,
537 ElapsedTime
538 );
539 }
540 }
541 }
542 if (HandleBuffer != &TempHandle) {
543 FreePool (HandleBuffer);
544 }
545 return Status;
546 }
547
548 /**
549 Gather and print PEIM data.
550
551 Only prints complete PEIM records
552
553 **/
554 VOID
555 ProcessPeims(
556 VOID
557 )
558 {
559 MEASUREMENT_RECORD Measurement;
560 UINT64 Duration;
561 UINT64 ElapsedTime;
562 EFI_STRING StringPtr;
563 UINTN LogEntryKey;
564 UINTN TIndex;
565
566
567 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);
568 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
569 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);
570
571 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION));
572 PrintToken (STRING_TOKEN (STR_DP_DASHES));
573 TIndex = 0;
574 LogEntryKey = 0;
575 while ((LogEntryKey = GetPerformanceMeasurement (
576 LogEntryKey,
577 &Measurement.Handle,
578 &Measurement.Token,
579 &Measurement.Module,
580 &Measurement.StartTimeStamp,
581 &Measurement.EndTimeStamp)) != 0)
582 {
583 TIndex++;
584 if ((Measurement.EndTimeStamp == 0) ||
585 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)
586 ) {
587 continue;
588 }
589
590 Duration = GetDuration (&Measurement);
591 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds
592 if (ElapsedTime >= mInterestThreshold) {
593 GetNameFromHandle ((EFI_HANDLE) Measurement.Handle); // Name placed in mGaugeString
594 PrintToken (STRING_TOKEN (STR_DP_PEIM_STAT2),
595 TIndex, // 1 based, Which measurement record is being printed
596 Measurement.Handle,
597 mGaugeString,
598 ElapsedTime
599 );
600 }
601 }
602 }
603
604 /**
605 Gather and print global data.
606
607 Strips out incomplete or "Execution Phase" records
608 Only prints records where Handle is NULL
609 Increment TIndex for every record, even skipped ones, so that we have an
610 indication of every measurement record taken.
611
612 **/
613 VOID
614 ProcessGlobal(
615 VOID
616 )
617 {
618 MEASUREMENT_RECORD Measurement;
619 UINT64 Duration;
620 UINT64 ElapsedTime;
621 EFI_STRING StringPtr;
622 UINTN LogEntryKey;
623 UINTN Index; // Index, or number, of the measurement record being processed
624
625 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
626 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
627 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);
628
629 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION));
630 PrintToken (STRING_TOKEN (STR_DP_DASHES));
631
632 Index = 1;
633 LogEntryKey = 0;
634
635 while ((LogEntryKey = GetPerformanceMeasurement (
636 LogEntryKey,
637 &Measurement.Handle,
638 &Measurement.Token,
639 &Measurement.Module,
640 &Measurement.StartTimeStamp,
641 &Measurement.EndTimeStamp)) != 0)
642 {
643 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);
644 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
645 if ( ! ( IsPhase( &Measurement) ||
646 (Measurement.Handle != NULL) ||
647 (Measurement.EndTimeStamp == 0)
648 ))
649 {
650 Duration = GetDuration (&Measurement);
651 ElapsedTime = DurationInMicroSeconds ( Duration );
652 if (ElapsedTime >= mInterestThreshold) {
653 PrintToken (
654 STRING_TOKEN (STR_DP_FOUR_VARS_2),
655 Index,
656 mGaugeString,
657 mUnicodeToken,
658 ElapsedTime
659 );
660 }
661 }
662 Index++;
663 }
664 }
665
666 /**
667 Gather and print cumulative data.
668
669 Traverse the measurement records and:<BR>
670 For each record with a Token listed in the CumData array:<BR>
671 - Update the instance count and the total, minimum, and maximum durations.
672 Finally, print the gathered cumulative statistics.
673
674 **/
675 VOID
676 ProcessCumulative(
677 VOID
678 )
679 {
680 UINT64 Avgval; // the computed average duration
681 EFI_STRING StringPtr;
682 UINTN TIndex;
683
684
685 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);
686 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
687 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);
688
689 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1));
690 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2));
691 PrintToken (STRING_TOKEN (STR_DP_DASHES));
692
693 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {
694 Avgval = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);
695 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
696 CumData[TIndex].Name,
697 CumData[TIndex].Count,
698 DurationInMicroSeconds(CumData[TIndex].Duration),
699 DurationInMicroSeconds(Avgval),
700 DurationInMicroSeconds(CumData[TIndex].MinDur),
701 DurationInMicroSeconds(CumData[TIndex].MaxDur)
702 );
703 }
704 }