void sgen_gray_object_queue_deinit (SgenGrayQueue *queue) { g_assert (!queue->first); while (queue->free_list) { GrayQueueSection *next = queue->free_list->next; STATE_TRANSITION (queue->free_list, GRAY_QUEUE_SECTION_STATE_FREE_LIST, GRAY_QUEUE_SECTION_STATE_FLOATING); sgen_gray_object_free_queue_section (queue->free_list); queue->free_list = next; } }
void sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue) { GrayQueueSection *section, *next; int i = 0; for (section = queue->free_list; section && i < GRAY_QUEUE_LENGTH_LIMIT - 1; section = section->next) { STATE_ASSERT (section, GRAY_QUEUE_SECTION_STATE_FREE_LIST); i ++; } if (!section) return; while (section->next) { next = section->next; section->next = next->next; STATE_TRANSITION (next, GRAY_QUEUE_SECTION_STATE_FREE_LIST, GRAY_QUEUE_SECTION_STATE_FLOATING); sgen_gray_object_free_queue_section (next); } }
static void workers_gray_queue_share_redirect (SgenGrayQueue *queue) { GrayQueueSection *section; WorkerData *data = queue->alloc_prepare_data; if (data->stealable_stack_fill) { /* * There are still objects in the stealable stack, so * wake up any workers that might be sleeping */ if (workers_state.data.gc_in_progress) workers_wake_up_all (); return; } /* The stealable stack is empty, so fill it. */ mono_mutex_lock (&data->stealable_stack_mutex); while (data->stealable_stack_fill < STEALABLE_STACK_SIZE && (section = sgen_gray_object_dequeue_section (queue))) { int num = MIN (section->size, STEALABLE_STACK_SIZE - data->stealable_stack_fill); memcpy (data->stealable_stack + data->stealable_stack_fill, section->entries + section->size - num, sizeof (GrayQueueEntry) * num); section->size -= num; data->stealable_stack_fill += num; if (section->size) sgen_gray_object_enqueue_section (queue, section); else sgen_gray_object_free_queue_section (section); } if (sgen_gray_object_queue_is_empty (queue)) workers_steal (data, data, FALSE); mono_mutex_unlock (&data->stealable_stack_mutex); if (workers_state.data.gc_in_progress) workers_wake_up_all (); }
void sgen_gray_object_queue_init (SgenGrayQueue *queue) { GrayQueueSection *section, *next; int i; g_assert (sgen_gray_object_queue_is_empty (queue)); SGEN_ASSERT (9, queue->balance == 0, "unbalanced queue on init %d", queue->balance); /* Free the extra sections allocated during the last collection */ i = 0; for (section = queue->free_list; section && i < GRAY_QUEUE_LENGTH_LIMIT - 1; section = section->next) i ++; if (!section) return; while (section->next) { next = section->next; section->next = next->next; sgen_gray_object_free_queue_section (next); } }