static inline void gray_object_enqueue (GrayQueue *queue, char *obj) { DEBUG (9, g_assert (obj)); if (G_UNLIKELY (!queue->first || queue->first->end == GRAY_QUEUE_SECTION_SIZE)) gray_object_alloc_queue_section (queue); DEBUG (9, g_assert (queue->first && queue->first->end < GRAY_QUEUE_SECTION_SIZE)); queue->first->objects [queue->first->end++] = obj; DEBUG (9, ++queue->balance); }
static gboolean workers_steal (WorkerData *data, WorkerData *victim_data, gboolean lock) { GrayQueue *queue = &data->private_gray_queue; int num, n; g_assert (!queue->first); if (!victim_data->stealable_stack_fill) return FALSE; if (lock && pthread_mutex_trylock (&victim_data->stealable_stack_mutex)) return FALSE; n = num = (victim_data->stealable_stack_fill + 1) / 2; /* We're stealing num entries. */ while (n > 0) { int m = MIN (SGEN_GRAY_QUEUE_SECTION_SIZE, n); n -= m; gray_object_alloc_queue_section (queue); memcpy (queue->first->objects, victim_data->stealable_stack + victim_data->stealable_stack_fill - num + n, sizeof (char*) * m); queue->first->end = m; } victim_data->stealable_stack_fill -= num; if (lock) pthread_mutex_unlock (&victim_data->stealable_stack_mutex); if (data == victim_data) { if (lock) stat_workers_stolen_from_self_lock += num; else stat_workers_stolen_from_self_no_lock += num; } else { stat_workers_stolen_from_others += num; } return num != 0; }