[sgen] Split up concurrent sweep from worker logic
[mono.git] / mono / sgen / sgen-marksweep.c
index 365f64787812f03981c64145cd51e38b01664d7a..04ab32dab84a0dbc96e64bf00e7293ed6eee2e8d 100644 (file)
@@ -187,6 +187,9 @@ static volatile int sweep_state = SWEEP_STATE_SWEPT;
 static gboolean concurrent_mark;
 static gboolean concurrent_sweep = TRUE;
 
+SgenThreadPool sweep_pool_inst;
+SgenThreadPool *sweep_pool;
+
 #define BLOCK_IS_TAGGED_HAS_REFERENCES(bl)     SGEN_POINTER_IS_TAGGED_1 ((bl))
 #define BLOCK_TAG_HAS_REFERENCES(bl)           SGEN_POINTER_TAG_1 ((bl))
 
@@ -918,7 +921,7 @@ major_finish_sweep_checking (void)
  wait:
        job = sweep_job;
        if (job)
-               sgen_thread_pool_job_wait (job);
+               sgen_thread_pool_job_wait (sweep_pool, job);
        SGEN_ASSERT (0, !sweep_job, "Why did the sweep job not null itself?");
        SGEN_ASSERT (0, sweep_state == SWEEP_STATE_SWEPT, "How is the sweep job done but we're not swept?");
 }
@@ -1806,7 +1809,7 @@ sweep_job_func (void *thread_data_untyped, SgenThreadPoolJob *job)
         */
        if (concurrent_sweep && lazy_sweep) {
                sweep_blocks_job = sgen_thread_pool_job_alloc ("sweep_blocks", sweep_blocks_job_func, sizeof (SgenThreadPoolJob));
-               sgen_thread_pool_job_enqueue (sweep_blocks_job);
+               sgen_thread_pool_job_enqueue (sweep_pool, sweep_blocks_job);
        }
 
        sweep_finish ();
@@ -1855,7 +1858,7 @@ major_sweep (void)
        SGEN_ASSERT (0, !sweep_job, "We haven't finished the last sweep?");
        if (concurrent_sweep) {
                sweep_job = sgen_thread_pool_job_alloc ("sweep", sweep_job_func, sizeof (SgenThreadPoolJob));
-               sgen_thread_pool_job_enqueue (sweep_job);
+               sgen_thread_pool_job_enqueue (sweep_pool, sweep_job);
        } else {
                sweep_job_func (NULL, NULL);
        }
@@ -2068,7 +2071,7 @@ major_start_major_collection (void)
                 */
                SgenThreadPoolJob *job = sweep_blocks_job;
                if (job)
-                       sgen_thread_pool_job_wait (job);
+                       sgen_thread_pool_job_wait (sweep_pool, job);
        }
 
        if (lazy_sweep && !concurrent_sweep)
@@ -2108,6 +2111,12 @@ major_finish_major_collection (ScannedObjectCounts *counts)
 #endif
 }
 
+static SgenThreadPool*
+major_get_sweep_pool (void)
+{
+       return sweep_pool;
+}
+
 static int
 compare_pointers (const void *va, const void *vb) {
        char *a = *(char**)va, *b = *(char**)vb;
@@ -2714,7 +2723,6 @@ static void
 post_param_init (SgenMajorCollector *collector)
 {
        collector->sweeps_lazily = lazy_sweep;
-       collector->needs_thread_pool = concurrent_mark || concurrent_sweep;
 }
 
 /* We are guaranteed to be called by the worker in question */
@@ -2733,6 +2741,12 @@ sgen_worker_init_callback (gpointer worker_untyped)
        mono_native_tls_set_value (worker_block_free_list_key, worker_free_blocks);
 }
 
+static void
+thread_pool_init_func (void *data_untyped)
+{
+       sgen_client_thread_register_worker ();
+}
+
 static void
 sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurrent, gboolean is_parallel)
 {
@@ -2788,7 +2802,6 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
        concurrent_mark = is_concurrent;
        collector->is_concurrent = is_concurrent;
        collector->is_parallel = is_parallel;
-       collector->needs_thread_pool = is_concurrent || concurrent_sweep;
        collector->get_and_reset_num_major_objects_marked = major_get_and_reset_num_major_objects_marked;
        collector->supports_cardtable = TRUE;
 
@@ -2834,6 +2847,7 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
        collector->is_valid_object = major_is_valid_object;
        collector->describe_pointer = major_describe_pointer;
        collector->count_cards = major_count_cards;
+       collector->get_sweep_pool = major_get_sweep_pool;
 
        collector->major_ops_serial.copy_or_mark_object = major_copy_or_mark_object_canonical;
        collector->major_ops_serial.scan_object = major_scan_object_with_evacuation;
@@ -2893,6 +2907,12 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr
 
        /*cardtable requires major pages to be 8 cards aligned*/
        g_assert ((MS_BLOCK_SIZE % (8 * CARD_SIZE_IN_BYTES)) == 0);
+
+       if (concurrent_sweep) {
+               SgenThreadPool **thread_datas = &sweep_pool;
+               sweep_pool = &sweep_pool_inst;
+               sgen_thread_pool_init (sweep_pool, 1, thread_pool_init_func, NULL, NULL, NULL, (SgenThreadPoolData**)&thread_datas);
+       }
 }
 
 void