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.
}
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
* 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) {
{
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;
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)
{
GrayQueueEntry *cursor;
GrayQueueSection *first;
GrayQueueSection *free_list;
- GrayQueueAllocPrepareFunc alloc_prepare_func;
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
GrayQueueEnqueueCheckFunc enqueue_check_func;
#endif
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);
}
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*
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);