diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs index 8269557f6c5869..20682ecdfb8b58 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs @@ -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); } } diff --git a/src/coreclr/vm/eventpipeadapter.h b/src/coreclr/vm/eventpipeadapter.h index 6bde11ccc0ed3b..93cb7a49408ed6 100644 --- a/src/coreclr/vm/eventpipeadapter.h +++ b/src/coreclr/vm/eventpipeadapter.h @@ -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(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) diff --git a/src/coreclr/vm/eventpipeinternal.cpp b/src/coreclr/vm/eventpipeinternal.cpp index 5e9117cf8456ff..454a4bdae04e0e 100644 --- a/src/coreclr/vm/eventpipeinternal.cpp +++ b/src/coreclr/vm/eventpipeinternal.cpp @@ -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 diff --git a/src/coreclr/vm/eventpipeinternal.h b/src/coreclr/vm/eventpipeinternal.h index bf57fed8b5acf3..7da96b67ea7b56 100644 --- a/src/coreclr/vm/eventpipeinternal.h +++ b/src/coreclr/vm/eventpipeinternal.h @@ -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( @@ -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__ diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index d2e3a558a7079c..670698736c7d46 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -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) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs index 92735de38e22e3..02dc1c2ff9a88d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventDispatcher.cs @@ -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 m_subscriptions = new Dictionary(); @@ -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) @@ -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); } } @@ -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; } @@ -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); diff --git a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.Mono.cs index 722f2b73a64f4a..21db2adac42126 100644 --- a/src/mono/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.Mono.cs @@ -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 // diff --git a/src/mono/mono/component/event_pipe-stub.c b/src/mono/mono/component/event_pipe-stub.c index e925629ae90acf..cb82a216b2d3d6 100644 --- a/src/mono/mono/component/event_pipe-stub.c +++ b/src/mono/mono/component/event_pipe-stub.c @@ -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); @@ -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 @@ -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) { diff --git a/src/mono/mono/component/event_pipe.c b/src/mono/mono/component/event_pipe.c index c23a694714de6e..3c950bf11ccb43 100644 --- a/src/mono/mono/component/event_pipe.c +++ b/src/mono/mono/component/event_pipe.c @@ -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, @@ -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 @@ -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) { @@ -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) { diff --git a/src/mono/mono/component/event_pipe.h b/src/mono/mono/component/event_pipe.h index c67e3b82867cfe..5e4d3861c149ce 100644 --- a/src/mono/mono/component/event_pipe.h +++ b/src/mono/mono/component/event_pipe.h @@ -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. */ @@ -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 diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index ded4fb18faa0e0..2d2c51a393388e 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -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); diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index 181396cccc2b33..8b4fb4390d8374 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -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)) diff --git a/src/mono/mono/metadata/icall-eventpipe.c b/src/mono/mono/metadata/icall-eventpipe.c index 78dba38de681f9..f7ee2635e2a1d0 100644 --- a/src/mono/mono/metadata/icall-eventpipe.c +++ b/src/mono/mono/metadata/icall-eventpipe.c @@ -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 @@ -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 diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 06083fa082eeca..cd63b4c46356cc 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1460,9 +1460,6 @@ https://github.com/dotnet/runtime/issues/54185 - - https://github.com/dotnet/runtime/issues/68032 - Mono does not define out of range fp to int conversions @@ -3077,6 +3074,9 @@ needs triage + + Build doesn't include diagnostics tracing + Test not expected to work with AOT @@ -3610,6 +3610,9 @@ Could not load legacy Microsoft.Diagnostics.Tools.RuntimeClient + + WASM doesn't support diagnostics tracing +