[sgen] Don't expose the worker's gray queue.
authorMark Probst <mark.probst@gmail.com>
Tue, 29 Mar 2016 20:02:11 +0000 (13:02 -0700)
committerMark Probst <mark.probst@gmail.com>
Mon, 25 Jul 2016 17:52:59 +0000 (10:52 -0700)
mono/sgen/sgen-gc.c
mono/sgen/sgen-gray.c
mono/sgen/sgen-gray.h
mono/sgen/sgen-workers.c
mono/sgen/sgen-workers.h

index fc0c8bdab5ec8ba60c841c6d8bf08862fb1e1b53..2d6e174fbe78784b41b19ab676f9501af27c1513 100644 (file)
@@ -428,33 +428,13 @@ sgen_workers_get_job_gray_queue (WorkerData *worker_data)
        return worker_data ? &worker_data->private_gray_queue : WORKERS_DISTRIBUTE_GRAY_QUEUE;
 }
 
-static void
-gray_queue_redirect (SgenGrayQueue *queue)
-{
-       gboolean wake = FALSE;
-
-       for (;;) {
-               GrayQueueSection *section = sgen_gray_object_dequeue_section (queue);
-               if (!section)
-                       break;
-               sgen_section_gray_queue_enqueue ((SgenSectionGrayQueue *)queue->alloc_prepare_data, section);
-               wake = TRUE;
-       }
-
-       if (wake) {
-               g_assert (concurrent_collection_in_progress);
-               sgen_workers_ensure_awake ();
-       }
-}
-
 static void
 gray_queue_enable_redirect (SgenGrayQueue *queue)
 {
-       if (!concurrent_collection_in_progress)
-               return;
+       SGEN_ASSERT (0, concurrent_collection_in_progress, "Where are we redirecting the gray queue to, without a concurrent collection?");
 
-       sgen_gray_queue_set_alloc_prepare (queue, gray_queue_redirect, sgen_workers_get_distribute_section_gray_queue ());
-       gray_queue_redirect (queue);
+       sgen_gray_queue_set_alloc_prepare (queue, sgen_workers_take_from_queue_and_awake);
+       sgen_workers_take_from_queue_and_awake (queue);
 }
 
 void
@@ -1904,7 +1884,7 @@ major_start_collection (const char *reason, gboolean concurrent, size_t *old_nex
 
        current_collection_generation = GENERATION_OLD;
 
-       g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
+       sgen_workers_assert_gray_queue_is_empty ();
 
        if (!concurrent)
                sgen_cement_reset ();
@@ -1963,7 +1943,7 @@ major_finish_collection (const char *reason, gboolean is_overflow, size_t old_ne
                object_ops = &major_collector.major_ops_serial;
        }
 
-       g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
+       sgen_workers_assert_gray_queue_is_empty ();
 
        /* all the objects in the heap */
        finish_gray_stack (GENERATION_OLD, CONTEXT_FROM_OBJECT_OPERATIONS (object_ops, &gray_queue));
@@ -2058,7 +2038,7 @@ major_finish_collection (const char *reason, gboolean is_overflow, size_t old_ne
        memset (&counts, 0, sizeof (ScannedObjectCounts));
        major_collector.finish_major_collection (&counts);
 
-       g_assert (sgen_section_gray_queue_is_empty (sgen_workers_get_distribute_section_gray_queue ()));
+       sgen_workers_assert_gray_queue_is_empty ();
 
        SGEN_ASSERT (0, sgen_workers_all_done (), "Can't have workers working after major collection has finished");
        if (concurrent_collection_in_progress)
@@ -2124,8 +2104,7 @@ major_start_concurrent_collection (const char *reason)
 
        // FIXME: store reason and pass it when finishing
        major_start_collection (reason, TRUE, NULL);
-
-       gray_queue_redirect (&gray_queue);
+       SGEN_ASSERT (0, sgen_gray_object_queue_is_empty (&gray_queue), "What's left in the gray queue?");
 
        num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
 
index 809215136f9799d817b0b157d6c1ac972f085f93..2aa43a3b0169d02521a1e99efbe74d2cd2a6e3d2 100644 (file)
@@ -217,7 +217,6 @@ sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enq
        g_assert (sgen_gray_object_queue_is_empty (queue));
 
        queue->alloc_prepare_func = NULL;
-       queue->alloc_prepare_data = NULL;
 #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
        queue->enqueue_check_func = enqueue_check_func;
 #endif
@@ -237,23 +236,13 @@ sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue)
 {
        sgen_gray_object_queue_init (queue, NULL);
        queue->alloc_prepare_func = invalid_prepare_func;
-       queue->alloc_prepare_data = NULL;
 }
 
 void
-sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func, void *data)
+sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func)
 {
-       SGEN_ASSERT (0, !queue->alloc_prepare_func && !queue->alloc_prepare_data, "Can't set gray queue alloc-prepare twice");
+       SGEN_ASSERT (0, !queue->alloc_prepare_func, "Can't set gray queue alloc-prepare twice");
        queue->alloc_prepare_func = alloc_prepare_func;
-       queue->alloc_prepare_data = data;
-}
-
-void
-sgen_gray_object_queue_init_with_alloc_prepare (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func,
-               GrayQueueAllocPrepareFunc alloc_prepare_func, void *data)
-{
-       sgen_gray_object_queue_init (queue, enqueue_check_func);
-       sgen_gray_queue_set_alloc_prepare (queue, alloc_prepare_func, data);
 }
 
 void
