diff options
author | Koichi Sasada <[email protected]> | 2025-06-04 06:41:39 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2025-06-06 06:49:08 +0900 |
commit | a62166e28efeb13d309bc4b7dc04371a5b62b3cc (patch) | |
tree | f592e57a1daa0f285f06e0e8f67e5e47656088c1 | |
parent | 1a991131a04feb3527f7e4993491b587d2e57179 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13507
-rw-r--r-- | vm_sync.c | 23 |
1 files changed, 20 insertions, 3 deletions
@@ -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); + } } } |