Merge pull request #2734 from nealef/master
[mono.git] / mono / utils / mono-threads.c
index a92d250b290448698ece831e6809b4c99a8f3cdd..03c0aca8ddf3f749a801d1319ba4fa76585691b5 100644 (file)
@@ -80,6 +80,9 @@ static gboolean unified_suspend_enabled;
 /*abort at 1 sec*/
 #define SLEEP_DURATION_BEFORE_ABORT 200
 
+static long sleepWarnDuration = SLEEP_DURATION_BEFORE_WARNING,
+           sleepAbortDuration = SLEEP_DURATION_BEFORE_ABORT;
+
 static int suspend_posts, resume_posts, abort_posts, waits_done, pending_ops;
 
 void
@@ -235,14 +238,14 @@ mono_threads_wait_pending_operations (void)
                for (i = 0; i < pending_suspends; ++i) {
                        THREADS_SUSPEND_DEBUG ("[INITIATOR-WAIT-WAITING]\n");
                        InterlockedIncrement (&waits_done);
-                       if (!mono_os_sem_timedwait (&suspend_semaphore, SLEEP_DURATION_BEFORE_ABORT, MONO_SEM_FLAGS_NONE))
+                       if (!mono_os_sem_timedwait (&suspend_semaphore, sleepAbortDuration, MONO_SEM_FLAGS_NONE))
                                continue;
                        mono_stopwatch_stop (&suspension_time);
 
                        dump_threads ();
 
                        MOSTLY_ASYNC_SAFE_PRINTF ("WAITING for %d threads, got %d suspended\n", (int)pending_suspends, i);
-                       g_error ("suspend_thread suspend took %d ms, which is more than the allowed %d ms", (int)mono_stopwatch_elapsed_ms (&suspension_time), SLEEP_DURATION_BEFORE_ABORT);
+                       g_error ("suspend_thread suspend took %d ms, which is more than the allowed %d ms", (int)mono_stopwatch_elapsed_ms (&suspension_time), sleepAbortDuration);
                }
                mono_stopwatch_stop (&suspension_time);
                THREADS_SUSPEND_DEBUG ("Suspending %d threads took %d ms.\n", (int)pending_suspends, (int)mono_stopwatch_elapsed_ms (&suspension_time));
@@ -639,6 +642,7 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
        gboolean res;
        threads_callbacks = *callbacks;
        thread_info_size = info_size;
+       char *sleepLimit;
 #ifdef HOST_WIN32
        res = mono_native_tls_alloc (&thread_info_key, NULL);
        res = mono_native_tls_alloc (&thread_exited_key, NULL);
@@ -655,6 +659,15 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
        g_assert (res);
 
        unified_suspend_enabled = g_getenv ("MONO_ENABLE_UNIFIED_SUSPEND") != NULL || mono_threads_is_coop_enabled ();
+       
+       if ((sleepLimit = g_getenv ("MONO_SLEEP_ABORT_LIMIT")) != NULL) {
+               long threshold = strtol(sleepLimit, NULL, 10);
+               if ((errno == 0) && (threshold >= 40))  {
+                       sleepAbortDuration = threshold;
+                       sleepWarnDuration = threshold / 20;
+               } else
+                       g_warning("MONO_SLEEP_ABORT_LIMIT must be a number >= 40");
+       }
 
        mono_os_sem_init (&global_suspend_semaphore, 1);
        mono_os_sem_init (&suspend_semaphore, 0);