예제 #1
0
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 ();
}
예제 #2
0
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);
    }
}