From f6c632a8ffe3012dcee9454253404e5f597da927 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 26 Aug 2019 18:35:38 +0300 Subject: [PATCH] [netcore] Implement missing ThreadPool methods (for metrics) (mono/mono#16076) * Implement missing ThreadPool methods * Address feedback * ifdef for mono_threadpool_worker_get_completed_threads_count * remove GetPendingUnmanagedWorkItemCount Commit migrated from https://github.com/mono/mono/commit/85265d884cf31f8779daba2d639eb795fbc9bd5e --- src/mono/mono/metadata/icall-def-netcore.h | 2 ++ src/mono/mono/metadata/threadpool-worker-default.c | 13 +++++++++++++ src/mono/mono/metadata/threadpool-worker-wasm.c | 12 ++++++++++++ src/mono/mono/metadata/threadpool-worker.h | 8 ++++++++ src/mono/mono/metadata/threadpool.c | 14 ++++++++++++++ src/mono/netcore/CoreFX.issues.rsp | 4 ---- .../src/System.Threading/ThreadPool.cs | 12 ++++++++++-- 7 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index 9b5ecff..d3c2570 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -519,8 +519,10 @@ NOHANDLES(ICALL(THREAD_14, "YieldInternal", ves_icall_System_Threading_Thread_Yi ICALL_TYPE(THREADP, "System.Threading.ThreadPool", THREADP_2) HANDLES(THREADP_2, "GetAvailableThreadsNative", ves_icall_System_Threading_ThreadPool_GetAvailableThreadsNative, void, 2, (gint32_ref, gint32_ref)) +HANDLES(THREADP_2a, "GetCompletedWorkItemCount", ves_icall_System_Threading_ThreadPool_GetCompletedWorkItemCount, gint64, 0, ()) HANDLES(THREADP_3, "GetMaxThreadsNative", ves_icall_System_Threading_ThreadPool_GetMaxThreadsNative, void, 2, (gint32_ref, gint32_ref)) HANDLES(THREADP_4, "GetMinThreadsNative", ves_icall_System_Threading_ThreadPool_GetMinThreadsNative, void, 2, (gint32_ref, gint32_ref)) +HANDLES(THREADP_4a, "GetThreadCount", ves_icall_System_Threading_ThreadPool_GetThreadCount, gint32, 0, ()) HANDLES(THREADP_5, "InitializeVMTp", ves_icall_System_Threading_ThreadPool_InitializeVMTp, void, 1, (MonoBoolean_ref)) HANDLES(THREADP_7, "NotifyWorkItemComplete", ves_icall_System_Threading_ThreadPool_NotifyWorkItemComplete, MonoBoolean, 0, ()) HANDLES(THREADP_8, "NotifyWorkItemProgressNative", ves_icall_System_Threading_ThreadPool_NotifyWorkItemProgressNative, void, 0, ()) diff --git a/src/mono/mono/metadata/threadpool-worker-default.c b/src/mono/mono/metadata/threadpool-worker-default.c index 0638125..aa9513e 100644 --- a/src/mono/mono/metadata/threadpool-worker-default.c +++ b/src/mono/mono/metadata/threadpool-worker-default.c @@ -349,6 +349,19 @@ mono_threadpool_worker_request (void) mono_refcount_dec (&worker); } +#ifdef ENABLE_NETCORE +gint64 mono_threadpool_worker_get_completed_threads_count (void) +{ + return worker.heuristic_completions; +} + +gint32 mono_threadpool_worker_get_threads_count (void) +{ + ThreadPoolWorkerCounter const counter = COUNTER_READ (); + return counter._.working; +} +#endif + /* return TRUE if timeout, FALSE otherwise (worker unpark or interrupt) */ static gboolean worker_park (void) diff --git a/src/mono/mono/metadata/threadpool-worker-wasm.c b/src/mono/mono/metadata/threadpool-worker-wasm.c index 8877df9..9eaa348 100644 --- a/src/mono/mono/metadata/threadpool-worker-wasm.c +++ b/src/mono/mono/metadata/threadpool-worker-wasm.c @@ -75,3 +75,15 @@ mono_threadpool_worker_notify_completed (void) { return FALSE; } + +#ifdef ENABLE_NETCORE +gint64 mono_threadpool_worker_get_completed_threads_count (void) +{ + return 0; +} + +gint32 mono_threadpool_worker_get_threads_count (void) +{ + return 0; +} +#endif diff --git a/src/mono/mono/metadata/threadpool-worker.h b/src/mono/mono/metadata/threadpool-worker.h index 9b2c51d..99bf52e 100644 --- a/src/mono/mono/metadata/threadpool-worker.h +++ b/src/mono/mono/metadata/threadpool-worker.h @@ -21,6 +21,14 @@ mono_threadpool_worker_request (void); gboolean mono_threadpool_worker_notify_completed (void); +#ifdef ENABLE_NETCORE +gint64 +mono_threadpool_worker_get_completed_threads_count (void); + +gint32 +mono_threadpool_worker_get_threads_count (void); +#endif + gint32 mono_threadpool_worker_get_min (void); gboolean diff --git a/src/mono/mono/metadata/threadpool.c b/src/mono/mono/metadata/threadpool.c index c9931a2..47a8dae 100644 --- a/src/mono/mono/metadata/threadpool.c +++ b/src/mono/mono/metadata/threadpool.c @@ -725,6 +725,20 @@ ves_icall_System_Threading_ThreadPool_SetMaxThreadsNative (gint32 worker_threads return TRUE; } +#ifdef ENABLE_NETCORE +gint32 +ves_icall_System_Threading_ThreadPool_GetThreadCount (MonoError *error) +{ + return mono_threadpool_worker_get_threads_count (); +} + +gint64 +ves_icall_System_Threading_ThreadPool_GetCompletedWorkItemCount (MonoError *error) +{ + return mono_threadpool_worker_get_completed_threads_count (); +} +#endif + void ves_icall_System_Threading_ThreadPool_InitializeVMTp (MonoBoolean *enable_worker_tracking, MonoError *error) { diff --git a/src/mono/netcore/CoreFX.issues.rsp b/src/mono/netcore/CoreFX.issues.rsp index 3dc9a0c..4321cce 100644 --- a/src/mono/netcore/CoreFX.issues.rsp +++ b/src/mono/netcore/CoreFX.issues.rsp @@ -610,10 +610,6 @@ # Explicitly skipped if it's MonoVM (SkipOnTargetFramework) -nomethod System.Threading.ThreadPools.Tests.ThreadPoolTests.SetMinMaxThreadsTest_ChangedInDotNetCore -# ThreadPool.CompletedWorkItemCount is not implemented -# https://github.com/mono/mono/issues/14829 --nomethod System.Threading.ThreadPools.Tests.ThreadPoolTests.MetricsTest - #################################################################### ## System.ComponentModel.Composition.Tests #################################################################### diff --git a/src/mono/netcore/System.Private.CoreLib/src/System.Threading/ThreadPool.cs b/src/mono/netcore/System.Private.CoreLib/src/System.Threading/ThreadPool.cs index 7e411bc..96e0460 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System.Threading/ThreadPool.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System.Threading/ThreadPool.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Threading { @@ -73,6 +74,13 @@ namespace System.Threading [MethodImplAttribute (MethodImplOptions.InternalCall)] static extern void GetAvailableThreadsNative (out int workerThreads, out int completionPortThreads); + [MethodImpl(MethodImplOptions.InternalCall)] + static extern long GetCompletedWorkItemCount (); + + [MethodImpl(MethodImplOptions.InternalCall)] + static extern int GetThreadCount (); + + public static bool SetMaxThreads (int workerThreads, int completionPortThreads) { return SetMaxThreadsNative (workerThreads, completionPortThreads); @@ -106,9 +114,9 @@ namespace System.Threading static long PendingUnmanagedWorkItemCount => 0; - public static long CompletedWorkItemCount => throw new PlatformNotSupportedException (); + public static long CompletedWorkItemCount => GetCompletedWorkItemCount (); - public static int ThreadCount => throw new NotImplementedException (); + public static int ThreadCount => GetThreadCount (); } internal static class _ThreadPoolWaitCallback -- 2.7.4