[sgen] Disable concurrent queue redirection
authorVlad Brezae <brezaevlad@gmail.com>
Wed, 28 Sep 2016 21:40:06 +0000 (00:40 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 19 Jan 2017 22:45:11 +0000 (00:45 +0200)
We used to support the case where workers are running and when the main gc thread populates the redirected gray queue, these queue sections are moved to the workers distribute gray queue from where they are distributed to all the workers. In order to simplify the process, the main gc thread should never do any relevant gc work concurrently with the workers. This means that we no longer need to handle the above case.

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 ea5b232afe6f42409e632b56677ceb781dcbcdd9..a45a9a106b03f0ce8035bd87202ac7faacf7c972 100644 (file)
@@ -424,12 +424,11 @@ sgen_workers_get_job_gray_queue (WorkerData *worker_data, SgenGrayQueue *default
 }
 
 static void
-gray_queue_enable_redirect (SgenGrayQueue *queue)
+gray_queue_redirect (SgenGrayQueue *queue)
 {
        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, sgen_workers_take_from_queue_and_awake);
-       sgen_workers_take_from_queue_and_awake (queue);
+       sgen_workers_take_from_queue (queue);
 }
 
 void
@@ -1905,12 +1904,12 @@ major_copy_or_mark_from_roots (SgenGrayQueue *gc_thread_gray_queue, size_t *old_
         * the roots.
         */
        if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
+               gray_queue_redirect (gc_thread_gray_queue);
                if (precleaning_enabled) {
                        sgen_workers_start_all_workers (object_ops, workers_finish_callback);
                } else {
                        sgen_workers_start_all_workers (object_ops, NULL);
                }
-               gray_queue_enable_redirect (gc_thread_gray_queue);
        }
 
        if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
index f8f04c145807db19fb27a7676f73d36f77555a05..02d368c6a99171eb007f5968eb1dea2684deb674 100644 (file)
@@ -49,9 +49,6 @@ sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue)
 {
        GrayQueueSection *section;
 
-       if (queue->alloc_prepare_func)
-               queue->alloc_prepare_func (queue);
-
        if (queue->free_list) {
                /* Use the previously allocated queue sections if possible */
                section = queue->free_list;
@@ -247,13 +244,6 @@ sgen_gray_object_queue_dispose (SgenGrayQueue *queue)
        memset (queue, 0, sizeof (SgenGrayQueue));
 }
 
-void
-sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func)
-{
-       SGEN_ASSERT (0, !queue->alloc_prepare_func, "Can't set gray queue alloc-prepare twice");
-       queue->alloc_prepare_func = alloc_prepare_func;
-}
-
 void
 sgen_gray_object_queue_deinit (SgenGrayQueue *queue)
 {
index 2a872d7d2bf1816193f06f8dfebec7a035cfb4d1..10ed5af939555c14c1e6a106b07a3632154b4e3a 100644 (file)
@@ -93,7 +93,6 @@ struct _SgenGrayQueue {
        GrayQueueEntry *cursor;
        GrayQueueSection *first;
        GrayQueueSection *free_list;
-       GrayQueueAllocPrepareFunc alloc_prepare_func;
 #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
        GrayQueueEnqueueCheckFunc enqueue_check_func;
 #endif
@@ -131,7 +130,6 @@ 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, gboolean reuse_free_list);
 void sgen_gray_object_queue_dispose (SgenGrayQueue *queue);
-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_alloc_queue_section (SgenGrayQueue *queue);
 void sgen_gray_object_free_queue_section (GrayQueueSection *section);
index f6c8859bd688381d43b21ea995076d9c0913dbe2..972bb5161115433ec0d45c1b6875699d40484aa1 100644 (file)
@@ -421,22 +421,16 @@ sgen_workers_assert_gray_queue_is_empty (void)
 }
 
 void
-sgen_workers_take_from_queue_and_awake (SgenGrayQueue *queue)
+sgen_workers_take_from_queue (SgenGrayQueue *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 ();
-       }
+       SGEN_ASSERT (0, !sgen_workers_are_working (), "We should fully populate the distribute gray queue before we start the workers");
 }
 
 SgenObjectOperations*
index 7c6c2fc34d1e98a45b71b106efd41dd0c450cab9..d99dbeb85cf90e43a45be9c72457f832234ee4a1 100644 (file)
@@ -41,7 +41,7 @@ gboolean sgen_workers_have_idle_work (void);
 gboolean sgen_workers_all_done (void);
 gboolean sgen_workers_are_working (void);
 void sgen_workers_assert_gray_queue_is_empty (void);
-void sgen_workers_take_from_queue_and_awake (SgenGrayQueue *queue);
+void sgen_workers_take_from_queue (SgenGrayQueue *queue);
 SgenObjectOperations* sgen_workers_get_idle_func_object_ops (void);
 int sgen_workers_get_job_split_count (void);
 void sgen_workers_foreach (SgenWorkerCallback callback);