typedef union {
struct {
gint16 max_working; /* determined by heuristic */
- gint16 active; /* working or waiting on thread_work_sem; warm threads */
- gint16 working;
- gint16 parked;
+ gint16 active; /* executing worker_thread */
+ gint16 working; /* actively executing worker_thread, not parked */
+ gint16 parked; /* parked */
} _;
gint64 as_gint64;
} ThreadPoolCounter;
#define COUNTER_CHECK(counter) \
do { \
g_assert (counter._.max_working > 0); \
+ g_assert (counter._.working >= 0); \
g_assert (counter._.active >= 0); \
} while (0)
for (;;) {
guint i;
ThreadPoolCounter counter = COUNTER_READ ();
- if (counter._.active == 0 && counter._.parked == 0)
+ if (counter._.active == 0)
break;
if (counter._.active == 1) {
MonoInternalThread *thread = mono_thread_internal_current ();
g_assert (tpdomain->domain);
if (mono_runtime_is_shutting_down () || mono_domain_is_unloading (tpdomain->domain)) {
- COUNTER_ATOMIC (counter, { counter._.active --; });
+ COUNTER_ATOMIC (counter, {
+ counter._.working --;
+ counter._.active --;
+ });
return;
}
thread = mono_thread_internal_current ();
g_assert (thread);
+ mono_mutex_lock (&threadpool->working_threads_lock);
+ g_ptr_array_add (threadpool->working_threads, thread);
+ mono_mutex_unlock (&threadpool->working_threads_lock);
+
mono_mutex_lock (&threadpool->domains_lock);
do {
mono_mutex_unlock (&threadpool->domains_lock);
- mono_mutex_lock (&threadpool->working_threads_lock);
- g_ptr_array_add (threadpool->working_threads, thread);
- mono_mutex_unlock (&threadpool->working_threads_lock);
-
- COUNTER_ATOMIC (counter, { counter._.working ++; });
-
mono_thread_push_appdomain_ref (tpdomain->domain);
if (mono_domain_set (tpdomain->domain, FALSE)) {
MonoObject *exc = NULL;
}
mono_thread_pop_appdomain_ref ();
- COUNTER_ATOMIC (counter, { counter._.working --; });
-
- mono_mutex_lock (&threadpool->working_threads_lock);
- g_ptr_array_remove_fast (threadpool->working_threads, thread);
- mono_mutex_unlock (&threadpool->working_threads_lock);
-
mono_mutex_lock (&threadpool->domains_lock);
tpdomain->domain->threadpool_jobs --;
gboolean park = TRUE;
COUNTER_ATOMIC (counter, {
- if (counter._.active <= counter._.max_working) {
+ if (counter._.working <= counter._.max_working) {
park = FALSE;
break;
}
- counter._.active --;
+ counter._.working --;
counter._.parked ++;
});
mono_mutex_lock (&threadpool->domains_lock);
COUNTER_ATOMIC (counter, {
- counter._.active ++;
+ counter._.working ++;
counter._.parked --;
});
}
mono_mutex_unlock (&threadpool->domains_lock);
- COUNTER_ATOMIC (counter, { counter._.active --; });
+ mono_mutex_lock (&threadpool->working_threads_lock);
+ g_ptr_array_remove_fast (threadpool->working_threads, thread);
+ mono_mutex_unlock (&threadpool->working_threads_lock);
+
+ COUNTER_ATOMIC (counter, {
+ counter._.working--;
+ counter._.active --;
+ });
}
static gboolean
return TRUE;
COUNTER_ATOMIC (counter, {
- if (counter._.active >= counter._.max_working)
+ if (counter._.working >= counter._.max_working)
return FALSE;
+ counter._.working ++;
counter._.active ++;
});
if (worker_try_create (tpdomain))
return TRUE;
- COUNTER_ATOMIC (counter, { counter._.active --; });
+ COUNTER_ATOMIC (counter, {
+ counter._.working --;
+ counter._.active --;
+ });
return FALSE;
}
break;
COUNTER_TRY_ATOMIC (success, counter, {
- if (counter._.active >= counter._.max_working)
+ if (counter._.working >= counter._.max_working)
break;
+ counter._.working ++;
counter._.active ++;
});
if (tpdomain && worker_try_create (tpdomain))
break;
- COUNTER_ATOMIC (counter, { counter._.active --; });
+ COUNTER_ATOMIC (counter, {
+ counter._.working --;
+ counter._.active --;
+ });
}
}
} while (monitor_should_keep_running ());
if (threadpool->heuristic_last_dequeue > threadpool->heuristic_last_adjustment + threadpool->heuristic_adjustment_interval) {
ThreadPoolCounter counter = COUNTER_READ ();
- if (counter._.active <= counter._.max_working)
+ if (counter._.working <= counter._.max_working)
return TRUE;
}
heuristic_adjust ();
counter = COUNTER_READ ();
- return counter._.active <= counter._.max_working;
+ return counter._.working <= counter._.max_working;
}
void