Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeale Ferguson <neale@sinenomine.net>2022-05-27 12:25:11 +0300
committerGitHub <noreply@github.com>2022-05-27 12:25:11 +0300
commit9f5ebbdc31fe1c836aef9357be935bb5450e77b5 (patch)
tree592d7c55a17a999dbb39b78962e2c04a7b42a16f
parenta76b50e5faa69d4cfe6c5ddfc58bbbba9d28b29c (diff)
Backport 4caf2b3dccee96d3d3bf1b95972761e32e62117c to 5.16 (#21496)2018-06
-rw-r--r--.gitmodules38
-rw-r--r--mono/metadata/threadpool-worker-default.c70
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 ();