static gboolean workers_steal (WorkerData *data, WorkerData *victim_data, gboolean lock) { SgenGrayQueue *queue = &data->private_gray_queue; int num, n; g_assert (!queue->first); if (!victim_data->stealable_stack_fill) return FALSE; if (lock && mono_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; sgen_gray_object_alloc_queue_section (queue); memcpy (queue->first->entries, victim_data->stealable_stack + victim_data->stealable_stack_fill - num + n, sizeof (GrayQueueEntry) * m); queue->first->size = m; /* * DO NOT move outside this loop * Doing so trigger "assert not reached" in sgen-scan-object.h : we use the queue->cursor * to compute the size of the first section during section allocation (via alloc_prepare_func * -> workers_gray_queue_share_redirect -> sgen_gray_object_dequeue_section) which will be then * set to 0, because queue->cursor is still pointing to queue->first->entries [-1], thus * losing objects in the gray queue. */ queue->cursor = queue->first->entries + queue->first->size - 1; } victim_data->stealable_stack_fill -= num; if (lock) mono_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; }
static int noshm_sem_trylock (int sem) { int ret; DEBUGLOG ("%s: trying to lock nosem %d", __func__, sem); ret = mono_mutex_trylock (&noshm_sems[sem]); return ret; }
static gboolean workers_steal (WorkerData *data, WorkerData *victim_data, gboolean lock) { SgenGrayQueue *queue = &data->private_gray_queue; int num, n; g_assert (!queue->first); if (!victim_data->stealable_stack_fill) return FALSE; if (lock && mono_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; sgen_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) mono_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; }