From fac38bfb6f0ced48fac5101c6362d4e9975751a8 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Mon, 22 Jun 2020 15:59:33 -0700 Subject: [PATCH 1/5] Add AsyncCausalityTracer --- .../System.Private.CoreLib.Shared.projitems | 4 +- .../Tasks/AsyncCausalityTracer.Noop.cs | 46 -------- .../Threading/Tasks/AsyncCausalityTracer.cs | 110 ++++++++++++++++++ .../System/Threading/Tasks/TplEventSource.cs | 4 +- 4 files changed, 113 insertions(+), 51 deletions(-) delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 8552f8d884cbca..8fa57629194fb7 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -954,6 +954,7 @@ + @@ -1591,9 +1592,6 @@ - - - diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs deleted file mode 100644 index b00d5d67561928..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; - -namespace System.Threading.Tasks -{ - // - // Empty implementation of AsyncCausality events - // - internal static class AsyncCausalityTracer - { - public static bool LoggingOn => false; - - [Conditional("NOOP_ASYNCCASUALITYTRACER")] - public static void EnableToETW(bool enabled) - { - } - - [Conditional("NOOP_ASYNCCASUALITYTRACER")] - public static void TraceOperationCreation(Task task, string operationName) - { - } - - [Conditional("NOOP_ASYNCCASUALITYTRACER")] - public static void TraceOperationCompletion(Task task, AsyncCausalityStatus status) - { - } - - [Conditional("NOOP_ASYNCCASUALITYTRACER")] - public static void TraceOperationRelation(Task task, CausalityRelation relation) - { - } - - [Conditional("NOOP_ASYNCCASUALITYTRACER")] - public static void TraceSynchronousWorkStart(Task task, CausalitySynchronousWork work) - { - } - - [Conditional("NOOP_ASYNCCASUALITYTRACER")] - public static void TraceSynchronousWorkCompletion(CausalitySynchronousWork work) - { - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs new file mode 100644 index 00000000000000..10f46a51a0a445 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs @@ -0,0 +1,110 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Threading.Tasks +{ + internal static class AsyncCausalityTracer + { + internal static void Enable() + { + LoggingOn = true; + } + + internal static void Disable() + { + LoggingOn = false; + } + + internal static bool LoggingOn = false; // assumes false by default + + + // The TraceXXX methods should be called only if LoggingOn property returned true + // + [MethodImpl(MethodImplOptions.NoInlining)] // Tracking is slow path. Disable inlining for it. + internal static void TraceOperationCreation(Task task, string operationName) + { + try + { + if (LoggingOn) + TplEventSource.Log.TraceOperationBegin(task.Id, operationName, RelatedContext: 0); + } + catch (Exception ex) + { + // view function comment + LogAndDisable(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void TraceOperationCompletion(Task task, AsyncCausalityStatus status) + { + try + { + if (LoggingOn) + TplEventSource.Log.TraceOperationEnd(task.Id, status); + } + catch (Exception ex) + { + // view function comment + LogAndDisable(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void TraceOperationRelation(Task task, CausalityRelation relation) + { + try + { + if (LoggingOn) + TplEventSource.Log.TraceOperationRelation(task.Id, relation); + } + catch (Exception ex) + { + // view function comment + LogAndDisable(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void TraceSynchronousWorkStart(Task task, CausalitySynchronousWork work) + { + try + { + if (LoggingOn) + TplEventSource.Log.TraceSynchronousWorkBegin(task.Id, work); + } + catch (Exception ex) + { + // view function comment + LogAndDisable(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void TraceSynchronousWorkCompletion(CausalitySynchronousWork work) + { + try + { + if (LoggingOn) + TplEventSource.Log.TraceSynchronousWorkEnd(work); + } + catch (Exception ex) + { + // view function comment + LogAndDisable(ex); + } + } + + // fix for 796185: leaking internal exceptions to customers, + // we should catch and log exceptions but never propagate them. + private static void LogAndDisable(Exception ex) + { + Disable(); + Debugger.Log(0, "AsyncCausalityTracer", ex.ToString()); + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index c1a1d20b0e1d84..81ccebe460dd31 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -35,9 +35,9 @@ protected override void OnEventCommand(EventCommandEventArgs command) { // To get the AsyncCausality events, we need to inform the AsyncCausalityTracer if (command.Command == EventCommand.Enable) - AsyncCausalityTracer.EnableToETW(true); + AsyncCausalityTracer.Enable(); else if (command.Command == EventCommand.Disable) - AsyncCausalityTracer.EnableToETW(false); + AsyncCausalityTracer.Disable(); if (IsEnabled(EventLevel.Informational, Keywords.TasksFlowActivityIds)) ActivityTracker.Instance.Enable(); From b72cfc4531ebddacc058337a3c7a692ebbbcdc70 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Tue, 23 Jun 2020 16:02:15 -0700 Subject: [PATCH 2/5] cleanup --- .../src/System/Threading/Tasks/AsyncCausalityTracer.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs index 10f46a51a0a445..37ad8327f54dc6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs @@ -19,8 +19,7 @@ internal static void Disable() LoggingOn = false; } - internal static bool LoggingOn = false; // assumes false by default - + internal static bool LoggingOn = false; // The TraceXXX methods should be called only if LoggingOn property returned true // @@ -34,7 +33,6 @@ internal static void TraceOperationCreation(Task task, string operationName) } catch (Exception ex) { - // view function comment LogAndDisable(ex); } } @@ -49,7 +47,6 @@ internal static void TraceOperationCompletion(Task task, AsyncCausalityStatus st } catch (Exception ex) { - // view function comment LogAndDisable(ex); } } @@ -64,7 +61,6 @@ internal static void TraceOperationRelation(Task task, CausalityRelation relatio } catch (Exception ex) { - // view function comment LogAndDisable(ex); } } @@ -79,7 +75,6 @@ internal static void TraceSynchronousWorkStart(Task task, CausalitySynchronousWo } catch (Exception ex) { - // view function comment LogAndDisable(ex); } } @@ -94,7 +89,6 @@ internal static void TraceSynchronousWorkCompletion(CausalitySynchronousWork wor } catch (Exception ex) { - // view function comment LogAndDisable(ex); } } From ef7c061b37a71bd8c668fe1dfac8ea0cc8c21c3b Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Tue, 23 Jun 2020 17:31:43 -0700 Subject: [PATCH 3/5] Handle multiple sessions --- .../src/System/Threading/Tasks/AsyncCausalityTracer.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs index 37ad8327f54dc6..ef7adb600a78e0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs @@ -11,15 +11,16 @@ internal static class AsyncCausalityTracer { internal static void Enable() { - LoggingOn = true; + Interlocked.Increment(ref listenerCnt); } internal static void Disable() { - LoggingOn = false; + Interlocked.Decrement(ref listenerCnt); } - internal static bool LoggingOn = false; + internal static bool LoggingOn => listenerCnt > 0; + private static int listenerCnt = 0; // The TraceXXX methods should be called only if LoggingOn property returned true // From ca75f31f473455fc78685251b635a38e851127c0 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Tue, 23 Jun 2020 18:06:31 -0700 Subject: [PATCH 4/5] CR feedback --- .../Threading/Tasks/AsyncCausalityTracer.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs index ef7adb600a78e0..dba01b7ca51982 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs @@ -29,8 +29,7 @@ internal static void TraceOperationCreation(Task task, string operationName) { try { - if (LoggingOn) - TplEventSource.Log.TraceOperationBegin(task.Id, operationName, RelatedContext: 0); + TplEventSource.Log.TraceOperationBegin(task.Id, operationName, RelatedContext: 0); } catch (Exception ex) { @@ -43,8 +42,7 @@ internal static void TraceOperationCompletion(Task task, AsyncCausalityStatus st { try { - if (LoggingOn) - TplEventSource.Log.TraceOperationEnd(task.Id, status); + TplEventSource.Log.TraceOperationEnd(task.Id, status); } catch (Exception ex) { @@ -57,8 +55,7 @@ internal static void TraceOperationRelation(Task task, CausalityRelation relatio { try { - if (LoggingOn) - TplEventSource.Log.TraceOperationRelation(task.Id, relation); + TplEventSource.Log.TraceOperationRelation(task.Id, relation); } catch (Exception ex) { @@ -71,8 +68,7 @@ internal static void TraceSynchronousWorkStart(Task task, CausalitySynchronousWo { try { - if (LoggingOn) - TplEventSource.Log.TraceSynchronousWorkBegin(task.Id, work); + TplEventSource.Log.TraceSynchronousWorkBegin(task.Id, work); } catch (Exception ex) { @@ -85,8 +81,7 @@ internal static void TraceSynchronousWorkCompletion(CausalitySynchronousWork wor { try { - if (LoggingOn) - TplEventSource.Log.TraceSynchronousWorkEnd(work); + TplEventSource.Log.TraceSynchronousWorkEnd(work); } catch (Exception ex) { @@ -94,7 +89,6 @@ internal static void TraceSynchronousWorkCompletion(CausalitySynchronousWork wor } } - // fix for 796185: leaking internal exceptions to customers, // we should catch and log exceptions but never propagate them. private static void LogAndDisable(Exception ex) { From 01a5d56248cbbd2b2370d61e704404c29c0838a3 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Fri, 26 Jun 2020 02:43:02 -0700 Subject: [PATCH 5/5] Remove AsyncCausalityTracer and replace it with direct calls to TplEventSource --- .../System.Private.CoreLib.Shared.projitems | 1 - .../AsyncTaskMethodBuilderT.cs | 14 +-- .../AsyncVoidMethodBuilder.cs | 8 +- .../Threading/Tasks/AsyncCausalityTracer.cs | 99 ------------------- .../System/Threading/Tasks/FutureFactory.cs | 44 ++++----- .../src/System/Threading/Tasks/Task.cs | 88 ++++++++--------- .../Threading/Tasks/TaskContinuation.cs | 8 +- .../src/System/Threading/Tasks/TaskFactory.cs | 34 +++---- .../System/Threading/Tasks/TplEventSource.cs | 6 -- 9 files changed, 98 insertions(+), 204 deletions(-) delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 8fa57629194fb7..8076e2948cabfa 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -954,7 +954,6 @@ - diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs index e195976f1f8c53..9448db0c273317 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs @@ -229,9 +229,9 @@ private static IAsyncStateMachineBox GetStateMachineBox( box.Context = currentContext; // Log the creation of the state machine box object / task for this async method. - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationCreation(box, "Async: " + stateMachine.GetType().Name); + TplEventSource.Log.TraceOperationBegin(box.Id, "Async: " + stateMachine.GetType().Name, 0); } // And if async debugging is enabled, track the task. @@ -310,10 +310,10 @@ private void MoveNext(Thread? threadPoolThread) { Debug.Assert(!IsCompleted); - bool loggingOn = AsyncCausalityTracer.LoggingOn; + bool loggingOn = TplEventSource.Log.IsEnabled(); if (loggingOn) { - AsyncCausalityTracer.TraceSynchronousWorkStart(this, CausalitySynchronousWork.Execution); + TplEventSource.Log.TraceSynchronousWorkBegin(this.Id, CausalitySynchronousWork.Execution); } ExecutionContext? context = Context; @@ -361,7 +361,7 @@ private void MoveNext(Thread? threadPoolThread) if (loggingOn) { - AsyncCausalityTracer.TraceSynchronousWorkCompletion(CausalitySynchronousWork.Execution); + TplEventSource.Log.TraceSynchronousWorkEnd(CausalitySynchronousWork.Execution); } } @@ -433,9 +433,9 @@ internal static void SetExistingTaskResult(Task task, [AllowNull] TResu { Debug.Assert(task != null, "Expected non-null task"); - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationCompletion(task, AsyncCausalityStatus.Completed); + TplEventSource.Log.TraceOperationEnd(task.Id, AsyncCausalityStatus.Completed); } if (!task.TrySetResult(result)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs index 3a0a0a2c63093b..9370d11161d613 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncVoidMethodBuilder.cs @@ -76,9 +76,9 @@ public void AwaitUnsafeOnCompleted( /// Completes the method builder successfully. public void SetResult() { - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationCompletion(this.Task, AsyncCausalityStatus.Completed); + TplEventSource.Log.TraceOperationEnd(this.Task.Id, AsyncCausalityStatus.Completed); } // Mark the builder as completed. As this is a void-returning method, this mostly @@ -102,9 +102,9 @@ public void SetException(Exception exception) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception); } - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationCompletion(this.Task, AsyncCausalityStatus.Error); + TplEventSource.Log.TraceOperationEnd(this.Task.Id, AsyncCausalityStatus.Error); } if (_synchronizationContext != null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs deleted file mode 100644 index dba01b7ca51982..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System.Threading.Tasks -{ - internal static class AsyncCausalityTracer - { - internal static void Enable() - { - Interlocked.Increment(ref listenerCnt); - } - - internal static void Disable() - { - Interlocked.Decrement(ref listenerCnt); - } - - internal static bool LoggingOn => listenerCnt > 0; - private static int listenerCnt = 0; - - // The TraceXXX methods should be called only if LoggingOn property returned true - // - [MethodImpl(MethodImplOptions.NoInlining)] // Tracking is slow path. Disable inlining for it. - internal static void TraceOperationCreation(Task task, string operationName) - { - try - { - TplEventSource.Log.TraceOperationBegin(task.Id, operationName, RelatedContext: 0); - } - catch (Exception ex) - { - LogAndDisable(ex); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void TraceOperationCompletion(Task task, AsyncCausalityStatus status) - { - try - { - TplEventSource.Log.TraceOperationEnd(task.Id, status); - } - catch (Exception ex) - { - LogAndDisable(ex); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void TraceOperationRelation(Task task, CausalityRelation relation) - { - try - { - TplEventSource.Log.TraceOperationRelation(task.Id, relation); - } - catch (Exception ex) - { - LogAndDisable(ex); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void TraceSynchronousWorkStart(Task task, CausalitySynchronousWork work) - { - try - { - TplEventSource.Log.TraceSynchronousWorkBegin(task.Id, work); - } - catch (Exception ex) - { - LogAndDisable(ex); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void TraceSynchronousWorkCompletion(CausalitySynchronousWork work) - { - try - { - TplEventSource.Log.TraceSynchronousWorkEnd(work); - } - catch (Exception ex) - { - LogAndDisable(ex); - } - } - - // we should catch and log exceptions but never propagate them. - private static void LogAndDisable(Exception ex) - { - Disable(); - Debugger.Log(0, "AsyncCausalityTracer", ex.ToString()); - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs index f3da02daa786f5..9eccd0c0a84ae1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs @@ -527,8 +527,8 @@ private static void FromAsyncCoreLogic( } else { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCompletion(promise, AsyncCausalityStatus.Completed); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationEnd(promise.Id, AsyncCausalityStatus.Completed); if (Task.s_asyncDebuggingEnabled) Task.RemoveFromActiveTasks(promise); @@ -649,8 +649,8 @@ internal static Task FromAsyncImpl( Task promise = new Task((object?)null, creationOptions); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(promise.Id, "TaskFactory.FromAsync", 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -665,8 +665,8 @@ internal static Task FromAsyncImpl( (object?)null, null, default, TaskCreationOptions.None, InternalTaskOptions.None, null); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(t, "TaskFactory.FromAsync Callback"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(t.Id, "TaskFactory.FromAsync Callback", 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(t); @@ -764,8 +764,8 @@ internal static Task FromAsyncImpl(Func promise = new Task(state, creationOptions); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(promise.Id, "TaskFactory.FromAsync: " + beginMethod.Method.Name, 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -786,8 +786,8 @@ internal static Task FromAsyncImpl(Func FromAsyncImpl(Func promise = new Task(state, creationOptions); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(promise.Id, "TaskFactory.FromAsync: " + beginMethod.Method.Name, 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -903,8 +903,8 @@ internal static Task FromAsyncImpl(Func FromAsyncImpl(Func promise = new Task(state, creationOptions); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(promise.Id, "TaskFactory.FromAsync: " + beginMethod.Method.Name, 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -1028,8 +1028,8 @@ internal static Task FromAsyncImpl(Func FromAsyncImpl(Func promise = new Task(state, creationOptions); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(promise.Id, "TaskFactory.FromAsync: " + beginMethod.Method.Name, 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -1161,8 +1161,8 @@ internal static Task FromAsyncImpl(Func 0, "Expected a non-zero length task array"); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(this, "Task.WhenAll"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(this.Id, "Task.WhenAll", 0); if (s_asyncDebuggingEnabled) AddToActiveTasks(this); @@ -5606,8 +5606,8 @@ internal WhenAllPromise(Task[] tasks) public void Invoke(Task completedTask) { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Join); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Join); // Decrement the count, and only continue to complete the promise if we're the last one. if (Interlocked.Decrement(ref m_count) == 0) @@ -5655,8 +5655,8 @@ public void Invoke(Task completedTask) } else { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); if (s_asyncDebuggingEnabled) RemoveFromActiveTasks(this); @@ -5824,8 +5824,8 @@ internal WhenAllPromise(Task[] tasks) m_tasks = tasks; m_count = tasks.Length; - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(this, "Task.WhenAll"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(this.Id, "Task.WhenAll", 0); if (s_asyncDebuggingEnabled) AddToActiveTasks(this); @@ -5839,8 +5839,8 @@ internal WhenAllPromise(Task[] tasks) public void Invoke(Task ignored) { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Join); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Join); // Decrement the count, and only continue to complete the promise if we're the last one. if (Interlocked.Decrement(ref m_count) == 0) @@ -5894,8 +5894,8 @@ public void Invoke(Task ignored) } else { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); if (Task.s_asyncDebuggingEnabled) RemoveFromActiveTasks(this); @@ -6000,9 +6000,9 @@ public TwoTaskWhenAnyPromise(TTask task1, TTask task2) _task1 = task1; _task2 = task2; - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationCreation(this, "Task.WhenAny"); + TplEventSource.Log.TraceOperationBegin(this.Id, "Task.WhenAny", 0); } if (s_asyncDebuggingEnabled) @@ -6035,10 +6035,10 @@ public void Invoke(Task completingTask) Debug.Assert(task1 != null && task2 != null); Debug.Assert(task1.IsCompleted || task2.IsCompleted); - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Choice); - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Choice); + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); } if (s_asyncDebuggingEnabled) @@ -6526,8 +6526,8 @@ public UnwrapPromise(Task outerTask, bool lookForOce) _lookForOce = lookForOce; _state = STATE_WAITING_ON_OUTER_TASK; - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(this, "Task.Unwrap"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(this.Id, "Task.Unwrap", 0); if (s_asyncDebuggingEnabled) AddToActiveTasks(this); @@ -6636,8 +6636,8 @@ private bool TrySetFromTask(Task task, bool lookForOce) { Debug.Assert(task != null && task.IsCompleted, "TrySetFromTask: Expected task to have completed."); - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Join); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Join); bool result = false; switch (task.Status) @@ -6662,8 +6662,8 @@ private bool TrySetFromTask(Task task, bool lookForOce) break; case TaskStatus.RanToCompletion: - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); if (Task.s_asyncDebuggingEnabled) RemoveFromActiveTasks(this); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs index b4571cff6881a8..a5717b11e6994b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs @@ -277,8 +277,8 @@ internal ContinueWithTaskContinuation(Task task, TaskContinuationOptions options m_task = task; m_options = options; m_taskScheduler = scheduler; - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(m_task, "Task.ContinueWith: " + task.m_action!.Method.Name); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(m_task.Id, "Task.ContinueWith: " + task.m_action!.Method.Name, 0); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(m_task); @@ -312,10 +312,10 @@ internal override void Run(Task completedTask, bool canInlineContinuationTask) // If the task was cancel before running (e.g a ContinueWhenAll with a cancelled caancelation token) // we will still flow it to ScheduleAndStart() were it will check the status before running // We check here to avoid faulty logs that contain a join event to an operation that was already set as completed. - if (!continuationTask.IsCanceled && AsyncCausalityTracer.LoggingOn) + if (!continuationTask.IsCanceled && TplEventSource.Log.IsEnabled()) { // Log now that we are sure that this continuation is being ran - AsyncCausalityTracer.TraceOperationRelation(continuationTask, CausalityRelation.AssignDelegate); + TplEventSource.Log.TraceOperationRelation(continuationTask.Id, CausalityRelation.AssignDelegate); } continuationTask.m_taskScheduler = m_taskScheduler; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskFactory.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskFactory.cs index c10aae54db5712..8b883bac5eb820 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskFactory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskFactory.cs @@ -1557,8 +1557,8 @@ internal CompleteOnCountdownPromise(Task[] tasksCopy) _tasks = tasksCopy; _count = tasksCopy.Length; - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(this, "TaskFactory.ContinueWhenAll"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(this.Id, "TaskFactory.ContinueWhenAll", 0); if (Task.s_asyncDebuggingEnabled) AddToActiveTasks(this); @@ -1566,14 +1566,14 @@ internal CompleteOnCountdownPromise(Task[] tasksCopy) public void Invoke(Task completingTask) { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Join); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Join); if (completingTask.IsWaitNotificationEnabled) this.SetNotificationForWaitCompletion(enabled: true); if (Interlocked.Decrement(ref _count) == 0) { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); if (Task.s_asyncDebuggingEnabled) RemoveFromActiveTasks(this); @@ -1627,8 +1627,8 @@ internal CompleteOnCountdownPromise(Task[] tasksCopy) _tasks = tasksCopy; _count = tasksCopy.Length; - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(this, "TaskFactory.ContinueWhenAll<>"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(this.Id, "TaskFactory.ContinueWhenAll<>", 0); if (Task.s_asyncDebuggingEnabled) AddToActiveTasks(this); @@ -1636,14 +1636,14 @@ internal CompleteOnCountdownPromise(Task[] tasksCopy) public void Invoke(Task completingTask) { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Join); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Join); if (completingTask.IsWaitNotificationEnabled) this.SetNotificationForWaitCompletion(enabled: true); if (Interlocked.Decrement(ref _count) == 0) { - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); if (Task.s_asyncDebuggingEnabled) RemoveFromActiveTasks(this); @@ -2282,8 +2282,8 @@ public CompleteOnInvokePromise(IList tasks, bool isSyncBlocking) _stateFlags = SyncBlockingFlag; } - if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(this, "TaskFactory.ContinueWhenAny"); + if (TplEventSource.Log.IsEnabled()) + TplEventSource.Log.TraceOperationBegin(this.Id, "TaskFactory.ContinueWhenAny", 0); if (Task.s_asyncDebuggingEnabled) AddToActiveTasks(this); @@ -2298,10 +2298,10 @@ public void Invoke(Task completingTask) if (isCompleted == 0 && Interlocked.Exchange(ref _stateFlags, isSyncBlockingFlag | CompletedFlag) == isSyncBlockingFlag) { - if (AsyncCausalityTracer.LoggingOn) + if (TplEventSource.Log.IsEnabled()) { - AsyncCausalityTracer.TraceOperationRelation(this, CausalityRelation.Choice); - AsyncCausalityTracer.TraceOperationCompletion(this, AsyncCausalityStatus.Completed); + TplEventSource.Log.TraceOperationRelation(this.Id, CausalityRelation.Choice); + TplEventSource.Log.TraceOperationEnd(this.Id, AsyncCausalityStatus.Completed); } if (Task.s_asyncDebuggingEnabled) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index 81ccebe460dd31..c8f798dbdacd8d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -33,12 +33,6 @@ internal sealed class TplEventSource : EventSource /// protected override void OnEventCommand(EventCommandEventArgs command) { - // To get the AsyncCausality events, we need to inform the AsyncCausalityTracer - if (command.Command == EventCommand.Enable) - AsyncCausalityTracer.Enable(); - else if (command.Command == EventCommand.Disable) - AsyncCausalityTracer.Disable(); - if (IsEnabled(EventLevel.Informational, Keywords.TasksFlowActivityIds)) ActivityTracker.Instance.Enable(); else