2 Trace reporting for the Dp utility.
4 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/TimerLib.h>
21 #include <Library/PeCoffGetEntryPointLib.h>
22 #include <Library/PerformanceLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/HiiLib.h>
25 #include <Library/PcdLib.h>
27 #include <Guid/Performance.h>
31 #include "DpInternal.h"
34 Collect verbose statistics about the logged performance measurements.
36 General Summary information for all Trace measurements is gathered and
37 stored within the SummaryData structure. This information is both
38 used internally by subsequent reporting functions, and displayed
39 at the end of verbose reports.
41 @pre The SummaryData and CumData structures must be initialized
42 prior to calling this function.
44 @post The SummaryData and CumData structures contain statistics for the
45 current performance logs.
47 @param[in, out] CustomCumulativeData A pointer to the cumtom cumulative data.
52 IN OUT PERF_CUM_DATA
*CustomCumulativeData OPTIONAL
55 MEASUREMENT_RECORD Measurement
;
61 while ((LogEntryKey
= GetPerformanceMeasurementEx (
66 &Measurement
.StartTimeStamp
,
67 &Measurement
.EndTimeStamp
,
68 &Measurement
.Identifier
)) != 0)
70 ++SummaryData
.NumTrace
; // Count the number of TRACE Measurement records
71 if (Measurement
.EndTimeStamp
== 0) {
72 ++SummaryData
.NumIncomplete
; // Count the incomplete records
76 if (Measurement
.Handle
!= NULL
) {
77 ++SummaryData
.NumHandles
; // Count the number of measurements with non-NULL handles
80 if (IsPhase( &Measurement
)) {
81 ++SummaryData
.NumSummary
; // Count the number of major phases
83 else { // !IsPhase(...
84 if(Measurement
.Handle
== NULL
) {
85 ++SummaryData
.NumGlobal
;
89 if (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) == 0) {
90 ++SummaryData
.NumPEIMs
; // Count PEIM measurements
93 Duration
= GetDuration (&Measurement
);
94 TIndex
= GetCumulativeItem (&Measurement
);
96 CumData
[TIndex
].Duration
+= Duration
;
97 CumData
[TIndex
].Count
++;
98 if ( Duration
< CumData
[TIndex
].MinDur
) {
99 CumData
[TIndex
].MinDur
= Duration
;
101 if ( Duration
> CumData
[TIndex
].MaxDur
) {
102 CumData
[TIndex
].MaxDur
= Duration
;
107 // Collect the data for custom cumulative data.
109 if ((CustomCumulativeData
!= NULL
) && (AsciiStrCmp (Measurement
.Token
, CustomCumulativeData
->Name
) == 0)) {
110 CustomCumulativeData
->Duration
+= Duration
;
111 CustomCumulativeData
->Count
++;
112 if (Duration
< CustomCumulativeData
->MinDur
) {
113 CustomCumulativeData
->MinDur
= Duration
;
115 if (Duration
> CustomCumulativeData
->MaxDur
) {
116 CustomCumulativeData
->MaxDur
= Duration
;
123 Gather and print ALL Trace Records.
125 Displays all "interesting" Trace measurements in order.<BR>
126 The number of records displayed is controlled by:
127 - records with a duration less than mInterestThreshold microseconds are not displayed.
128 - No more than Limit records are displayed. A Limit of zero will not limit the output.
129 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
132 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
133 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
134 They must not be in use by a calling function.
136 @param[in] Limit The number of records to print. Zero is ALL.
137 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
139 @retval EFI_SUCCESS The operation was successful.
140 @retval EFI_ABORTED The user aborts the operation.
141 @return Others from a call to gBS->LocateHandleBuffer().
146 IN BOOLEAN ExcludeFlag
149 MEASUREMENT_RECORD Measurement
;
152 const CHAR16
*IncFlag
;
158 EFI_HANDLE
*HandleBuffer
;
161 EFI_STRING StringPtrUnknown
;
163 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
164 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_ALL
), NULL
);
165 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
166 (IncFlag
== NULL
) ? StringPtrUnknown
: IncFlag
);
167 FreePool (StringPtrUnknown
);
169 // Get Handle information
171 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
172 if (EFI_ERROR (Status
)) {
173 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR
), Status
);
176 // We have successfully populated the HandleBuffer
177 // Display ALL Measurement Records
178 // Up to Limit lines displayed
179 // Display only records with Elapsed times >= mInterestThreshold
180 // Display driver names in Module field for records with Handles.
183 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2
) );
184 PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2
) );
186 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR
) );
187 PrintToken (STRING_TOKEN (STR_DP_DASHES
) );
193 while ( WITHIN_LIMIT(Count
, Limit
) &&
194 ((LogEntryKey
= GetPerformanceMeasurementEx (
199 &Measurement
.StartTimeStamp
,
200 &Measurement
.EndTimeStamp
,
201 &Measurement
.Identifier
)) != 0)
204 ++Index
; // Count every record. First record is 1.
206 SafeFreePool ((VOID
*) IncFlag
);
207 if (Measurement
.EndTimeStamp
!= 0) {
208 Duration
= GetDuration (&Measurement
);
209 ElapsedTime
= DurationInMicroSeconds ( Duration
);
210 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_COMPLETE
), NULL
);
213 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_INCOMPLETE
), NULL
); // Mark incomplete records
215 if (((Measurement
.EndTimeStamp
!= 0) && (ElapsedTime
< mInterestThreshold
)) ||
216 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
217 ) { // Ignore "uninteresting" or excluded records
220 ++Count
; // Count the number of records printed
222 // If Handle is non-zero, see if we can determine a name for the driver
223 AsciiStrToUnicodeStrS (Measurement
.Module
, mGaugeString
, sizeof (mGaugeString
) / sizeof (mGaugeString
[0])); // Use Module by default
224 AsciiStrToUnicodeStrS (Measurement
.Token
, mUnicodeToken
, sizeof (mUnicodeToken
) / sizeof (mUnicodeToken
[0]));
225 if (Measurement
.Handle
!= NULL
) {
226 // See if the Handle is in the HandleBuffer
227 for (TIndex
= 0; TIndex
< HandleCount
; TIndex
++) {
228 if (Measurement
.Handle
== HandleBuffer
[TIndex
]) {
229 GetNameFromHandle (HandleBuffer
[TIndex
]);
235 if (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) == 0) {
236 UnicodeSPrint (mGaugeString
, sizeof (mGaugeString
), L
"%g", Measurement
.Handle
);
239 // Ensure that the argument strings are not too long.
240 mGaugeString
[DP_GAUGE_STRING_LENGTH
] = 0;
241 mUnicodeToken
[13] = 0;
244 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2
),
245 Index
, // 1 based, Which measurement record is being printed
251 Measurement
.Identifier
254 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS
),
255 Index
, // 1 based, Which measurement record is being printed
263 if (ShellGetExecutionBreakFlag ()) {
264 Status
= EFI_ABORTED
;
269 if (HandleBuffer
!= NULL
) {
270 FreePool (HandleBuffer
);
272 SafeFreePool ((VOID
*) IncFlag
);
277 Gather and print Raw Trace Records.
279 All Trace measurements with a duration greater than or equal to
280 mInterestThreshold are printed without interpretation.
282 The number of records displayed is controlled by:
283 - records with a duration less than mInterestThreshold microseconds are not displayed.
284 - No more than Limit records are displayed. A Limit of zero will not limit the output.
285 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
288 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
290 @param[in] Limit The number of records to print. Zero is ALL.
291 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
293 @retval EFI_SUCCESS The operation was successful.
294 @retval EFI_ABORTED The user aborts the operation.
299 IN BOOLEAN ExcludeFlag
302 MEASUREMENT_RECORD Measurement
;
309 EFI_STRING StringPtr
;
310 EFI_STRING StringPtrUnknown
;
313 Status
= EFI_SUCCESS
;
315 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
316 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_RAWTRACE
), NULL
);
317 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
318 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
319 FreePool (StringPtr
);
320 FreePool (StringPtrUnknown
);
323 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR2
) );
324 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES2
) );
326 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR
) );
327 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES
) );
333 while ( WITHIN_LIMIT(Count
, Limit
) &&
334 ((LogEntryKey
= GetPerformanceMeasurementEx (
339 &Measurement
.StartTimeStamp
,
340 &Measurement
.EndTimeStamp
,
341 &Measurement
.Identifier
)) != 0)
344 ++Index
; // Count every record. First record is 1.
346 if (Measurement
.EndTimeStamp
!= 0) {
347 Duration
= GetDuration (&Measurement
);
348 ElapsedTime
= DurationInMicroSeconds ( Duration
);
350 if ((ElapsedTime
< mInterestThreshold
) ||
351 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
352 ) { // Ignore "uninteresting" or Excluded records
355 ++Count
; // Count the number of records printed
358 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS2
),
359 Index
, // 1 based, Which measurement record is being printed
361 Measurement
.StartTimeStamp
,
362 Measurement
.EndTimeStamp
,
365 Measurement
.Identifier
368 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS
),
369 Index
, // 1 based, Which measurement record is being printed
371 Measurement
.StartTimeStamp
,
372 Measurement
.EndTimeStamp
,
377 if (ShellGetExecutionBreakFlag ()) {
378 Status
= EFI_ABORTED
;
386 Gather and print Major Phase metrics.
388 @param[in] Ticker The timer value for the END of Shell phase
396 MEASUREMENT_RECORD Measurement
;
397 UINT64 BdsTimeoutValue
;
406 EFI_STRING StringPtr
;
408 EFI_STRING StringPtrUnknown
;
417 // Get Execution Phase Statistics
419 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
420 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_PHASES
), NULL
);
421 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
422 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
423 FreePool (StringPtr
);
424 FreePool (StringPtrUnknown
);
427 while ((LogEntryKey
= GetPerformanceMeasurementEx (
432 &Measurement
.StartTimeStamp
,
433 &Measurement
.EndTimeStamp
,
434 &Measurement
.Identifier
)) != 0)
436 if (AsciiStrnCmp (Measurement
.Token
, ALit_SHELL
, PERF_TOKEN_LENGTH
) == 0) {
437 Measurement
.EndTimeStamp
= Ticker
;
439 if (Measurement
.EndTimeStamp
== 0) { // Skip "incomplete" records
442 Duration
= GetDuration (&Measurement
);
443 if ( Measurement
.Handle
!= NULL
444 && (AsciiStrnCmp (Measurement
.Token
, ALit_BdsTO
, PERF_TOKEN_LENGTH
) == 0)
447 BdsTimeoutValue
= Duration
;
448 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_SEC
, PERF_TOKEN_LENGTH
) == 0) {
450 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_PEI
, PERF_TOKEN_LENGTH
) == 0) {
452 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_DXE
, PERF_TOKEN_LENGTH
) == 0) {
454 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_BDS
, PERF_TOKEN_LENGTH
) == 0) {
456 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_SHELL
, PERF_TOKEN_LENGTH
) == 0) {
457 ShellTime
= Duration
;
463 // print SEC phase duration time
466 ElapsedTime
= DurationInMicroSeconds ( SecTime
); // Calculate elapsed time in microseconds
467 Total
+= DivU64x32 (ElapsedTime
, 1000); // Accumulate time in milliseconds
468 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE
), ElapsedTime
);
471 // print PEI phase duration time
474 ElapsedTime
= DivU64x32 (
476 (UINT32
)TimerInfo
.Frequency
478 Total
+= ElapsedTime
;
479 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_PEI
, ElapsedTime
);
482 // print DXE phase duration time
485 ElapsedTime
= DivU64x32 (
487 (UINT32
)TimerInfo
.Frequency
489 Total
+= ElapsedTime
;
490 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_DXE
, ElapsedTime
);
493 // print BDS phase duration time
496 ElapsedTime
= DivU64x32 (
498 (UINT32
)TimerInfo
.Frequency
500 Total
+= ElapsedTime
;
501 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_BDS
, ElapsedTime
);
504 if (BdsTimeoutValue
> 0) {
505 ElapsedTime
= DivU64x32 (
507 (UINT32
)TimerInfo
.Frequency
509 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO
), ALit_BdsTO
, ElapsedTime
);
512 // print SHELL phase duration time
515 ElapsedTime
= DivU64x32 (
517 (UINT32
)TimerInfo
.Frequency
519 Total
+= ElapsedTime
;
520 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_SHELL
, ElapsedTime
);
523 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION
), Total
);
527 Gather and print Handle data.
529 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
531 @retval EFI_SUCCESS The operation was successful.
532 @retval EFI_ABORTED The user aborts the operation.
533 @return Others from a call to gBS->LocateHandleBuffer().
537 IN BOOLEAN ExcludeFlag
540 MEASUREMENT_RECORD Measurement
;
543 EFI_HANDLE
*HandleBuffer
;
544 EFI_STRING StringPtr
;
550 EFI_STRING StringPtrUnknown
;
552 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
553 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_DRIVERS
), NULL
);
554 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
555 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
556 FreePool (StringPtr
);
557 FreePool (StringPtrUnknown
);
559 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
560 if (EFI_ERROR (Status
)) {
561 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR
), Status
);
565 Print (L
"There are %,d Handles defined.\n", (Size
/ sizeof(HandleBuffer
[0])));
569 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2
) );
571 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION
) );
573 PrintToken (STRING_TOKEN (STR_DP_DASHES
) );
577 while ((LogEntryKey
= GetPerformanceMeasurementEx (
582 &Measurement
.StartTimeStamp
,
583 &Measurement
.EndTimeStamp
,
584 &Measurement
.Identifier
)) != 0)
587 Duration
= GetDuration (&Measurement
);
588 ElapsedTime
= DurationInMicroSeconds ( Duration
);
589 if ((ElapsedTime
< mInterestThreshold
) ||
590 (Measurement
.EndTimeStamp
== 0) ||
591 (Measurement
.Handle
== NULL
) ||
592 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
593 ) { // Ignore "uninteresting" or excluded records
596 mGaugeString
[0] = 0; // Empty driver name by default
597 AsciiStrToUnicodeStrS (Measurement
.Token
, mUnicodeToken
, sizeof (mUnicodeToken
) / sizeof (mUnicodeToken
[0]));
598 // See if the Handle is in the HandleBuffer
599 for (Index
= 0; Index
< HandleCount
; Index
++) {
600 if (Measurement
.Handle
== HandleBuffer
[Index
]) {
601 GetNameFromHandle (HandleBuffer
[Index
]); // Name is put into mGaugeString
605 // Ensure that the argument strings are not too long.
606 mGaugeString
[DP_GAUGE_STRING_LENGTH
] = 0;
607 mUnicodeToken
[11] = 0;
608 if (mGaugeString
[0] != 0) {
609 // Display the record if it has a valid handle.
612 STRING_TOKEN (STR_DP_HANDLE_VARS2
),
613 Count
, // 1 based, Which measurement record is being printed
614 Index
+ 1, // 1 based, Which handle is being printed
618 Measurement
.Identifier
622 STRING_TOKEN (STR_DP_HANDLE_VARS
),
623 Count
, // 1 based, Which measurement record is being printed
624 Index
+ 1, // 1 based, Which handle is being printed
631 if (ShellGetExecutionBreakFlag ()) {
632 Status
= EFI_ABORTED
;
637 if (HandleBuffer
!= NULL
) {
638 FreePool (HandleBuffer
);
644 Gather and print PEIM data.
646 Only prints complete PEIM records
648 @retval EFI_SUCCESS The operation was successful.
649 @retval EFI_ABORTED The user aborts the operation.
656 MEASUREMENT_RECORD Measurement
;
659 EFI_STRING StringPtr
;
662 EFI_STRING StringPtrUnknown
;
665 Status
= EFI_SUCCESS
;
667 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
668 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_PEIMS
), NULL
);
669 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
670 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
671 FreePool (StringPtr
);
672 FreePool (StringPtrUnknown
);
675 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION2
));
677 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION
));
679 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
682 while ((LogEntryKey
= GetPerformanceMeasurementEx (
687 &Measurement
.StartTimeStamp
,
688 &Measurement
.EndTimeStamp
,
689 &Measurement
.Identifier
)) != 0)
692 if ((Measurement
.EndTimeStamp
== 0) ||
693 (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) != 0)
698 Duration
= GetDuration (&Measurement
);
699 ElapsedTime
= DurationInMicroSeconds ( Duration
); // Calculate elapsed time in microseconds
700 if (ElapsedTime
>= mInterestThreshold
) {
701 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
703 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS2
),
704 TIndex
, // 1 based, Which measurement record is being printed
705 Measurement
.Handle
, // base address
706 Measurement
.Handle
, // file guid
708 Measurement
.Identifier
711 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS
),
712 TIndex
, // 1 based, Which measurement record is being printed
713 Measurement
.Handle
, // base address
714 Measurement
.Handle
, // file guid
719 if (ShellGetExecutionBreakFlag ()) {
720 Status
= EFI_ABORTED
;
728 Gather and print global data.
730 Strips out incomplete or "Execution Phase" records
731 Only prints records where Handle is NULL
732 Increment TIndex for every record, even skipped ones, so that we have an
733 indication of every measurement record taken.
735 @retval EFI_SUCCESS The operation was successful.
736 @retval EFI_ABORTED The user aborts the operation.
743 MEASUREMENT_RECORD Measurement
;
746 EFI_STRING StringPtr
;
748 UINTN Index
; // Index, or number, of the measurement record being processed
749 EFI_STRING StringPtrUnknown
;
752 Status
= EFI_SUCCESS
;
754 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
755 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_GENERAL
), NULL
);
756 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
757 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
758 FreePool (StringPtr
);
759 FreePool (StringPtrUnknown
);
762 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2
));
764 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION
));
766 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
771 while ((LogEntryKey
= GetPerformanceMeasurementEx (
776 &Measurement
.StartTimeStamp
,
777 &Measurement
.EndTimeStamp
,
778 &Measurement
.Identifier
)) != 0)
780 AsciiStrToUnicodeStrS (Measurement
.Module
, mGaugeString
, sizeof (mGaugeString
) / sizeof (mGaugeString
[0]));
781 AsciiStrToUnicodeStrS (Measurement
.Token
, mUnicodeToken
, sizeof (mUnicodeToken
) / sizeof (mUnicodeToken
[0]));
782 mGaugeString
[25] = 0;
783 mUnicodeToken
[31] = 0;
784 if ( ! ( IsPhase( &Measurement
) ||
785 (Measurement
.Handle
!= NULL
) ||
786 (Measurement
.EndTimeStamp
== 0)
789 Duration
= GetDuration (&Measurement
);
790 ElapsedTime
= DurationInMicroSeconds ( Duration
);
791 if (ElapsedTime
>= mInterestThreshold
) {
794 STRING_TOKEN (STR_DP_GLOBAL_VARS2
),
799 Measurement
.Identifier
803 STRING_TOKEN (STR_DP_GLOBAL_VARS
),
812 if (ShellGetExecutionBreakFlag ()) {
813 Status
= EFI_ABORTED
;
822 Gather and print cumulative data.
824 Traverse the measurement records and:<BR>
825 For each record with a Token listed in the CumData array:<BR>
826 - Update the instance count and the total, minimum, and maximum durations.
827 Finally, print the gathered cumulative statistics.
829 @param[in] CustomCumulativeData A pointer to the cumtom cumulative data.
834 IN PERF_CUM_DATA
*CustomCumulativeData OPTIONAL
837 UINT64 AvgDur
; // the computed average duration
841 EFI_STRING StringPtr
;
843 EFI_STRING StringPtrUnknown
;
845 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
846 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE
), NULL
);
847 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
848 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
849 FreePool (StringPtr
);
850 FreePool (StringPtrUnknown
);
852 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1
));
853 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2
));
854 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
856 for ( TIndex
= 0; TIndex
< NumCum
; ++TIndex
) {
857 if (CumData
[TIndex
].Count
!= 0) {
858 AvgDur
= DivU64x32 (CumData
[TIndex
].Duration
, CumData
[TIndex
].Count
);
859 AvgDur
= DurationInMicroSeconds(AvgDur
);
860 Dur
= DurationInMicroSeconds(CumData
[TIndex
].Duration
);
861 MaxDur
= DurationInMicroSeconds(CumData
[TIndex
].MaxDur
);
862 MinDur
= DurationInMicroSeconds(CumData
[TIndex
].MinDur
);
864 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS
),
865 CumData
[TIndex
].Name
,
866 CumData
[TIndex
].Count
,
876 // Print the custom cumulative data.
878 if (CustomCumulativeData
!= NULL
) {
879 if (CustomCumulativeData
->Count
!= 0) {
880 AvgDur
= DivU64x32 (CustomCumulativeData
->Duration
, CustomCumulativeData
->Count
);
881 AvgDur
= DurationInMicroSeconds (AvgDur
);
882 Dur
= DurationInMicroSeconds (CustomCumulativeData
->Duration
);
883 MaxDur
= DurationInMicroSeconds (CustomCumulativeData
->MaxDur
);
884 MinDur
= DurationInMicroSeconds (CustomCumulativeData
->MinDur
);
891 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS
),
892 CustomCumulativeData
->Name
,
893 CustomCumulativeData
->Count
,