Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,13 @@ private static unsafe partial ulong Enable(
[return: MarshalAs(UnmanagedType.Bool)]
internal static unsafe partial bool GetNextEvent(ulong sessionID, EventPipeEventInstanceData* pInstance);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "EventPipeInternal_GetWaitHandle")]
internal static unsafe partial IntPtr GetWaitHandle(ulong sessionID);
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "EventPipeInternal_SignalSession")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static unsafe partial bool SignalSession(ulong sessionID);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "EventPipeInternal_WaitForSessionSignal")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static unsafe partial bool WaitForSessionSignal(ulong sessionID, int timeoutMs);
}
}

Expand Down
20 changes: 18 additions & 2 deletions src/coreclr/vm/eventpipeadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,26 @@ class EventPipeAdapter final
return ep_get_session(id);
}

static inline HANDLE GetWaitHandle(EventPipeSessionID id)
static inline bool SignalSession(EventPipeSessionID id)
{
STATIC_CONTRACT_NOTHROW;
return reinterpret_cast<HANDLE>(ep_get_wait_handle(id));

EventPipeSession *const session = ep_get_session (id);
if (!session)
return false;

return ep_rt_wait_event_set (ep_session_get_wait_event (session));
}

static inline bool WaitForSessionSignal(EventPipeSessionID id, INT32 timeoutMs)
{
STATIC_CONTRACT_NOTHROW;

EventPipeSession *const session = ep_get_session (id);
if (!session)
return false;

return !ep_rt_wait_event_wait (ep_session_get_wait_event (session), (uint32_t)timeoutMs, false) ? true : false;
}

static inline FILETIME GetSessionStartTime(EventPipeSession *session)
Expand Down
21 changes: 17 additions & 4 deletions src/coreclr/vm/eventpipeinternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,17 +255,30 @@ extern "C" bool QCALLTYPE EventPipeInternal_GetNextEvent(UINT64 sessionID, Event
return pNextInstance != NULL;
}

extern "C" HANDLE QCALLTYPE EventPipeInternal_GetWaitHandle(UINT64 sessionID)
extern "C" bool QCALLTYPE EventPipeInternal_SignalSession(UINT64 sessionID)
{
QCALL_CONTRACT;

HANDLE waitHandle = NULL;
bool result = false;
BEGIN_QCALL;

waitHandle = EventPipeAdapter::GetWaitHandle(sessionID);
result = EventPipeAdapter::SignalSession(sessionID);

END_QCALL;
return waitHandle;
return result;
}

extern "C" bool QCALLTYPE EventPipeInternal_WaitForSessionSignal(UINT64 sessionID, INT32 timeoutMs)
{
QCALL_CONTRACT;

bool result = false;
BEGIN_QCALL;

result = EventPipeAdapter::WaitForSessionSignal(sessionID, timeoutMs);

END_QCALL;
return result;
}

#endif // FEATURE_PERFTRACING
8 changes: 6 additions & 2 deletions src/coreclr/vm/eventpipeinternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ extern "C" void QCALLTYPE EventPipeInternal_DeleteProvider(
INT_PTR provHandle);

extern "C" int QCALLTYPE EventPipeInternal_EventActivityIdControl(
uint32_t controlCode,
UINT32 controlCode,
GUID *pActivityId);

