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
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 ();
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));
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)
// 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 ();
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
{
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
}
}
-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)
{
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
GrayQueueEnqueueCheckFunc enqueue_check_func;
#endif
- void *alloc_prepare_data;
};
typedef struct _SgenSectionGrayQueue SgenSectionGrayQueue;
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);
return state == STATE_WORKING || state == STATE_WORK_ENQUEUED;
}
-void
+static void
sgen_workers_ensure_awake (void)
{
State old_state;
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
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);
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