1#include "internal/gc.h"
2#include "internal/thread.h"
5#include "ractor_core.h"
14 return vm->ractor.sync.lock_owner == GET_RACTOR();
19RUBY_ASSERT_vm_locking(
void)
21 if (rb_multi_ractor_p()) {
23 VM_ASSERT(vm_locked(vm));
28RUBY_ASSERT_vm_unlocking(
void)
30 if (rb_multi_ractor_p()) {
32 VM_ASSERT(!vm_locked(vm));
40 return vm_locked(GET_VM());
44vm_lock_enter(
rb_ractor_t *cr,
rb_vm_t *vm,
bool locked,
bool no_barrier,
unsigned int *lev APPEND_LOCATION_ARGS)
46 RUBY_DEBUG_LOG2(file, line,
"start locked:%d", locked);
54 VM_ASSERT(cr->sync.locked_by != rb_ractor_self(cr));
58 VM_ASSERT(vm->ractor.sync.lock_owner == NULL);
59 VM_ASSERT(vm->ractor.sync.lock_rec == 0);
61#ifdef RUBY_THREAD_PTHREAD_H
63 cr->threads.sched.running != NULL
66 while (vm->ractor.sched.barrier_waiting) {
67 RUBY_DEBUG_LOG(
"barrier serial:%u", vm->ractor.sched.barrier_serial);
68 rb_ractor_sched_barrier_join(vm, cr);
73 while (vm->ractor.sync.barrier_waiting) {
74 rb_ractor_sched_barrier_join(vm, cr);
79 VM_ASSERT(vm->ractor.sync.lock_rec == 0);
80 VM_ASSERT(vm->ractor.sync.lock_owner == NULL);
81 vm->ractor.sync.lock_owner = cr;
84 vm->ractor.sync.lock_rec++;
85 *lev = vm->ractor.sync.lock_rec;
87 RUBY_DEBUG_LOG2(file, line,
"rec:%u owner:%u", vm->ractor.sync.lock_rec,
88 (
unsigned int)rb_ractor_id(vm->ractor.sync.lock_owner));
92vm_lock_leave(
rb_vm_t *vm,
unsigned int *lev APPEND_LOCATION_ARGS)
94 RUBY_DEBUG_LOG2(file, line,
"rec:%u owner:%u%s", vm->ractor.sync.lock_rec,
95 (
unsigned int)rb_ractor_id(vm->ractor.sync.lock_owner),
96 vm->ractor.sync.lock_rec == 1 ?
" (leave)" :
"");
99 VM_ASSERT(vm->ractor.sync.lock_rec > 0);
100 VM_ASSERT(vm->ractor.sync.lock_rec == *lev);
102 vm->ractor.sync.lock_rec--;
103 *lev = vm->ractor.sync.lock_rec;
105 if (vm->ractor.sync.lock_rec == 0) {
106 vm->ractor.sync.lock_owner = NULL;
112rb_vm_lock_enter_body(
unsigned int *lev APPEND_LOCATION_ARGS)
116 vm_lock_enter(NULL, vm,
true,
false, lev APPEND_LOCATION_PARAMS);
119 vm_lock_enter(GET_RACTOR(), vm,
false,
false, lev APPEND_LOCATION_PARAMS);
124rb_vm_lock_enter_body_nb(
unsigned int *lev APPEND_LOCATION_ARGS)
128 vm_lock_enter(NULL, vm,
true,
true, lev APPEND_LOCATION_PARAMS);
131 vm_lock_enter(GET_RACTOR(), vm,
false,
true, lev APPEND_LOCATION_PARAMS);
136rb_vm_lock_enter_body_cr(
rb_ractor_t *cr,
unsigned int *lev APPEND_LOCATION_ARGS)
139 vm_lock_enter(cr, vm, vm_locked(vm),
false, lev APPEND_LOCATION_PARAMS);
143rb_vm_lock_leave_body(
unsigned int *lev APPEND_LOCATION_ARGS)
145 vm_lock_leave(GET_VM(), lev APPEND_LOCATION_PARAMS);
149rb_vm_lock_body(LOCATION_ARGS)
152 ASSERT_vm_unlocking();
154 vm_lock_enter(GET_RACTOR(), vm,
false,
false, &vm->ractor.sync.lock_rec APPEND_LOCATION_PARAMS);
158rb_vm_unlock_body(LOCATION_ARGS)
162 VM_ASSERT(vm->ractor.sync.lock_rec == 1);
163 vm_lock_leave(vm, &vm->ractor.sync.lock_rec APPEND_LOCATION_PARAMS);
167vm_cond_wait(
rb_vm_t *vm, rb_nativethread_cond_t *cond,
unsigned long msec)
170 unsigned int lock_rec = vm->ractor.sync.lock_rec;
173 vm->ractor.sync.lock_rec = 0;
174 vm->ractor.sync.lock_owner = NULL;
181 vm->ractor.sync.lock_rec = lock_rec;
182 vm->ractor.sync.lock_owner = cr;
186rb_vm_cond_wait(
rb_vm_t *vm, rb_nativethread_cond_t *cond)
188 vm_cond_wait(vm, cond, 0);
192rb_vm_cond_timedwait(
rb_vm_t *vm, rb_nativethread_cond_t *cond,
unsigned long msec)
194 vm_cond_wait(vm, cond, msec);
200 RB_DEBUG_COUNTER_INC(vm_sync_barrier);
202 if (!rb_multi_ractor_p()) {
208 VM_ASSERT(!vm->ractor.sched.barrier_waiting);
211 VM_ASSERT(cr == GET_RACTOR());
212 VM_ASSERT(rb_ractor_status_p(cr, ractor_running));
214 rb_ractor_sched_barrier_start(vm, cr);
220 unsigned int recorded_lock_rec,
221 unsigned int current_lock_rec)
223 VM_ASSERT(recorded_lock_rec != current_lock_rec);
225 if (UNLIKELY(recorded_lock_rec > current_lock_rec)) {
226 rb_bug(
"unexpected situation - recordd:%u current:%u",
227 recorded_lock_rec, current_lock_rec);
230 while (recorded_lock_rec < current_lock_rec) {
231 RB_VM_LOCK_LEAVE_LEV(¤t_lock_rec);
235 VM_ASSERT(recorded_lock_rec == rb_ec_vm_lock_rec(ec));
void rb_native_mutex_lock(rb_nativethread_lock_t *lock)
Just another name of rb_nativethread_lock_lock.
void rb_native_mutex_unlock(rb_nativethread_lock_t *lock)
Just another name of rb_nativethread_lock_unlock.
void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex)
Waits for the passed condition variable to be signalled.
void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec)
Identical to rb_native_cond_wait(), except it additionally takes timeout in msec resolution.