}
CONTRACTL_END;
- // Take the lock before enabling tracing.
- CrstHolder _crst(GetLock());
+ EventPipeSessionID sessionId;
+ EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+ {
+ // Take the lock before enabling tracing.
+ CrstHolder _crst(GetLock());
+
+ // Create a new session.
+ SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds);
+ EventPipeSession *pSession = s_pConfig->CreateSession(
+ (strOutputPath != NULL) ? EventPipeSessionType::File : EventPipeSessionType::Streaming,
+ circularBufferSizeInMB,
+ pProviders,
+ numProviders);
- // Create a new session.
- SampleProfiler::SetSamplingRate(static_cast<unsigned long>(profilerSamplingRateInNanoseconds));
- EventPipeSession *pSession = s_pConfig->CreateSession(
- sessionType,
- circularBufferSizeInMB,
- pProviders,
- numProviders);
+ // Enable the session.
+ sessionId = Enable(strOutputPath, pSession, sessionType, pStream, &eventPipeProviderCallbackDataQueue);
+ }
+
+ while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
+ {
+ EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
+ }
- EventPipeSessionID sessionId = Enable(strOutputPath, pSession, sessionType, pStream);
return sessionId;
}
LPCWSTR strOutputPath,
EventPipeSession *const pSession,
EventPipeSessionType sessionType,
- IpcStream *const pStream)
+ IpcStream *const pStream,
+ EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
}
// Enable tracing.
- s_pConfig->Enable(s_pSession);
+ s_pConfig->Enable(s_pSession, pEventPipeProviderCallbackDataQueue);
// Enable the sample profiler
- SampleProfiler::Enable();
+ SampleProfiler::Enable(pEventPipeProviderCallbackDataQueue);
// Return the session ID.
return sessionId;
// Don't block GC during clean-up.
GCX_PREEMP();
- // Take the lock before disabling tracing.
- CrstHolder _crst(GetLock());
- DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession));
+ EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+ {
+ // Take the lock before disabling tracing.
+ CrstHolder _crst(GetLock());
+ DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession), &eventPipeProviderCallbackDataQueue);
+ }
+
+ while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
+ {
+ EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
+ }
}
-void EventPipe::DisableInternal(EventPipeSessionID id)
+void EventPipe::DisableInternal(EventPipeSessionID id, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Normal);
// Disable tracing.
- s_pConfig->Disable(s_pSession);
+ s_pConfig->Disable(s_pSession, pEventPipeProviderCallbackDataQueue);
// Delete the session.
s_pConfig->DeleteSession(s_pSession);
1 /* circularBufferSizeInMB */,
RundownProviders,
sizeof(RundownProviders) / sizeof(EventPipeProviderConfiguration));
- s_pConfig->EnableRundown(s_pSession);
+ s_pConfig->EnableRundown(s_pSession, pEventPipeProviderCallbackDataQueue);
// Ask the runtime to emit rundown events.
if (g_fEEStarted && !g_fEEShutDown)
ETW::EnumerationLog::EndRundown();
// Disable the event pipe now that rundown is complete.
- s_pConfig->Disable(s_pSession);
+ s_pConfig->Disable(s_pSession, pEventPipeProviderCallbackDataQueue);
// Delete the rundown session.
s_pConfig->DeleteSession(s_pSession);
GCX_PREEMP();
- // Take the lock control lock to make sure that tracing isn't disabled during this operation.
- CrstHolder _crst(GetLock());
+ EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+ {
+ // Take the lock control lock to make sure that tracing isn't disabled during this operation.
+ CrstHolder _crst(GetLock());
- if (s_pSession == nullptr || s_pFile == nullptr)
- return;
+ if (s_pSession == nullptr || s_pFile == nullptr)
+ return;
- // Make sure that we should actually switch files.
- if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::IpcStream)
- return;
+ // Make sure that we should actually switch files.
+ if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::IpcStream)
+ return;
- if (CLRGetTickCount64() > (s_lastFlushSwitchTime + 100))
- {
- // Get the current time stamp.
- // WriteAllBuffersToFile will use this to ensure that no events after
- // the current timestamp are written into the file.
- LARGE_INTEGER stopTimeStamp;
- QueryPerformanceCounter(&stopTimeStamp);
- s_pBufferManager->WriteAllBuffersToFile(s_pFile, stopTimeStamp);
+ if (CLRGetTickCount64() > (s_lastFlushSwitchTime + 100))
+ {
+ // Get the current time stamp.
+ // WriteAllBuffersToFile will use this to ensure that no events after
+ // the current timestamp are written into the file.
+ LARGE_INTEGER stopTimeStamp;
+ QueryPerformanceCounter(&stopTimeStamp);
+ s_pBufferManager->WriteAllBuffersToFile(s_pFile, stopTimeStamp);
+
+ s_lastFlushSwitchTime = CLRGetTickCount64();
+ }
- s_lastFlushSwitchTime = CLRGetTickCount64();
+ if (s_pFile->HasErrors())
+ {
+ EX_TRY
+ {
+ DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession), &eventPipeProviderCallbackDataQueue);
+ }
+ EX_CATCH {}
+ EX_END_CATCH(SwallowAllExceptions);
+ }
}
- if (s_pFile->HasErrors())
+ while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
{
- EX_TRY
- {
- DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession));
- }
- EX_CATCH {}
- EX_END_CATCH(SwallowAllExceptions);
+ EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
}
}
THROWS;
GC_TRIGGERS;
MODE_ANY;
+ PRECONDITION(!GetLock()->OwnedByCurrentThread());
}
CONTRACTL_END;
+
+ EventPipeProvider *pProvider = NULL;
+ EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+ {
+ CrstHolder _crst(GetLock());
+ pProvider = EventPipe::CreateProvider(providerName, pCallbackFunction, pCallbackData, &eventPipeProviderCallbackDataQueue);
+ }
+ while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
+ {
+ EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
+ }
+ return pProvider;
+}
+
+EventPipeProvider *EventPipe::CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ PRECONDITION(GetLock()->OwnedByCurrentThread());
+ }
+ CONTRACTL_END;
+
EventPipeProvider *pProvider = NULL;
if (s_pConfig != NULL)
{
- pProvider = s_pConfig->CreateProvider(providerName, pCallbackFunction, pCallbackData);
+ pProvider = s_pConfig->CreateProvider(providerName, pCallbackFunction, pCallbackData, pEventPipeProviderCallbackDataQueue);
}
-
return pProvider;
}
typedef UINT64 EventPipeSessionID;
+class EventPipeProviderCallbackDataQueue;
+
class EventPipe
{
// Declare friends.
// Create a provider.
static EventPipeProvider *CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction = NULL, void *pCallbackData = NULL);
+ static EventPipeProvider *CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
+
// Get a provider.
static EventPipeProvider *GetProvider(const SString &providerName);
// The counterpart to WriteEvent which after the payload is constructed
static void WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload &payload, LPCGUID pActivityId = NULL, LPCGUID pRelatedActivityId = NULL);
- static void DisableInternal(EventPipeSessionID id);
+ static void DisableInternal(EventPipeSessionID id, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Enable the specified EventPipe session.
static EventPipeSessionID Enable(
LPCWSTR strOutputPath,
EventPipeSession *const pSession,
EventPipeSessionType sessionType,
- IpcStream *const pStream);
+ IpcStream *const pStream,
+ EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
static void CreateFlushTimerCallback();
MODE_ANY;
}
CONTRACTL_END;
+
+ EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+ {
+ CrstHolder _crst(EventPipe::GetLock());
- // Create the configuration provider.
- m_pConfigProvider = CreateProvider(SL(s_configurationProviderName), NULL, NULL);
+ // Create the configuration provider.
+ m_pConfigProvider = CreateProvider(SL(s_configurationProviderName), NULL, NULL, &eventPipeProviderCallbackDataQueue);
+ }
+ while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
+ {
+ EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
+ }
// Create the metadata event.
m_pMetadataEvent = m_pConfigProvider->AddEvent(
false); /* needStack */
}
-EventPipeProvider *EventPipeConfiguration::CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData)
+EventPipeProvider *EventPipeConfiguration::CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_ANY;
+ PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
}
CONTRACTL_END;
EventPipeProvider *pProvider = new EventPipeProvider(this, providerName, pCallbackFunction, pCallbackData);
// Register the provider with the configuration system.
- RegisterProvider(*pProvider);
+ RegisterProvider(*pProvider, pEventPipeProviderCallbackDataQueue);
return pProvider;
}
delete pProvider;
}
-bool EventPipeConfiguration::RegisterProvider(EventPipeProvider &provider)
+bool EventPipeConfiguration::RegisterProvider(EventPipeProvider &provider, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_ANY;
+ PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
}
CONTRACTL_END;
- // Take the lock before manipulating the provider list.
- CrstHolder _crst(EventPipe::GetLock());
-
// See if we've already registered this provider.
EventPipeProvider *pExistingProvider = GetProviderNoLock(provider.GetProviderName());
if (pExistingProvider != NULL)
EventPipeSessionProvider *pSessionProvider = GetSessionProvider(m_pSession, &provider);
if (pSessionProvider != NULL)
{
- provider.SetConfiguration(
+ EventPipeProviderCallbackData eventPipeProviderCallbackData = provider.SetConfiguration(
true /* providerEnabled */,
pSessionProvider->GetKeywords(),
pSessionProvider->GetLevel(),
pSessionProvider->GetFilterData());
+ pEventPipeProviderCallbackDataQueue->Enqueue(&eventPipeProviderCallbackData);
}
}
}
}
-void EventPipeConfiguration::Enable(EventPipeSession *pSession)
+void EventPipeConfiguration::Enable(EventPipeSession *pSession, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
}
CONTRACTL_END;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+
m_pSession = pSession;
m_enabled = true;
EventPipeSessionProvider *pSessionProvider = GetSessionProvider(m_pSession, pProvider);
if (pSessionProvider != NULL)
{
- pProvider->SetConfiguration(
+ eventPipeProviderCallbackData = pProvider->SetConfiguration(
true /* providerEnabled */,
pSessionProvider->GetKeywords(),
pSessionProvider->GetLevel(),
pSessionProvider->GetFilterData());
+ pEventPipeProviderCallbackDataQueue->Enqueue(&eventPipeProviderCallbackData);
}
pElem = m_pProviderList->GetNext(pElem);
}
}
-void EventPipeConfiguration::Disable(EventPipeSession *pSession)
+void EventPipeConfiguration::Disable(EventPipeSession *pSession, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
}
CONTRACTL_END;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+
// The provider list should be non-NULL, but can be NULL on shutdown.
if (m_pProviderList != NULL)
{
while (pElem != NULL)
{
EventPipeProvider *pProvider = pElem->GetValue();
- pProvider->SetConfiguration(
+ eventPipeProviderCallbackData = pProvider->SetConfiguration(
false /* providerEnabled */,
0 /* keywords */,
EventPipeEventLevel::Critical /* level */,
NULL /* filterData */);
+ pEventPipeProviderCallbackDataQueue->Enqueue(&eventPipeProviderCallbackData);
pElem = m_pProviderList->GetNext(pElem);
}
return m_rundownEnabled;
}
-void EventPipeConfiguration::EnableRundown(EventPipeSession *pSession)
+void EventPipeConfiguration::EnableRundown(EventPipeSession *pSession, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
m_rundownEnabled = true;
// Enable tracing.
- Enable(pSession);
+ Enable(pSession, pEventPipeProviderCallbackDataQueue);
}
EventPipeEventInstance *EventPipeConfiguration::BuildEventMetadataEvent(EventPipeEventInstance &sourceInstance, unsigned int metadataId)
Verbose
};
+struct EventPipeProviderCallbackData
+{
+ LPCWSTR pFilterData;
+ EventPipeCallback pCallbackFunction;
+ bool enabled;
+ INT64 keywords;
+ EventPipeEventLevel providerLevel;
+ void* pCallbackData;
+};
+
+struct EventPipeProviderCallbackDataNode
+{
+ EventPipeProviderCallbackData* value;
+ EventPipeProviderCallbackDataNode* prev;
+};
+
+class EventPipeProviderCallbackDataQueue
+{
+public:
+ EventPipeProviderCallbackDataQueue();
+
+ void Enqueue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
+
+ bool TryDequeue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
+
+private:
+ EventPipeProviderCallbackDataNode* front;
+ EventPipeProviderCallbackDataNode* back;
+};
+
class EventPipeConfiguration
{
public:
void Initialize();
// Create a new provider.
- EventPipeProvider *CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData);
+ EventPipeProvider *CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Delete a provider.
void DeleteProvider(EventPipeProvider *pProvider);
// Register a provider.
- bool RegisterProvider(EventPipeProvider &provider);
+ bool RegisterProvider(EventPipeProvider &provider, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Unregister a provider.
bool UnregisterProvider(EventPipeProvider &provider);
size_t GetCircularBufferSize() const;
// Enable a session in the event pipe.
- void Enable(EventPipeSession *pSession);
+ void Enable(EventPipeSession *pSession, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Disable a session in the event pipe.
- void Disable(EventPipeSession *pSession);
+ void Disable(EventPipeSession *pSession, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Get the status of the event pipe.
bool Enabled() const;
bool RundownEnabled() const;
// Enable rundown using the specified configuration.
- void EnableRundown(EventPipeSession *pSession);
+ void EnableRundown(EventPipeSession *pSession, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Get the event used to write metadata to the event stream.
EventPipeEventInstance *BuildEventMetadataEvent(EventPipeEventInstance &sourceInstance, unsigned int metdataId);
#ifdef FEATURE_PERFTRACING
+EventPipeProviderCallbackDataQueue::EventPipeProviderCallbackDataQueue()
+{
+ this->front = this->back = NULL;
+}
+
+void EventPipeProviderCallbackDataQueue::Enqueue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData)
+{
+ EventPipeProviderCallbackDataNode* newNode = new EventPipeProviderCallbackDataNode(); // throws
+ newNode->prev = NULL;
+ newNode->value = new EventPipeProviderCallbackData(); // throws
+ *(newNode->value) = *pEventPipeProviderCallbackData;
+ if (this->back == NULL)
+ {
+ this->front = this->back = newNode;
+ }
+ else
+ {
+ this->back->prev = newNode;
+ this->back = newNode;
+ }
+}
+
+bool EventPipeProviderCallbackDataQueue::TryDequeue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData)
+{
+ if (this->front == nullptr)
+ {
+ return false;
+ }
+
+ EventPipeProviderCallbackDataNode* oldNode = this->front;
+ this->front = this->front->prev;
+ if (this->front == nullptr)
+ {
+ this->back = nullptr;
+ }
+
+ *pEventPipeProviderCallbackData = *(oldNode->value);
+ delete oldNode;
+ return true;
+}
+
EventPipeProvider::EventPipeProvider(EventPipeConfiguration *pConfig, const SString &providerName, EventPipeCallback pCallbackFunction, void *pCallbackData)
{
CONTRACTL
((eventLevel == EventPipeEventLevel::LogAlways) || (m_providerLevel >= eventLevel)));
}
-void EventPipeProvider::SetConfiguration(bool providerEnabled, INT64 keywords, EventPipeEventLevel providerLevel, LPCWSTR pFilterData)
+EventPipeProviderCallbackData EventPipeProvider::SetConfiguration(bool providerEnabled, INT64 keywords, EventPipeEventLevel providerLevel, LPCWSTR pFilterData)
{
CONTRACTL
{
m_providerLevel = providerLevel;
RefreshAllEvents();
- InvokeCallback(pFilterData);
+ return PrepareCallbackData(pFilterData);
}
EventPipeEvent* EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata, unsigned int metadataLength)
event.RefreshState();
}
-void EventPipeProvider::InvokeCallback(LPCWSTR pFilterData)
+/* static */ void EventPipeProvider::InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
MODE_ANY;
- PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
+ PRECONDITION(!EventPipe::GetLock()->OwnedByCurrentThread());
}
CONTRACTL_END;
+ LPCWSTR pFilterData = eventPipeProviderCallbackData.pFilterData;
+ EventPipeCallback pCallbackFunction = eventPipeProviderCallbackData.pCallbackFunction;
+ bool enabled = eventPipeProviderCallbackData.enabled;
+ INT64 keywords = eventPipeProviderCallbackData.keywords;
+ EventPipeEventLevel providerLevel = eventPipeProviderCallbackData.providerLevel;
+ void* pCallbackData = eventPipeProviderCallbackData.pCallbackData;
bool isEventFilterDescriptorInitialized = false;
EventFilterDescriptor eventFilterDescriptor{};
isEventFilterDescriptorInitialized = true;
}
- if(m_pCallbackFunction != NULL && !g_fEEShutDown)
+ if(pCallbackFunction != NULL && !g_fEEShutDown)
{
- (*m_pCallbackFunction)(
+ (*pCallbackFunction)(
NULL, /* providerId */
- m_enabled,
- (UCHAR) m_providerLevel,
- m_keywords,
+ enabled,
+ (UCHAR) providerLevel,
+ keywords,
0 /* matchAllKeywords */,
isEventFilterDescriptorInitialized ? &eventFilterDescriptor : NULL,
- m_pCallbackData /* CallbackContext */);
+ pCallbackData /* CallbackContext */);
}
buffer.Destroy();
}
+EventPipeProviderCallbackData EventPipeProvider::PrepareCallbackData(LPCWSTR pFilterData)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
+ }
+ CONTRACTL_END;
+
+ EventPipeProviderCallbackData result;
+ result.pFilterData = pFilterData;
+ result.pCallbackFunction = m_pCallbackFunction;
+ result.enabled = m_enabled;
+ result.providerLevel = m_providerLevel;
+ result.keywords = m_keywords;
+ result.pCallbackData = m_pCallbackData;
+ return result;
+}
+
bool EventPipeProvider::GetDeleteDeferred() const
{
LIMITED_METHOD_CONTRACT;
// Set the provider configuration (enable and disable sets of events).
// This is called by EventPipeConfiguration.
- void SetConfiguration(bool providerEnabled, INT64 keywords, EventPipeEventLevel providerLevel, LPCWSTR pFilterData);
+ EventPipeProviderCallbackData SetConfiguration(bool providerEnabled, INT64 keywords, EventPipeEventLevel providerLevel, LPCWSTR pFilterData);
// Refresh the runtime state of all events.
void RefreshAllEvents();
+ // Prepare the data required for invoking callback
+ EventPipeProviderCallbackData PrepareCallbackData(LPCWSTR pFilterData);
+
// Invoke the provider callback.
- void InvokeCallback(LPCWSTR pFilterData);
+ static void InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData);
// Specifies whether or not the provider was deleted, but that deletion
// was deferred until after tracing is stopped.
typedef MMRESULT (WINAPI *TimePeriodFnPtr) (UINT uPeriod);
#endif //FEATURE_PAL
-void SampleProfiler::Enable()
+void SampleProfiler::Enable(EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
{
if(s_pEventPipeProvider == NULL)
{
- s_pEventPipeProvider = EventPipe::CreateProvider(SL(s_providerName));
+ s_pEventPipeProvider = EventPipe::CreateProvider(SL(s_providerName), nullptr, nullptr, pEventPipeProviderCallbackDataQueue);
s_pThreadTimeEvent = s_pEventPipeProvider->AddEvent(
0, /* eventID */
0, /* keywords */
public:
// Enable profiling.
- static void Enable();
+ static void Enable(EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);
// Disable profiling.
static void Disable();