Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions src/coreclr/src/vm/eventpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "eventpipesession.h"
#include "eventpipejsonfile.h"
#include "eventtracebase.h"
#include "ipcstreamfactory.h"
#include "sampleprofiler.h"
#include "win32threadpool.h"
#include "ceemain.h"
Expand All @@ -38,7 +39,8 @@ Volatile<uint64_t> EventPipe::s_allowWrite = 0;
unsigned int * EventPipe::s_pProcGroupOffsets = nullptr;
#endif
Volatile<uint32_t> EventPipe::s_numberOfSessions(0);
CQuickArrayList<EventPipeSessionID> EventPipe::s_rgDeferredEventPipeSessionIds = CQuickArrayList<EventPipeSessionID>();
CQuickArrayList<EventPipeSessionID> EventPipe::s_rgDeferredEnableEventPipeSessionIds = CQuickArrayList<EventPipeSessionID>();
CQuickArrayList<EventPipeSessionID> EventPipe::s_rgDeferredDisableEventPipeSessionIds = CQuickArrayList<EventPipeSessionID>();
bool EventPipe::s_CanStartThreads = false;

// This function is auto-generated from /src/scripts/genEventPipe.py
Expand Down Expand Up @@ -111,21 +113,34 @@ void EventPipe::FinishInitialize()
{
STANDARD_VM_CONTRACT;

CrstHolder _crst(GetLock());
// Enable streaming for any deferred sessions
{
CrstHolder _crst(GetLock());

s_CanStartThreads = true;
s_CanStartThreads = true;

while (s_rgDeferredEventPipeSessionIds.Size() > 0)
{
EventPipeSessionID id = s_rgDeferredEventPipeSessionIds.Pop();
if (IsSessionIdInCollection(id))
while (s_rgDeferredEnableEventPipeSessionIds.Size() > 0)
{
EventPipeSession *pSession = reinterpret_cast<EventPipeSession*>(id);
pSession->StartStreaming();
EventPipeSessionID id = s_rgDeferredEnableEventPipeSessionIds.Pop();
if (IsSessionIdInCollection(id))
{
EventPipeSession *pSession = reinterpret_cast<EventPipeSession*>(id);
pSession->StartStreaming();
}
}

SampleProfiler::CanStartSampling();
}

SampleProfiler::CanStartSampling();
// release lock in case someone tried to disable while we held it
// s_rgDeferredDisableEventPipeSessionIds is now safe to access without the
// lock since we've set s_canStartThreads to true inside the lock. Anyone
// who was waiting on that lock will see that state and not mutate the defer list
while (s_rgDeferredDisableEventPipeSessionIds.Size() > 0)
{
EventPipeSessionID id = s_rgDeferredDisableEventPipeSessionIds.Pop();
DisableHelper(id);
}
}

//
Expand Down Expand Up @@ -420,7 +435,7 @@ void EventPipe::StartStreaming(EventPipeSessionID id)
}
else
{
s_rgDeferredEventPipeSessionIds.Push(id);
s_rgDeferredEnableEventPipeSessionIds.Push(id);
}

}
Expand All @@ -435,6 +450,27 @@ void EventPipe::Disable(EventPipeSessionID id)
}
CONTRACTL_END;

// EventPipe::Disable is called synchronously since the diagnostics server is
// single threaded. HOWEVER, if the runtime was suspended in EEStartupHelper,
// then EventPipe::FinishInitialize might not have executed yet. Disabling a session
// needs to either happen before we resume or after initialization. We briefly take the
// lock to check s_CanStartThreads to check whether we've finished initialization. We
// also check whether we are still suspended in which case we can safely disable the session
// without deferral.
{
CrstHolder _crst(GetLock());
if (!s_CanStartThreads && !IpcStreamFactory::AnySuspendedPorts())
{
s_rgDeferredDisableEventPipeSessionIds.Push(id);
return;
}
}

DisableHelper(id);
}

void EventPipe::DisableHelper(EventPipeSessionID id)
{
if (s_CanStartThreads)
SetupThread();

Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/src/vm/eventpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ class EventPipe
Thread *pEventThread = nullptr,
StackContents *pStack = nullptr);

static void DisableHelper(EventPipeSessionID id);

static void DisableInternal(EventPipeSessionID id, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue);

// Enable the specified EventPipe session.
Expand Down Expand Up @@ -239,7 +241,8 @@ class EventPipe

static bool s_CanStartThreads;

static CQuickArrayList<EventPipeSessionID> s_rgDeferredEventPipeSessionIds;
static CQuickArrayList<EventPipeSessionID> s_rgDeferredEnableEventPipeSessionIds;
static CQuickArrayList<EventPipeSessionID> s_rgDeferredDisableEventPipeSessionIds;

//! Bitmask tracking EventPipe active sessions.
// in all groups preceding it. For example if there are three groups with sizes:
Expand Down