Ruby 3.5.0dev (2025-01-10 revision 5fab31b15e32622c4b71d1d347a41937e9f9c212)
vm_sync.h (5fab31b15e32622c4b71d1d347a41937e9f9c212)
1#ifndef RUBY_VM_SYNC_H
2#define RUBY_VM_SYNC_H
3
4#include "vm_debug.h"
5#include "debug_counter.h"
6
7#if USE_RUBY_DEBUG_LOG
8#define LOCATION_ARGS const char *file, int line
9#define LOCATION_PARAMS file, line
10#define APPEND_LOCATION_ARGS , const char *file, int line
11#define APPEND_LOCATION_PARAMS , file, line
12#else
13#define LOCATION_ARGS void
14#define LOCATION_PARAMS
15#define APPEND_LOCATION_ARGS
16#define APPEND_LOCATION_PARAMS
17#endif
18
19bool rb_vm_locked_p(void);
20void rb_vm_lock_body(LOCATION_ARGS);
21void rb_vm_unlock_body(LOCATION_ARGS);
22
23struct rb_ractor_struct;
24NOINLINE(void rb_vm_lock_enter_body_cr(struct rb_ractor_struct *cr, unsigned int *lev APPEND_LOCATION_ARGS));
25NOINLINE(void rb_vm_lock_enter_body_nb(unsigned int *lev APPEND_LOCATION_ARGS));
26NOINLINE(void rb_vm_lock_enter_body(unsigned int *lev APPEND_LOCATION_ARGS));
27void rb_vm_lock_leave_body(unsigned int *lev APPEND_LOCATION_ARGS);
28void rb_vm_barrier(void);
29
30#if RUBY_DEBUG
31// GET_VM()
32#include "vm_core.h"
33#endif
34
35RUBY_EXTERN struct rb_ractor_struct *ruby_single_main_ractor; // ractor.c
36
37static inline bool
38rb_multi_ractor_p(void)
39{
40 if (LIKELY(ruby_single_main_ractor)) {
41 // 0 on boot time.
42 RUBY_ASSERT(GET_VM()->ractor.cnt <= 1);
43 return false;
44 }
45 else {
46 // multi-ractor mode can run ractor.cnt == 1
47 return true;
48 }
49}
50
51static inline void
52rb_vm_lock(const char *file, int line)
53{
54 RB_DEBUG_COUNTER_INC(vm_sync_lock);
55
56 if (rb_multi_ractor_p()) {
57 rb_vm_lock_body(LOCATION_PARAMS);
58 }
59}
60
61static inline void
62rb_vm_unlock(const char *file, int line)
63{
64 if (rb_multi_ractor_p()) {
65 rb_vm_unlock_body(LOCATION_PARAMS);
66 }
67}
68
69static inline void
70rb_vm_lock_enter(unsigned int *lev, const char *file, int line)
71{
72 RB_DEBUG_COUNTER_INC(vm_sync_lock_enter);
73
74 if (rb_multi_ractor_p()) {
75 rb_vm_lock_enter_body(lev APPEND_LOCATION_PARAMS);
76 }
77}
78
79static inline void
80rb_vm_lock_enter_nb(unsigned int *lev, const char *file, int line)
81{
82 RB_DEBUG_COUNTER_INC(vm_sync_lock_enter_nb);
83
84 if (rb_multi_ractor_p()) {
85 rb_vm_lock_enter_body_nb(lev APPEND_LOCATION_PARAMS);
86 }
87}
88
89static inline void
90rb_vm_lock_leave(unsigned int *lev, const char *file, int line)
91{
92 if (rb_multi_ractor_p()) {
93 rb_vm_lock_leave_body(lev APPEND_LOCATION_PARAMS);
94 }
95}
96
97static inline void
98rb_vm_lock_enter_cr(struct rb_ractor_struct *cr, unsigned int *levp, const char *file, int line)
99{
100 RB_DEBUG_COUNTER_INC(vm_sync_lock_enter_cr);
101 rb_vm_lock_enter_body_cr(cr, levp APPEND_LOCATION_PARAMS);
102}
103
104static inline void
105rb_vm_lock_leave_cr(struct rb_ractor_struct *cr, unsigned int *levp, const char *file, int line)
106{
107 rb_vm_lock_leave_body(levp APPEND_LOCATION_PARAMS);
108}
109
110#define RB_VM_LOCKED_P() rb_vm_locked_p()
111
112#define RB_VM_LOCK() rb_vm_lock(__FILE__, __LINE__)
113#define RB_VM_UNLOCK() rb_vm_unlock(__FILE__, __LINE__)
114
115#define RB_VM_LOCK_ENTER_CR_LEV(cr, levp) rb_vm_lock_enter_cr(cr, levp, __FILE__, __LINE__)
116#define RB_VM_LOCK_LEAVE_CR_LEV(cr, levp) rb_vm_lock_leave_cr(cr, levp, __FILE__, __LINE__)
117#define RB_VM_LOCK_ENTER_LEV(levp) rb_vm_lock_enter(levp, __FILE__, __LINE__)
118#define RB_VM_LOCK_LEAVE_LEV(levp) rb_vm_lock_leave(levp, __FILE__, __LINE__)
119
120#define RB_VM_LOCK_ENTER() { unsigned int _lev; RB_VM_LOCK_ENTER_LEV(&_lev);
121#define RB_VM_LOCK_LEAVE() RB_VM_LOCK_LEAVE_LEV(&_lev); }
122
123#define RB_VM_LOCK_ENTER_LEV_NB(levp) rb_vm_lock_enter_nb(levp, __FILE__, __LINE__)
124#define RB_VM_LOCK_ENTER_NO_BARRIER() { unsigned int _lev; RB_VM_LOCK_ENTER_LEV_NB(&_lev);
125#define RB_VM_LOCK_LEAVE_NO_BARRIER() RB_VM_LOCK_LEAVE_LEV(&_lev); }
126
127#if RUBY_DEBUG > 0
128void RUBY_ASSERT_vm_locking(void);
129void RUBY_ASSERT_vm_unlocking(void);
130#define ASSERT_vm_locking() RUBY_ASSERT_vm_locking()
131#define ASSERT_vm_unlocking() RUBY_ASSERT_vm_unlocking()
132#else
133#define ASSERT_vm_locking()
134#define ASSERT_vm_unlocking()
135#endif
136
137#endif // RUBY_VM_SYNC_H
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
#define RUBY_EXTERN
Declaration of externally visible global variables.
Definition dllexport.h:45