From a62166e28efeb13d309bc4b7dc04371a5b62b3cc Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 4 Jun 2025 06:41:39 +0900 Subject: [PATCH] support nested VM barrier synchronization on `RGENGC_CHECK_MODE > 1`, there are the following steps 1. gc_enter 2. vm_barrier 3. verify_internal_consistency 4. vm_barrier and it causes nested vm_barrier synchronization. This patch allows such cases. --- vm_sync.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/vm_sync.c b/vm_sync.c index 54c9cb8236..bafb18b126 100644 --- a/vm_sync.c +++ b/vm_sync.c @@ -226,6 +226,16 @@ rb_vm_cond_timedwait(rb_vm_t *vm, rb_nativethread_cond_t *cond, unsigned long ms vm_cond_wait(vm, cond, msec); } +static bool +vm_barrier_acquired_p(const rb_vm_t *vm, const rb_ractor_t *cr) +{ +#ifdef RUBY_THREAD_PTHREAD_H + return vm->ractor.sched.barrier_ractor == cr; +#else + return false; +#endif +} + void rb_vm_barrier(void) { @@ -237,13 +247,20 @@ rb_vm_barrier(void) } else { rb_vm_t *vm = GET_VM(); - VM_ASSERT(!vm->ractor.sched.barrier_waiting); - ASSERT_vm_locking(); rb_ractor_t *cr = vm->ractor.sync.lock_owner; + + ASSERT_vm_locking(); VM_ASSERT(cr == GET_RACTOR()); VM_ASSERT(rb_ractor_status_p(cr, ractor_running)); - rb_ractor_sched_barrier_start(vm, cr); + if (vm_barrier_acquired_p(vm, cr)) { + // already in barrier synchronization + return; + } + else { + VM_ASSERT(!vm->ractor.sched.barrier_waiting); + rb_ractor_sched_barrier_start(vm, cr); + } } }