diff options
author | Neale Ferguson <neale@sinenomine.net> | 2022-05-27 12:25:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-27 12:25:11 +0300 |
commit | 9f5ebbdc31fe1c836aef9357be935bb5450e77b5 (patch) | |
tree | 592d7c55a17a999dbb39b78962e2c04a7b42a16f | |
parent | a76b50e5faa69d4cfe6c5ddfc58bbbba9d28b29c (diff) |
Backport 4caf2b3dccee96d3d3bf1b95972761e32e62117c to 5.16 (#21496)2018-06
-rw-r--r-- | .gitmodules | 38 | ||||
-rw-r--r-- | mono/metadata/threadpool-worker-default.c | 70 |
2 files changed, 76 insertions, 32 deletions
diff --git a/.gitmodules b/.gitmodules index 4e968d7a066..74cfae3eab2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,60 +1,60 @@ [submodule "external/aspnetwebstack"] path = external/aspnetwebstack - url = git://github.com/mono/aspnetwebstack.git + url = https://github.com/mono/aspnetwebstack.git [submodule "external/Newtonsoft.Json"] path = external/Newtonsoft.Json - url = git://github.com/mono/Newtonsoft.Json.git + url = https://github.com/mono/Newtonsoft.Json.git [submodule "external/cecil"] path = external/cecil - url = git://github.com/mono/cecil.git + url = https://github.com/mono/cecil.git [submodule "external/rx"] path = external/rx - url = git://github.com/mono/rx.git + url = https://github.com/mono/rx.git branch = rx-oss-v2.2 [submodule "external/ikvm"] path = external/ikvm - url = git://github.com/mono/ikvm-fork.git + url = https://github.com/mono/ikvm-fork.git [submodule "external/ikdasm"] path = external/ikdasm - url = git://github.com/mono/ikdasm.git + url = https://github.com/mono/ikdasm.git [submodule "external/reference-assemblies"] path = external/binary-reference-assemblies - url = git://github.com/mono/reference-assemblies.git + url = https://github.com/mono/reference-assemblies.git [submodule "external/nunit-lite"] path = external/nunit-lite - url = git://github.com/mono/NUnitLite.git + url = https://github.com/mono/NUnitLite.git [submodule "external/nuget-buildtasks"] path = external/nuget-buildtasks - url = git://github.com/mono/NuGet.BuildTasks + url = https://github.com/mono/NuGet.BuildTasks [submodule "external/cecil-legacy"] path = external/cecil-legacy - url = git://github.com/mono/cecil.git + url = https://github.com/mono/cecil.git branch = mono-legacy-0.9.5 [submodule "external/boringssl"] path = external/boringssl - url = git://github.com/mono/boringssl.git + url = https://github.com/mono/boringssl.git branch = mono [submodule "external/corefx"] path = external/corefx - url = git://github.com/mono/corefx.git + url = https://github.com/mono/corefx.git [submodule "external/bockbuild"] path = external/bockbuild - url = git://github.com/mono/bockbuild.git + url = https://github.com/mono/bockbuild.git [submodule "external/linker"] path = external/linker - url = git://github.com/mono/linker.git + url = https://github.com/mono/linker.git [submodule "external/roslyn-binaries"] path = external/roslyn-binaries - url = git://github.com/mono/roslyn-binaries.git + url = https://github.com/mono/roslyn-binaries.git [submodule "external/corert"] path = external/corert - url = git://github.com/mono/corert.git + url = https://github.com/mono/corert.git [submodule "external/xunit-binaries"] path = external/xunit-binaries - url = git://github.com/mono/xunit-binaries.git + url = https://github.com/mono/xunit-binaries.git [submodule "external/api-doc-tools"] path = external/api-doc-tools - url = git://github.com/mono/api-doc-tools.git + url = https://github.com/mono/api-doc-tools.git [submodule "external/api-snapshot"] path = external/api-snapshot - url = git://github.com/mono/api-snapshot.git + url = https://github.com/mono/api-snapshot.git diff --git a/mono/metadata/threadpool-worker-default.c b/mono/metadata/threadpool-worker-default.c index 33870a6de15..3779b8471f2 100644 --- a/mono/metadata/threadpool-worker-default.c +++ b/mono/metadata/threadpool-worker-default.c @@ -194,6 +194,14 @@ COUNTER_READ (void) return counter; } +static gint16 +counter_num_active (ThreadPoolWorkerCounter counter) +{ + gint16 num_active = counter._.starting + counter._.working + counter._.parked; + g_assert (num_active >= 0); + return num_active; +} + static gpointer rand_create (void) { @@ -453,6 +461,8 @@ worker_try_unpark (void) return res; } +static void hill_climbing_force_change (gint16 new_thread_count, ThreadPoolHeuristicStateTransition transition); + static gsize WINAPI worker_thread (gpointer unused) { @@ -473,16 +483,18 @@ worker_thread (gpointer unused) thread = mono_thread_internal_current (); g_assert (thread); + gboolean worker_timed_out = FALSE; while (!mono_runtime_is_shutting_down ()) { if (mono_thread_interruption_checkpoint_bool ()) continue; if (!work_item_try_pop ()) { - gboolean timeout; + gboolean const timeout = worker_park(); - timeout = worker_park (); - if (timeout) + if (timeout) { + worker_timed_out = TRUE; break; + } continue; } @@ -497,6 +509,19 @@ worker_thread (gpointer unused) counter._.working --; }); + if (worker_timed_out) { + gint16 decr_max_working; + COUNTER_ATOMIC (counter, { + decr_max_working = MAX (worker.limit_worker_min, MIN (counter_num_active (counter), counter._.max_working)); + counter._.max_working = decr_max_working; + }); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] worker timed out, starting = %d working = %d parked = %d, setting max_working to %d", + GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ())), + counter._.starting, counter._.working, counter._.parked, + decr_max_working); + hill_climbing_force_change (decr_max_working, TRANSITION_THREAD_TIMED_OUT); + } + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] worker finishing", GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()))); @@ -659,8 +684,6 @@ monitor_sufficient_delay_since_last_dequeue (void) return mono_msec_ticks () >= worker.heuristic_last_dequeue + threshold; } -static void hill_climbing_force_change (gint16 new_thread_count, ThreadPoolHeuristicStateTransition transition); - static gsize WINAPI monitor_thread (gpointer unused) { @@ -688,9 +711,16 @@ monitor_thread (gpointer unused) g_assert (worker.monitor_status != MONITOR_STATUS_NOT_RUNNING); - // counter = COUNTER_READ (); - // printf ("monitor_thread: starting = %d working = %d parked = %d max_working = %d\n", - // counter._.starting, counter._.working, counter._.parked, counter._.max_working); +#if 0 + // This is ifdef'd out because otherwise we flood the log every + // MONITOR_INTERVAL ms, which is pretty noisy. + if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL)) { + ThreadPoolWorkerCounter trace_counter = COUNTER_READ (); + gint32 work_items = work_item_count (); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "monitor_thread: work items = %d, starting = %d working = %d parked = %d max_working = %d\n", + work_items, trace_counter._.starting, trace_counter._.working, trace_counter._.parked, trace_counter._.max_working); + } +#endif do { gint64 ts; @@ -721,20 +751,33 @@ monitor_thread (gpointer unused) if (!monitor_sufficient_delay_since_last_dequeue ()) continue; - limit_worker_max_reached = FALSE; + gboolean active_max_reached; COUNTER_ATOMIC (counter, { + limit_worker_max_reached = FALSE; + active_max_reached = FALSE; if (counter._.max_working >= worker.limit_worker_max) { limit_worker_max_reached = TRUE; + if (counter_num_active (counter) >= counter._.max_working) + active_max_reached = TRUE; break; } counter._.max_working ++; }); - if (limit_worker_max_reached) - continue; - - hill_climbing_force_change (counter._.max_working, TRANSITION_STARVATION); + if (limit_worker_max_reached) { + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_THREADPOOL, "[%p] monitor thread, limit_worker_max (%d) reached", + GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ())), + worker.limit_worker_max); + if (active_max_reached) + continue; + else + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_THREADPOOL, "[%p] monitor thread, num_active (%d) < max_working, allowing active thread increase", + GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ())), + counter_num_active (counter)); + } + else + hill_climbing_force_change (counter._.max_working, TRANSITION_STARVATION); for (i = 0; i < 5; ++i) { if (mono_runtime_is_shutting_down ()) @@ -1093,6 +1136,7 @@ heuristic_adjust (void) counter._.max_working = new_thread_count; }); + /* FIXME: this can never be true. we only leave COUNTER_ATOMIC() if the assignment and CAS succeeded */ if (new_thread_count > counter._.max_working) worker_request (); |