static void print_pool_info (ThreadPool *tp) { // if (tp->tail - tp->head == 0) // return; g_print ("Pool status? %d\n", InterlockedCompareExchange (&tp->pool_status, 0, 0)); g_print ("Min. threads: %d\n", InterlockedCompareExchange (&tp->min_threads, 0, 0)); g_print ("Max. threads: %d\n", InterlockedCompareExchange (&tp->max_threads, 0, 0)); g_print ("nthreads: %d\n", InterlockedCompareExchange (&tp->nthreads, 0, 0)); g_print ("busy threads: %d\n", InterlockedCompareExchange (&tp->busy_threads, 0, 0)); g_print ("Waiting: %d\n", InterlockedCompareExchange (&tp->waiting, 0, 0)); g_print ("Queued: %d\n", (tp->tail - tp->head)); if (tp == &async_tp) { int i; EnterCriticalSection (&wsqs_lock); for (i = 0; i < wsqs->len; i++) { g_print ("\tWSQ %d: %d\n", i, mono_wsq_count (g_ptr_array_index (wsqs, i))); } LeaveCriticalSection (&wsqs_lock); } else { g_print ("\tSockets: %d\n", mono_g_hash_table_size (socket_io_data.sock_to_state)); } g_print ("-------------\n"); }
static void try_steal (MonoWSQ *local_wsq, gpointer *data, gboolean retry) { int i; int ms; if (wsqs == NULL || data == NULL || *data != NULL) return; ms = 0; do { if (mono_runtime_is_shutting_down ()) return; EnterCriticalSection (&wsqs_lock); for (i = 0; wsqs != NULL && i < wsqs->len; i++) { MonoWSQ *wsq; wsq = wsqs->pdata [i]; if (wsq == local_wsq || mono_wsq_count (wsq) == 0) continue; mono_wsq_try_steal (wsqs->pdata [i], data, ms); if (*data != NULL) { LeaveCriticalSection (&wsqs_lock); return; } } LeaveCriticalSection (&wsqs_lock); ms += 10; } while (retry && ms < 11); }
static void monitor_thread (gpointer unused) { ThreadPool *pools [2]; MonoInternalThread *thread; guint32 ms; gboolean need_one; int i; pools [0] = &async_tp; pools [1] = &async_io_tp; thread = mono_thread_internal_current (); ves_icall_System_Threading_Thread_SetName_internal (thread, mono_string_new (mono_domain_get (), "Threadpool monitor")); while (1) { ms = 500; i = 10; //number of spurious awakes we tolerate before doing a round of rebalancing. do { guint32 ts; ts = mono_msec_ticks (); if (SleepEx (ms, TRUE) == 0) break; ms -= (mono_msec_ticks () - ts); if (mono_runtime_is_shutting_down ()) break; if (THREAD_WANTS_A_BREAK (thread)) mono_thread_interruption_checkpoint (); } while (ms > 0 && i--); if (mono_runtime_is_shutting_down ()) break; if (suspended) continue; for (i = 0; i < 2; i++) { ThreadPool *tp; tp = pools [i]; if (tp->waiting > 0) continue; need_one = (mono_cq_count (tp->queue) > 0); if (!need_one && !tp->is_io) { EnterCriticalSection (&wsqs_lock); for (i = 0; wsqs != NULL && i < wsqs->len; i++) { MonoWSQ *wsq; wsq = g_ptr_array_index (wsqs, i); if (mono_wsq_count (wsq) != 0) { need_one = TRUE; break; } } LeaveCriticalSection (&wsqs_lock); } if (need_one) threadpool_start_thread (tp); } } }