summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Au <andrewau@microsoft.com>2019-07-02 16:35:40 -0700
committerGitHub <noreply@github.com>2019-07-02 16:35:40 -0700
commitbf3dce315eb9fe8da4491b711fecddb4116e2314 (patch)
tree79c9ea196d1760182af66d648d5a2c08ed4a5ce7 /src
parentd98efbef7016d38036f69ed69dc041c5876755b6 (diff)
downloadcoreclr-bf3dce315eb9fe8da4491b711fecddb4116e2314.tar.gz
coreclr-bf3dce315eb9fe8da4491b711fecddb4116e2314.tar.bz2
coreclr-bf3dce315eb9fe8da4491b711fecddb4116e2314.zip
Ensure YIELD_WHILE() in EventPipeBufferManager::SuspendWriteEvent() always terminates (#25491)
Diffstat (limited to 'src')
-rw-r--r--src/vm/eventpipe.cpp12
-rw-r--r--src/vm/eventpipe.h1
2 files changed, 7 insertions, 6 deletions
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
index 4ca57a274c..6350256d00 100644
--- a/src/vm/eventpipe.cpp
+++ b/src/vm/eventpipe.cpp
@@ -33,6 +33,7 @@ Volatile<bool> EventPipe::s_tracingInitialized(false);
EventPipeConfiguration EventPipe::s_config;
EventPipeEventSource *EventPipe::s_pEventSource = nullptr;
VolatilePtr<EventPipeSession> EventPipe::s_pSessions[MaxNumberOfSessions];
+Volatile<uint64_t> EventPipe::s_allowWrite = 0;
#ifndef FEATURE_PAL
unsigned int * EventPipe::s_pProcGroupOffsets = nullptr;
#endif
@@ -262,6 +263,7 @@ bool EventPipe::EnableInternal(
return false;
}
s_pSessions[pSession->GetIndex()].Store(pSession);
+ s_allowWrite |= pSession->GetMask();
++s_numberOfSessions;
// Enable tracing.
@@ -344,6 +346,8 @@ void EventPipe::DisableInternal(EventPipeSessionID id, EventPipeProviderCallback
// Disable pSession tracing.
s_config.Disable(*pSession, pEventPipeProviderCallbackDataQueue);
+ s_allowWrite &= ~(pSession->GetMask());
+
pSession->Disable(); // Suspend EventPipeBufferManager, and remove providers.
// Do rundown before fully stopping the session unless rundown wasn't requested
@@ -620,10 +624,7 @@ void EventPipe::WriteEventInternal(
{
for (uint32_t i = 0; i < MaxNumberOfSessions; ++i)
{
- // This read is OK because we aren't derefencing the pointer and if we observe a value that
- // isn't up-to-date (whether null or non-null) that is just the natural race timing of trying to
- // write to a session while it is being concurrently enabled/disabled.
- if (s_pSessions[i].LoadWithoutBarrier() == nullptr)
+ if ((s_allowWrite & (1ui64 << i)) == 0)
continue;
// Now that we know this session is probably live we pay the perf cost of the memory barriers
@@ -635,8 +636,7 @@ void EventPipe::WriteEventInternal(
{
EventPipeSession *const pSession = s_pSessions[i].Load();
- // The NULL check above may make this check below appear redundant but it is not. Disable is
- // allowed to set s_pSessions[i] = NULL at any time and that may have occured in between
+ // Disable is allowed to set s_pSessions[i] = NULL at any time and that may have occured in between
// the check and the load
if (pSession != nullptr)
pSession->WriteEventBuffered(
diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h
index de2e72f4e8..610dc399f7 100644
--- a/src/vm/eventpipe.h
+++ b/src/vm/eventpipe.h
@@ -199,6 +199,7 @@ private:
static Volatile<bool> s_tracingInitialized;
static EventPipeConfiguration s_config;
static VolatilePtr<EventPipeSession> s_pSessions[MaxNumberOfSessions];
+ static Volatile<uint64_t> s_allowWrite;
static EventPipeEventSource *s_pEventSource;
//! Bitmask tracking EventPipe active sessions.