@@ -16,6 +16,8 @@ Thread* SampleProfiler::s_pSamplingThread = NULL;
1616const GUID SampleProfiler::s_providerID = {0x3c530d44 ,0x97ae ,0x513a ,{0x1e ,0x6d ,0x78 ,0x3e ,0x8f ,0x8e ,0x03 ,0xa9 }}; // {3c530d44-97ae-513a-1e6d-783e8f8e03a9}
1717EventPipeProvider* SampleProfiler::s_pEventPipeProvider = NULL ;
1818EventPipeEvent* SampleProfiler::s_pThreadTimeEvent = NULL ;
19+ BYTE* SampleProfiler::s_pPayloadExternal = NULL ;
20+ BYTE* SampleProfiler::s_pPayloadManaged = NULL ;
1921CLREventStatic SampleProfiler::s_threadShutdownEvent;
2022long SampleProfiler::s_samplingRateInNs = 1000000 ; // 1ms
2123
@@ -43,6 +45,15 @@ void SampleProfiler::Enable()
4345 false /* NeedStack */ );
4446 }
4547
48+ if (s_pPayloadExternal == NULL )
49+ {
50+ s_pPayloadExternal = new BYTE[sizeof (unsigned int )];
51+ *((unsigned int *)s_pPayloadExternal) = static_cast <unsigned int >(SampleProfilerSampleType::External);
52+
53+ s_pPayloadManaged = new BYTE[sizeof (unsigned int )];
54+ *((unsigned int *)s_pPayloadManaged) = static_cast <unsigned int >(SampleProfilerSampleType::Managed);
55+ }
56+
4657 s_profilingEnabled = true ;
4758 s_pSamplingThread = SetupUnstartedThread ();
4859 if (s_pSamplingThread->CreateNewThread (0 , ThreadProc, NULL ))
@@ -166,8 +177,21 @@ void SampleProfiler::WalkManagedThreads()
166177 // Walk the stack and write it out as an event.
167178 if (EventPipe::WalkManagedStackForThread (pTargetThread, stackContents) && !stackContents.IsEmpty ())
168179 {
169- EventPipe::WriteSampleProfileEvent (s_pSamplingThread, pTargetThread, stackContents);
180+ // Set the payload. If the GC mode on suspension > 0, then the thread was in cooperative mode.
181+ // Even though there are some cases where this is not managed code, we assume it is managed code here.
182+ // If the GC mode on suspension == 0 then the thread was in preemptive mode, which we qualify as external here.
183+ BYTE *pPayload = s_pPayloadExternal;
184+ if (pTargetThread->GetGCModeOnSuspension ())
185+ {
186+ pPayload = s_pPayloadManaged;
187+ }
188+
189+ // Write the sample.
190+ EventPipe::WriteSampleProfileEvent (s_pSamplingThread, s_pThreadTimeEvent, pTargetThread, stackContents, pPayload, c_payloadSize);
170191 }
192+
193+ // Reset the GC mode.
194+ pTargetThread->ClearGCModeOnSuspension ();
171195 }
172196}
173197
0 commit comments