From: Stephen Toub Date: Thu, 2 Feb 2017 16:51:28 +0000 (-0500) Subject: Remove StackCrawlMark goo from {Unsafe}QueueUserWorkItem X-Git-Tag: submit/tizen/20210909.063632~11030^2~8228^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=678e2993b632506090871eceebda8a9a7e6e716f;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Remove StackCrawlMark goo from {Unsafe}QueueUserWorkItem Allow more methods to be inlined Commit migrated from https://github.com/dotnet/coreclr/commit/d41bffbfeb3f5adf1b0e6a0309d8a23294b91f0a --- diff --git a/src/coreclr/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/coreclr/src/mscorlib/src/System/Threading/ThreadPool.cs index 789fd7a..5f869d7 100644 --- a/src/coreclr/src/mscorlib/src/System/Threading/ThreadPool.cs +++ b/src/coreclr/src/mscorlib/src/System/Threading/ThreadPool.cs @@ -1267,64 +1267,40 @@ namespace System.Threading StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,false); } - - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public static bool QueueUserWorkItem( - WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC - Object state - ) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return QueueUserWorkItemHelper(callBack,state,ref stackMark,true); - } - - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public static bool QueueUserWorkItem( - WaitCallback callBack // NOTE: we do not expose options that allow the callback to be queued as an APC - ) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return QueueUserWorkItemHelper(callBack,null,ref stackMark,true); - } - - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public static bool UnsafeQueueUserWorkItem( - WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC - Object state - ) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return QueueUserWorkItemHelper(callBack,state,ref stackMark,false); - } - //ThreadPool has per-appdomain managed queue of work-items. The VM is - //responsible for just scheduling threads into appdomains. After that - //work-items are dispatched from the managed queue. - private static bool QueueUserWorkItemHelper(WaitCallback callBack, Object state, ref StackCrawlMark stackMark, bool compressStack) + public static bool QueueUserWorkItem(WaitCallback callBack) => + QueueUserWorkItem(callBack, null); + + public static bool QueueUserWorkItem(WaitCallback callBack, object state) { if (callBack == null) { - throw new ArgumentNullException(nameof(callBack)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callBack); } - //The thread pool maintains a per-appdomain managed work queue. - //New thread pool entries are added in the managed queue. - //The VM is responsible for the actual growing/shrinking of - //threads. - EnsureVMInitialized(); - // - // If we are able to create the workitem, we need to get it in the queue without being interrupted - // by a ThreadAbortException. - // - ExecutionContext context = compressStack && !ExecutionContext.IsFlowSuppressed() ? - ExecutionContext.Capture(ref stackMark, ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase) : - null; + ExecutionContext context = ExecutionContext.Capture(); IThreadPoolWorkItem tpcallBack = context == ExecutionContext.PreAllocatedDefault ? - new QueueUserWorkItemCallbackDefaultContext(callBack, state) : - (IThreadPoolWorkItem)new QueueUserWorkItemCallback(callBack, state, context); + new QueueUserWorkItemCallbackDefaultContext(callBack, state) : + (IThreadPoolWorkItem)new QueueUserWorkItemCallback(callBack, state, context); + + ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); + + return true; + } + + public static bool UnsafeQueueUserWorkItem(WaitCallback callBack, Object state) + { + if (callBack == null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callBack); + } + + EnsureVMInitialized(); + + IThreadPoolWorkItem tpcallBack = new QueueUserWorkItemCallback(callBack, state, null); ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); @@ -1335,10 +1311,6 @@ namespace System.Threading { Debug.Assert(null != workItem); EnsureVMInitialized(); - - // - // Enqueue needs to be protected from ThreadAbort - // ThreadPoolGlobals.workQueue.Enqueue(workItem, forceGlobal); } @@ -1437,6 +1409,10 @@ namespace System.Threading unsafe public static bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped) => PostQueuedCompletionStatus(overlapped); + // The thread pool maintains a per-appdomain managed work queue. + // New thread pool entries are added in the managed queue. + // The VM is responsible for the actual growing/shrinking of + // threads. private static void EnsureVMInitialized() { if (!ThreadPoolGlobals.vmTpInitialized) diff --git a/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs b/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs index f487bf6..6b90f89 100644 --- a/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs +++ b/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs @@ -361,7 +361,7 @@ namespace System { updateValueFactory, concurrencyLevel, text, - + callBack, } //