static void workers_gray_queue_share_redirect (GrayQueue *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_gc_in_progress) workers_wake_up_all (); return; } /* The stealable stack is empty, so fill it. */ pthread_mutex_lock (&data->stealable_stack_mutex); while (data->stealable_stack_fill < STEALABLE_STACK_SIZE && (section = gray_object_dequeue_section (queue))) { int num = MIN (section->end, STEALABLE_STACK_SIZE - data->stealable_stack_fill); memcpy (data->stealable_stack + data->stealable_stack_fill, section->objects + section->end - num, sizeof (char*) * num); section->end -= num; data->stealable_stack_fill += num; if (section->end) gray_object_enqueue_section (queue, section); else gray_object_free_queue_section (section); } if (data != &workers_gc_thread_data && gray_object_queue_is_empty (queue)) workers_steal (data, data, FALSE); pthread_mutex_unlock (&data->stealable_stack_mutex); if (workers_gc_in_progress) workers_wake_up_all (); }
static void gray_object_queue_init (GrayQueue *queue) { GrayQueueSection *section, *next; int i; g_assert (gray_object_queue_is_empty (queue)); DEBUG (9, g_assert (queue->balance == 0)); /* 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; gray_object_free_queue_section (next); } }