summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <[email protected]>2025-06-04 06:41:39 +0900
committerKoichi Sasada <[email protected]>2025-06-06 06:49:08 +0900
commita62166e28efeb13d309bc4b7dc04371a5b62b3cc (patch)
treef592e57a1daa0f285f06e0e8f67e5e47656088c1
parent1a991131a04feb3527f7e4993491b587d2e57179 (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.c23
1 files 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);
+ }
}
}