[sgen] Split up concurrent sweep from worker logic
[mono.git] / mono / sgen / sgen-workers.c
index d5343db50d1c37cb2f3241ebab4b9e0eb760823d..47fb00d9e1f8db39461cc62ff7a29c126ffedf61 100644 (file)
@@ -26,6 +26,9 @@ static volatile gboolean forced_stop;
 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
@@ -84,7 +87,7 @@ set_state (WorkerData *data, State old_state, State new_state)
        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;
 }
@@ -128,7 +131,7 @@ sgen_workers_ensure_awake (void)
        }
 
        if (need_signal)
-               sgen_thread_pool_idle_signal ();
+               sgen_thread_pool_idle_signal (pool);
 }
 
 static void
@@ -200,7 +203,7 @@ sgen_workers_enqueue_job (SgenThreadPoolJob *job, gboolean enqueue)
                return;
        }
 
-       sgen_thread_pool_job_enqueue (job);
+       sgen_thread_pool_job_enqueue (pool, job);
 }
 
 static gboolean
@@ -371,12 +374,7 @@ void
 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);
@@ -390,15 +388,23 @@ sgen_workers_init (int num_workers, SgenWorkerCallback callback)
        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)
 {
@@ -406,8 +412,8 @@ 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");
 }
 
@@ -446,8 +452,8 @@ sgen_workers_join (void)
 {
        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. */
@@ -546,4 +552,12 @@ sgen_workers_foreach (SgenWorkerCallback callback)
                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