@@ -352,8 +352,8 @@ void CALLBACK EventRecordCallback(EVENT_RECORD* pEventRecord)
352
352
#pragma warning(disable: 4984) // c++17 extension
353
353
354
354
if constexpr (SAVE_FIRST_TIMESTAMP) {
355
- if (session->mStartQpc .QuadPart == 0 ) {
356
- session->mStartQpc = hdr.TimeStamp ;
355
+ if (session->mStartTimestamp .QuadPart == 0 ) {
356
+ session->mStartTimestamp = hdr.TimeStamp ;
357
357
}
358
358
}
359
359
@@ -481,18 +481,19 @@ ULONG TraceSession::Start(
481
481
PMTraceConsumer* pmConsumer,
482
482
MRTraceConsumer* mrConsumer,
483
483
wchar_t const * etlPath,
484
- wchar_t const * sessionName)
484
+ wchar_t const * sessionName,
485
+ TimestampType timestampType)
485
486
{
486
487
assert (mSessionHandle == 0 );
487
488
assert (mTraceHandle == INVALID_PROCESSTRACE_HANDLE);
488
- mStartQpc .QuadPart = 0 ;
489
+ mStartTimestamp .QuadPart = 0 ;
489
490
mPMConsumer = pmConsumer;
490
491
mMRConsumer = mrConsumer;
491
492
mContinueProcessingBuffers = TRUE ;
492
493
493
494
// -------------------------------------------------------------------------
494
495
// Configure trace properties
495
- EVENT_TRACE_LOGFILE traceProps = {};
496
+ EVENT_TRACE_LOGFILEW traceProps = {};
496
497
traceProps.LogFileName = (wchar_t *) etlPath;
497
498
traceProps.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP;
498
499
traceProps.Context = this ;
@@ -528,7 +529,7 @@ ULONG TraceSession::Start(
528
529
529
530
TraceProperties sessionProps = {};
530
531
sessionProps.Wnode .BufferSize = (ULONG) sizeof (TraceProperties);
531
- sessionProps.Wnode .ClientContext = 1 ; // Clock resolution to use when logging the timestamp for each event; 1 == query performance counter
532
+ sessionProps.Wnode .ClientContext = timestampType ; // Clock resolution to use when logging the timestamp for each event
532
533
sessionProps.LogFileMode = EVENT_TRACE_REAL_TIME_MODE; // We have a realtime consumer, not writing to a log file
533
534
sessionProps.LogFileNameOffset = 0 ; // 0 means no output log file
534
535
sessionProps.LoggerNameOffset = offsetof (TraceProperties, mSessionName ); // Location of session name; will be written by StartTrace()
@@ -556,7 +557,7 @@ ULONG TraceSession::Start(
556
557
sessionProps.LoggerThreadId // tracing session identifier
557
558
*/
558
559
559
- auto status = StartTrace (&mSessionHandle , sessionName, &sessionProps);
560
+ auto status = StartTraceW (&mSessionHandle , sessionName, &sessionProps);
560
561
if (status != ERROR_SUCCESS) {
561
562
mSessionHandle = 0 ;
562
563
return status;
@@ -571,7 +572,7 @@ ULONG TraceSession::Start(
571
572
572
573
// -------------------------------------------------------------------------
573
574
// Open the trace
574
- mTraceHandle = OpenTrace (&traceProps);
575
+ mTraceHandle = OpenTraceW (&traceProps);
575
576
if (mTraceHandle == INVALID_PROCESSTRACE_HANDLE) {
576
577
auto lastError = GetLastError ();
577
578
Stop ();
@@ -584,14 +585,15 @@ ULONG TraceSession::Start(
584
585
// captures are based off the timestamp here.
585
586
586
587
switch (traceProps.LogfileHeader .ReservedFlags ) {
587
- case 2 : // System time
588
- mQpcFrequency .QuadPart = 10000000ull ;
588
+ case TIMESTAMP_TYPE_SYSTEM_TIME:
589
+ mTimestampFrequency .QuadPart = 10000000ull ;
589
590
break ;
590
- case 3 : // CPU cycle counter
591
- mQpcFrequency .QuadPart = 1000000ull * traceProps.LogfileHeader .CpuSpeedInMHz ;
591
+ case TIMESTAMP_TYPE_CPU_CYCLE_COUNTER:
592
+ mTimestampFrequency .QuadPart = 1000000ull * traceProps.LogfileHeader .CpuSpeedInMHz ;
592
593
break ;
593
- default : // 1 == QPC
594
- mQpcFrequency = traceProps.LogfileHeader .PerfFreq ;
594
+ case TIMESTAMP_TYPE_QPC:
595
+ default :
596
+ mTimestampFrequency = traceProps.LogfileHeader .PerfFreq ;
595
597
break ;
596
598
}
597
599
@@ -602,17 +604,20 @@ ULONG TraceSession::Start(
602
604
QueryPerformanceCounter (&qpc1);
603
605
GetSystemTimeAsFileTime (&ft);
604
606
QueryPerformanceCounter (&qpc2);
605
- FileTimeToLocalFileTime (&ft, & mStartTime );
606
- mStartQpc .QuadPart = qpc1.QuadPart + ( qpc2. QuadPart - qpc1 .QuadPart ) / 2 ;
607
+ FileTimeToLocalFileTime (&ft, (FILETIME*) & mStartFileTime );
608
+ mStartTimestamp .QuadPart = ( qpc1.QuadPart + qpc2.QuadPart ) / 2 ;
607
609
} else {
608
- SYSTEMTIME ust = {};
609
- SYSTEMTIME lst = {};
610
+ // Convert start FILETIME to local start FILETIME
611
+ SYSTEMTIME ust{};
612
+ SYSTEMTIME lst{};
610
613
FileTimeToSystemTime ((FILETIME const *) &traceProps.LogfileHeader .StartTime , &ust);
611
614
SystemTimeToTzSpecificLocalTime (&traceProps.LogfileHeader .TimeZone , &ust, &lst);
612
- SystemTimeToFileTime (&lst, &mStartTime );
615
+ SystemTimeToFileTime (&lst, (FILETIME*) &mStartFileTime );
616
+ // The above conversion stops at milliseconds, so copy the rest over too
617
+ mStartFileTime += traceProps.LogfileHeader .StartTime .QuadPart % 10000 ;
613
618
}
614
619
615
- InitializeTimestampInfo (&mStartQpc , mQpcFrequency );
620
+ InitializeTimestampInfo (&mStartTimestamp , mTimestampFrequency );
616
621
617
622
return ERROR_SUCCESS;
618
623
}
0 commit comments