Ejemplo n.º 1
0
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 ();
}
Ejemplo n.º 2
0
static gboolean
workers_get_work (WorkerData *data)
{
    SgenMajorCollector *major;

    g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));

    /* If we're concurrent, steal from the workers distribute gray queue. */
    major = sgen_get_major_collector ();
    if (major->is_concurrent) {
        GrayQueueSection *section = sgen_section_gray_queue_dequeue (&workers_distribute_gray_queue);
        if (section) {
            sgen_gray_object_enqueue_section (&data->private_gray_queue, section);
            return TRUE;
        }
    }

    /* Nobody to steal from */
    g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));
    return FALSE;
}
Ejemplo n.º 3
0
static gboolean
workers_get_work (WorkerData *data)
{
	SgenMajorCollector *major;
	int i;

	g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));

	/* Try to steal from our own stack. */
	if (workers_steal (data, data, TRUE))
		return TRUE;

	/* From another worker. */
	for (i = 0; i < workers_num; ++i) {
		WorkerData *victim_data = &workers_data [i];
		if (data == victim_data)
			continue;
		if (workers_steal (data, victim_data, TRUE))
			return TRUE;
	}

	/*
	 * If we're concurrent or parallel, from the workers
	 * distribute gray queue.
	 */
	major = sgen_get_major_collector ();
	if (major->is_concurrent || major->is_parallel) {
		GrayQueueSection *section = sgen_section_gray_queue_dequeue (&workers_distribute_gray_queue);
		if (section) {
			sgen_gray_object_enqueue_section (&data->private_gray_queue, section);
			return TRUE;
		}
	}

	/* Nobody to steal from */
	g_assert (sgen_gray_object_queue_is_empty (&data->private_gray_queue));
	return FALSE;
}