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