static mono_native_thread_return_t workers_thread_func (void *data_untyped) { WorkerData *data = data_untyped; SgenMajorCollector *major = sgen_get_major_collector (); mono_thread_info_register_small_id (); if (major->init_worker_thread) major->init_worker_thread (data->major_collector_data); init_private_gray_queue (data); for (;;) { gboolean did_work = FALSE; SGEN_ASSERT (0, sgen_get_current_collection_generation () != GENERATION_NURSERY, "Why are we doing work while there's a nursery collection happening?"); while (workers_state.data.state == STATE_WORKING && workers_dequeue_and_do_job (data)) { did_work = TRUE; /* FIXME: maybe distribute the gray queue here? */ } if (!did_work && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) { SgenObjectOperations *ops = sgen_concurrent_collection_in_progress () ? &major->major_concurrent_ops : &major->major_ops; ScanCopyContext ctx = { ops->scan_object, NULL, &data->private_gray_queue }; g_assert (!sgen_gray_object_queue_is_empty (&data->private_gray_queue)); while (!sgen_drain_gray_stack (32, ctx)) { if (workers_state.data.state == STATE_NURSERY_COLLECTION) workers_wait (); } g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue)); init_private_gray_queue (data); did_work = TRUE; } if (!did_work) workers_wait (); } /* dummy return to make compilers happy */ return NULL; }
static mono_native_thread_return_t workers_thread_func (void *data_untyped) { WorkerData *data = data_untyped; SgenMajorCollector *major = sgen_get_major_collector (); mono_thread_info_register_small_id (); if (major->init_worker_thread) major->init_worker_thread (data->major_collector_data); init_private_gray_queue (data); for (;;) { gboolean did_work = FALSE; while (workers_dequeue_and_do_job (data)) { did_work = TRUE; /* FIXME: maybe distribute the gray queue here? */ } if (workers_marking && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) { SgenObjectOperations *ops = sgen_concurrent_collection_in_progress () ? &major->major_concurrent_ops : &major->major_ops; ScanCopyContext ctx = { ops->scan_object, NULL, &data->private_gray_queue }; g_assert (!sgen_gray_object_queue_is_empty (&data->private_gray_queue)); while (!sgen_drain_gray_stack (32, ctx)) workers_gray_queue_share_redirect (&data->private_gray_queue); g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue)); init_private_gray_queue (data); did_work = TRUE; } if (!did_work) workers_wait (); } /* dummy return to make compilers happy */ return NULL; }
static mono_native_thread_return_t workers_thread_func (void *data_untyped) { WorkerData *data = data_untyped; mono_thread_info_register_small_id (); if (sgen_get_major_collector ()->init_worker_thread) sgen_get_major_collector ()->init_worker_thread (data->major_collector_data); sgen_gray_object_queue_init_with_alloc_prepare (&data->private_gray_queue, workers_gray_queue_share_redirect, data); for (;;) { gboolean did_work = FALSE; while (workers_dequeue_and_do_job (data)) { did_work = TRUE; /* FIXME: maybe distribute the gray queue here? */ } if (workers_marking && (!sgen_gray_object_queue_is_empty (&data->private_gray_queue) || workers_get_work (data))) { g_assert (!sgen_gray_object_queue_is_empty (&data->private_gray_queue)); while (!sgen_drain_gray_stack (&data->private_gray_queue, 32)) workers_gray_queue_share_redirect (&data->private_gray_queue); g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue)); sgen_gray_object_queue_init (&data->private_gray_queue); did_work = TRUE; } if (!did_work) workers_wait (); } /* dummy return to make compilers happy */ return NULL; }