@@ -268,13 +257,6 @@ sgen_gray_object_queue_deinit (SgenGrayQueue *queue)
        }
 }
 
-void
-sgen_gray_object_queue_disable_alloc_prepare (SgenGrayQueue *queue)
-{
-       queue->alloc_prepare_func = NULL;
-       queue->alloc_prepare_data = NULL;
-}
-
 static void
 lock_section_queue (SgenSectionGrayQueue *queue)
 {
index 019f44c927c8e5fbee00e0d291c0234cb54b73cb..c3b9918763cce796d154b897b3ebb2e56bb86e79 100644 (file)
@@ -97,7 +97,6 @@ struct _SgenGrayQueue {
 #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
        GrayQueueEnqueueCheckFunc enqueue_check_func;
 #endif
-       void *alloc_prepare_data;
 };
 
 typedef struct _SgenSectionGrayQueue SgenSectionGrayQueue;
@@ -132,11 +131,8 @@ void sgen_gray_object_enqueue_section (SgenGrayQueue *queue, GrayQueueSection *s
 void sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue);
 void sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func);
 void sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue);
-void sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func, void *data);
-void sgen_gray_object_queue_init_with_alloc_prepare (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func,
-               GrayQueueAllocPrepareFunc func, void *data);
+void sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func);
 void sgen_gray_object_queue_deinit (SgenGrayQueue *queue);
-void sgen_gray_object_queue_disable_alloc_prepare (SgenGrayQueue *queue);
 void sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue);
 void sgen_gray_object_free_queue_section (GrayQueueSection *section);
 
index adc600a090f3dc801f8d1b16b4796acb28a69988..0d613a70d14227056439dabe6803cf92e92a74b3 100644 (file)
@@ -77,7 +77,7 @@ state_is_working_or_enqueued (State state)
        return state == STATE_WORKING || state == STATE_WORK_ENQUEUED;
 }
 
-void
+static void
 sgen_workers_ensure_awake (void)
 {
        State old_state;
@@ -354,10 +354,29 @@ sgen_workers_are_working (void)
        return state_is_working_or_enqueued (workers_state);
 }
 
-SgenSectionGrayQueue*
-sgen_workers_get_distribute_section_gray_queue (void)
+void
+sgen_workers_assert_gray_queue_is_empty (void)
+{
+       SGEN_ASSERT (0, sgen_section_gray_queue_is_empty (&workers_distribute_gray_queue), "Why is the workers gray queue not empty?");
+}
+
+void
+sgen_workers_take_from_queue_and_awake (SgenGrayQueue *queue)
 {
-       return &workers_distribute_gray_queue;
+       gboolean wake = FALSE;
+
+       for (;;) {
+               GrayQueueSection *section = sgen_gray_object_dequeue_section (queue);
+               if (!section)
+                       break;
+               sgen_section_gray_queue_enqueue (&workers_distribute_gray_queue, section);
+               wake = TRUE;
+       }
+
+       if (wake) {
+               SGEN_ASSERT (0, sgen_concurrent_collection_in_progress (), "Why is there work to take when there's no concurrent collection in progress?");
+               sgen_workers_ensure_awake ();
+       }
 }
 
 #endif
index 780d2eb6df921ed6a096879c4876eef75f8adbaf..1a66c79a48c238fd5ae4e3b589bc4e6e8f5ca4bf 100644 (file)
@@ -20,7 +20,6 @@ struct _WorkerData {
 void sgen_workers_init (int num_workers);
 void sgen_workers_stop_all_workers (void);
 void sgen_workers_start_all_workers (SgenObjectOperations *object_ops, SgenThreadPoolJob *finish_job);
-void sgen_workers_ensure_awake (void);
 void sgen_workers_init_distribute_gray_queue (void);
 void sgen_workers_enqueue_job (SgenThreadPoolJob *job, gboolean enqueue);
 void sgen_workers_wait_for_jobs_finished (void);
@@ -30,6 +29,7 @@ void sgen_workers_join (void);
 gboolean sgen_workers_have_idle_work (void);
 gboolean sgen_workers_all_done (void);
 gboolean sgen_workers_are_working (void);
-SgenSectionGrayQueue* sgen_workers_get_distribute_section_gray_queue (void);
+void sgen_workers_assert_gray_queue_is_empty (void);
+void sgen_workers_take_from_queue_and_awake (SgenGrayQueue *queue);
 
 #endif