extern "C" void QCALLTYPE EventPipeInternal_WriteEventData(
Expand All @@ -86,9 +86,13 @@ extern "C" bool QCALLTYPE EventPipeInternal_GetNextEvent(
UINT64 sessionID,
EventPipeEventInstanceData *pInstance);

extern "C" HANDLE QCALLTYPE EventPipeInternal_GetWaitHandle(
extern "C" bool QCALLTYPE EventPipeInternal_SignalSession(
UINT64 sessionID);

extern "C" bool QCALLTYPE EventPipeInternal_WaitForSessionSignal(
UINT64 sessionID,
INT32 timeoutMs);

#endif // FEATURE_PERFTRACING

#endif // __EVENTPIPEINTERNAL_H__
3 changes: 2 additions & 1 deletion src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ static const Entry s_QCall[] =
DllImportEntry(EventPipeInternal_GetProvider)
DllImportEntry(EventPipeInternal_WriteEventData)
DllImportEntry(EventPipeInternal_GetNextEvent)
DllImportEntry(EventPipeInternal_GetWaitHandle)
DllImportEntry(EventPipeInternal_SignalSession)
DllImportEntry(EventPipeInternal_WaitForSessionSignal)
#endif
#if defined(TARGET_UNIX)
DllImportEntry(CloseHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ internal EventListenerSubscription(EventKeywords matchAnyKeywords, EventLevel le
private long m_timeQPCFrequency;

private bool m_stopDispatchTask;
private readonly EventPipeWaitHandle m_dispatchTaskWaitHandle = new EventPipeWaitHandle();
private Task? m_dispatchTask;
private readonly object m_dispatchControlLock = new object();
private readonly Dictionary<EventListener, EventListenerSubscription> m_subscriptions = new Dictionary<EventListener, EventListenerSubscription>();
Expand All @@ -43,7 +42,6 @@ private EventPipeEventDispatcher()
{
// Get the ID of the runtime provider so that it can be used as a filter when processing events.
m_RuntimeProviderID = EventPipeInternal.GetProvider(NativeRuntimeEventSource.EventSourceName);
m_dispatchTaskWaitHandle.SafeWaitHandle = new SafeWaitHandle(IntPtr.Zero, false);
}

internal void SendCommand(EventListener eventListener, EventCommand command, bool enable, EventLevel level, EventKeywords matchAnyKeywords)
Expand Down Expand Up @@ -139,9 +137,6 @@ private void StartDispatchTask()
if (m_dispatchTask == null)
{
m_stopDispatchTask = false;
// Create a SafeWaitHandle that won't release the handle when done
m_dispatchTaskWaitHandle.SafeWaitHandle = new SafeWaitHandle(EventPipeInternal.GetWaitHandle(m_sessionID), false);

m_dispatchTask = Task.Factory.StartNew(DispatchEventsToEventListeners, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}
Expand All @@ -153,8 +148,7 @@ private void StopDispatchTask()
if (m_dispatchTask != null)
{
m_stopDispatchTask = true;
Debug.Assert(!m_dispatchTaskWaitHandle.SafeWaitHandle.IsInvalid);
EventWaitHandle.Set(m_dispatchTaskWaitHandle.SafeWaitHandle);
EventPipeInternal.SignalSession(m_sessionID);
m_dispatchTask.Wait();
m_dispatchTask = null;
}
Expand Down Expand Up @@ -188,9 +182,7 @@ private unsafe void DispatchEventsToEventListeners()
{
if (!eventsReceived)
{
// Future TODO: this would make more sense to handle in EventPipeSession/EventPipe native code.
Debug.Assert(!m_dispatchTaskWaitHandle.SafeWaitHandle.IsInvalid);
m_dispatchTaskWaitHandle.WaitOne();
EventPipeInternal.WaitForSessionSignal(m_sessionID, Timeout.Infinite);
}

Thread.Sleep(10);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ internal static unsafe IntPtr GetProvider(string providerName)
internal static extern unsafe bool GetNextEvent(ulong sessionID, EventPipeEventInstanceData* pInstance);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe IntPtr GetWaitHandle(ulong sessionID);
internal static extern unsafe bool SignalSession(ulong sessionID);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe bool WaitForSessionSignal(ulong sessionID, int timeoutMs);
#endif // FEATURE_PERFTRACING

//
Expand Down
26 changes: 25 additions & 1 deletion src/mono/mono/component/event_pipe-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ event_pipe_stub_write_event_threadpool_io_pack (
intptr_t overlapped,
uint16_t clr_instance_id);

static bool
event_pipe_stub_signal_session (EventPipeSessionID session_id);

static bool
event_pipe_stub_wait_for_session_signal (
EventPipeSessionID session_id,
uint32_t timeout);

MonoComponentEventPipe *
component_event_pipe_stub_init (void);

Expand Down Expand Up @@ -210,7 +218,9 @@ static MonoComponentEventPipe fn_table = {
&event_pipe_stub_write_event_threadpool_io_enqueue,
&event_pipe_stub_write_event_threadpool_io_dequeue,
&event_pipe_stub_write_event_threadpool_working_thread_count,
&event_pipe_stub_write_event_threadpool_io_pack
&event_pipe_stub_write_event_threadpool_io_pack,
&event_pipe_stub_signal_session,
&event_pipe_stub_wait_for_session_signal
};

static bool
Expand Down Expand Up @@ -459,6 +469,20 @@ event_pipe_stub_write_event_threadpool_io_pack (
return true;
}

static bool
event_pipe_stub_signal_session (EventPipeSessionID session_id)
{
return true;
}

static bool
event_pipe_stub_wait_for_session_signal (
EventPipeSessionID session_id,
uint32_t timeout)
{
return true;
}

MonoComponentEventPipe *
component_event_pipe_stub_init (void)
{
Expand Down
36 changes: 34 additions & 2 deletions src/mono/mono/component/event_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ event_pipe_thread_ctrl_activity_id(
uint8_t *activity_id,
uint32_t activity_id_len);

static bool
event_pipe_signal_session (EventPipeSessionID session_id);

static bool
event_pipe_wait_for_session_signal (
EventPipeSessionID session_id,
uint32_t timeout);

static MonoComponentEventPipe fn_table = {
{ MONO_COMPONENT_ITF_VERSION, &event_pipe_available },
&ep_init,
Expand Down Expand Up @@ -114,7 +122,9 @@ static MonoComponentEventPipe fn_table = {
&ep_rt_write_event_threadpool_io_enqueue,
&ep_rt_write_event_threadpool_io_dequeue,
&ep_rt_write_event_threadpool_working_thread_count,
&ep_rt_write_event_threadpool_io_pack
&ep_rt_write_event_threadpool_io_pack,
&event_pipe_signal_session,
&event_pipe_wait_for_session_signal
};

static bool
Expand Down Expand Up @@ -161,7 +171,7 @@ event_pipe_enable (
rundown_requested,
stream,
sync_callback,
NULL);
NULL);

if (config_providers) {
for (int i = 0; i < providers_len; ++i) {
Expand Down Expand Up @@ -285,6 +295,28 @@ event_pipe_thread_ctrl_activity_id (
return result;
}

static bool
event_pipe_signal_session (EventPipeSessionID session_id)
{
EventPipeSession *const session = ep_get_session (session_id);
if (!session)
return false;

return ep_rt_wait_event_set (ep_session_get_wait_event (session));
}

static bool
event_pipe_wait_for_session_signal (
EventPipeSessionID session_id,
uint32_t timeout)
{
EventPipeSession *const session = ep_get_session (session_id);
if (!session)
return false;

return !ep_rt_wait_event_wait (ep_session_get_wait_event (session), timeout, false) ? true : false;
}

MonoComponentEventPipe *
mono_component_event_pipe_init (void)
{
Expand Down
10 changes: 10 additions & 0 deletions src/mono/mono/component/event_pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ typedef bool
typedef ep_timestamp_t
(*event_pipe_component_convert_100ns_ticks_to_timestamp_t_func) (int64_t ticks_100ns);

typedef bool
(*event_pipe_component_signal_session) (EventPipeSessionID session_id);

typedef bool
(*event_pipe_component_wait_for_session_signal) (
EventPipeSessionID session_id,
uint32_t timeout);

/*
* EventPipeProvider.
*/
Expand Down Expand Up @@ -242,6 +250,8 @@ typedef struct _MonoComponentEventPipe {
event_pipe_component_write_event_threadpool_io_dequeue_func write_event_threadpool_io_dequeue;
event_pipe_component_write_event_threadpool_working_thread_count_func write_event_threadpool_working_thread_count;
event_pipe_component_write_event_threadpool_io_pack_func write_event_threadpool_io_pack;
event_pipe_component_signal_session signal_session;
event_pipe_component_wait_for_session_signal wait_for_session_signal;
} MonoComponentEventPipe;

MONO_COMPONENT_EXPORT_ENTRYPOINT
Expand Down
3 changes: 2 additions & 1 deletion src/mono/mono/metadata/icall-decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Tracing_EventPipeInternal_
ICALL_EXPORT intptr_t ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetProvider (const_gunichar2_ptr provider_name);
ICALL_EXPORT guint64 ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetRuntimeCounterValue (gint32 counter);
ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo (uint64_t session_id, void *session_info);
ICALL_EXPORT intptr_t ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle (uint64_t session_id);
ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Tracing_EventPipeInternal_SignalSession (uint64_t session_id);
ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WaitForSessionSignal (uint64_t session_id, int32_t timeout);
ICALL_EXPORT void ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WriteEventData (intptr_t event_handle, void *event_data, uint32_t event_data_len, const uint8_t *activity_id, const uint8_t *related_activity_id);

ICALL_EXPORT void ves_icall_System_Diagnostics_Tracing_NativeRuntimeEventSource_LogThreadPoolIODequeue (intptr_t native_overlapped, intptr_t overlapped, uint16_t clr_instance_id);
Expand Down
5 changes: 3 additions & 2 deletions src/mono/mono/metadata/icall-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,9 @@ NOHANDLES(ICALL(EVENTPIPE_7, "GetNextEvent", ves_icall_System_Diagnostics_Tracin
NOHANDLES(ICALL(EVENTPIPE_8, "GetProvider", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetProvider))
NOHANDLES(ICALL(EVENTPIPE_9, "GetRuntimeCounterValue", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetRuntimeCounterValue))
NOHANDLES(ICALL(EVENTPIPE_10, "GetSessionInfo", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo))
NOHANDLES(ICALL(EVENTPIPE_11, "GetWaitHandle", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle))
NOHANDLES(ICALL(EVENTPIPE_12, "WriteEventData", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WriteEventData))
NOHANDLES(ICALL(EVENTPIPE_12, "SignalSession", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_SignalSession))
NOHANDLES(ICALL(EVENTPIPE_14, "WaitForSessionSignal", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WaitForSessionSignal))
NOHANDLES(ICALL(EVENTPIPE_13, "WriteEventData", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WriteEventData))

ICALL_TYPE(NATIVE_RUNTIME_EVENT_SOURCE, "System.Diagnostics.Tracing.NativeRuntimeEventSource", NATIVE_RUNTIME_EVENT_SOURCE_1)
NOHANDLES(ICALL(NATIVE_RUNTIME_EVENT_SOURCE_1, "LogThreadPoolIODequeue", ves_icall_System_Diagnostics_Tracing_NativeRuntimeEventSource_LogThreadPoolIODequeue))
Expand Down
33 changes: 26 additions & 7 deletions src/mono/mono/metadata/icall-eventpipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,18 @@ ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo (
return mono_component_event_pipe()->get_session_info (session_id, (EventPipeSessionInfo *)session_info) ? TRUE : FALSE;
}

intptr_t
ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle (uint64_t session_id)
MonoBoolean
ves_icall_System_Diagnostics_Tracing_EventPipeInternal_SignalSession (uint64_t session_id)
{
return (intptr_t) mono_component_event_pipe()->signal_session ((EventPipeSessionID)session_id);
}

MonoBoolean
ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WaitForSessionSignal (
uint64_t session_id,
int32_t timeout)
{
return (intptr_t) mono_component_event_pipe()->get_wait_handle ((EventPipeSessionID)session_id);
return (intptr_t) mono_component_event_pipe()->wait_for_session_signal ((EventPipeSessionID)session_id, (uint32_t)timeout);
}

void
Expand Down Expand Up @@ -577,13 +585,24 @@ ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo (
return FALSE;
}

intptr_t
ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle (uint64_t session_id)
MonoBoolean
ves_icall_System_Diagnostics_Tracing_EventPipeInternal_SignalSession (uint64_t session_id)
{
ERROR_DECL (error);
mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.GetWaitHandle");
mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.SignalSession");
mono_error_set_pending_exception (error);
return 0;
return FALSE;
}

MonoBoolean
ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WaitForSessionSignal (
uint64_t session_id,
int32_t timeout)
{
ERROR_DECL (error);
mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.WaitForSessionSignal");
mono_error_set_pending_exception (error);
return FALSE;
}

void
Expand Down
Loading