diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs index 96a7333de3434..c9cd0ed68eb17 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs @@ -66,7 +66,7 @@ public partial class Thread internal ExecutionContext? _executionContext; internal SynchronizationContext? _synchronizationContext; #if TARGET_UNIX || TARGET_BROWSER - internal WaitSubsystem.ThreadWaitInfo _waitInfo; + internal WaitSubsystem.ThreadWaitInfo? _waitInfo; #endif // This is used for a quick check on thread pool threads after running a work item to determine if the name, background @@ -138,9 +138,20 @@ internal static int OptimalMaxSpinWaitsPerSpinIteration return 7; } } - #if TARGET_UNIX || TARGET_BROWSER - internal WaitSubsystem.ThreadWaitInfo WaitInfo => _waitInfo; + internal WaitSubsystem.ThreadWaitInfo WaitInfo + { + get + { + return Volatile.Read(ref _waitInfo) ?? AllocateWaitInfo(); + + WaitSubsystem.ThreadWaitInfo AllocateWaitInfo() + { + Interlocked.CompareExchange(ref _waitInfo, new WaitSubsystem.ThreadWaitInfo(this), null!); + return _waitInfo; + } + } + } #endif public ThreadPriority Priority @@ -199,25 +210,13 @@ public bool Join(int millisecondsTimeout) } #if TARGET_UNIX || TARGET_BROWSER - [MemberNotNull(nameof(_waitInfo))] [DynamicDependency(nameof(OnThreadExiting))] #endif private void Initialize() { InitInternal(this); -#if TARGET_UNIX || TARGET_BROWSER - _waitInfo = new WaitSubsystem.ThreadWaitInfo(this); -#endif } -#if TARGET_UNIX || TARGET_BROWSER - private void EnsureWaitInfo() - { - if (_waitInfo == null) - _waitInfo = new WaitSubsystem.ThreadWaitInfo(this); - } -#endif - public static void SpinWait(int iterations) { if (iterations < 0) @@ -321,9 +320,6 @@ private static void OnThreadExiting(Thread thread) private static Thread InitializeCurrentThread() { var current = GetCurrentThread(); -#if TARGET_UNIX || TARGET_BROWSER - current.EnsureWaitInfo(); -#endif t_currentThread = current; return t_currentThread; }