static WorkerData *workers_data;
static SgenWorkerCallback worker_init_cb;
+static SgenThreadPool pool_inst;
+static SgenThreadPool *pool; /* null if we're not using workers */
+
/*
* When using multiple workers, we need to have the last worker
* enqueue the preclean jobs (if there are any). This lock ensures
else if (new_state == STATE_WORKING)
SGEN_ASSERT (0, old_state == STATE_WORK_ENQUEUED, "We can only transition to WORKING from WORK ENQUEUED");
if (new_state == STATE_NOT_WORKING || new_state == STATE_WORKING)
- SGEN_ASSERT (6, sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()), "Only the worker thread is allowed to transition to NOT_WORKING or WORKING");
+ SGEN_ASSERT (6, sgen_thread_pool_is_thread_pool_thread (pool, mono_native_thread_id_get ()), "Only the worker thread is allowed to transition to NOT_WORKING or WORKING");
return InterlockedCompareExchange (&data->state, new_state, old_state) == old_state;
}
}
if (need_signal)
- sgen_thread_pool_idle_signal ();
+ sgen_thread_pool_idle_signal (pool);
}
static void
return;
}
- sgen_thread_pool_job_enqueue (job);
+ sgen_thread_pool_job_enqueue (pool, job);
}
static gboolean
sgen_workers_init (int num_workers, SgenWorkerCallback callback)
{
int i;
- void **workers_data_ptrs = (void **)alloca(num_workers * sizeof(void *));
-
- if (!sgen_get_major_collector ()->is_concurrent && !sgen_get_minor_collector ()->is_parallel) {
- sgen_thread_pool_init (num_workers, thread_pool_init_func, NULL, NULL, NULL, NULL);
- return;
- }
+ WorkerData **workers_data_ptrs = (WorkerData**)alloca(num_workers * sizeof(WorkerData*));
mono_os_mutex_init (&finished_lock);
//g_print ("initing %d workers\n", num_workers);
init_distribute_gray_queue ();
for (i = 0; i < num_workers; ++i)
- workers_data_ptrs [i] = (void *) &workers_data [i];
+ workers_data_ptrs [i] = &workers_data [i];
worker_init_cb = callback;
- sgen_thread_pool_init (num_workers, thread_pool_init_func, marker_idle_func, continue_idle_func, should_work_func, workers_data_ptrs);
+ pool = &pool_inst;
+ sgen_thread_pool_init (pool, num_workers, thread_pool_init_func, marker_idle_func, continue_idle_func, should_work_func, (SgenThreadPoolData**)workers_data_ptrs);
mono_counters_register ("# workers finished", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_workers_num_finished);
}
+void
+sgen_workers_shutdown (void)
+{
+ if (pool)
+ sgen_thread_pool_shutdown (pool);
+}
+
void
sgen_workers_stop_all_workers (void)
{
mono_memory_write_barrier ();
forced_stop = TRUE;
- sgen_thread_pool_wait_for_all_jobs ();
- sgen_thread_pool_idle_wait ();
+ sgen_thread_pool_wait_for_all_jobs (pool);
+ sgen_thread_pool_idle_wait (pool);
SGEN_ASSERT (0, sgen_workers_all_done (), "Can only signal enqueue work when in no work state");
}
{
int i;
- sgen_thread_pool_wait_for_all_jobs ();
- sgen_thread_pool_idle_wait ();
+ sgen_thread_pool_wait_for_all_jobs (pool);
+ sgen_thread_pool_idle_wait (pool);
SGEN_ASSERT (0, sgen_workers_all_done (), "Can only signal enqueue work when in no work state");
/* At this point all the workers have stopped. */
callback (&workers_data [i]);
}
+gboolean
+sgen_workers_is_worker_thread (MonoNativeThreadId id)
+{
+ if (!pool)
+ return FALSE;
+ return sgen_thread_pool_is_thread_pool_thread (pool, id);
+}
+
#endif