Line | Count | Source |
1 | | #include "internal/gc.h" |
2 | | #include "ruby/ruby.h" |
3 | | #include "ruby/ractor.h" |
4 | | #include "vm_core.h" |
5 | | #include "id_table.h" |
6 | | #include "vm_debug.h" |
7 | | |
8 | | #ifndef RACTOR_CHECK_MODE |
9 | | #define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE) |
10 | | #endif |
11 | | |
12 | | // experimental flag because it is not sure it is the common pattern |
13 | 0 | #define RUBY_TYPED_FROZEN_SHAREABLE_NO_REC RUBY_FL_FINALIZE |
14 | | |
15 | | struct rb_ractor_sync { |
16 | | // ractor lock |
17 | | rb_nativethread_lock_t lock; |
18 | | |
19 | | #if RACTOR_CHECK_MODE > 0 |
20 | | VALUE locked_by; |
21 | | #endif |
22 | | |
23 | | #ifndef RUBY_THREAD_PTHREAD_H |
24 | | rb_nativethread_cond_t wakeup_cond; |
25 | | #endif |
26 | | |
27 | | // incoming messages |
28 | | struct ractor_queue *recv_queue; |
29 | | |
30 | | // waiting threads for receiving |
31 | | struct ccan_list_head waiters; |
32 | | |
33 | | // ports |
34 | | VALUE default_port_value; |
35 | | struct st_table *ports; |
36 | | size_t next_port_id; |
37 | | |
38 | | // monitors |
39 | | struct ccan_list_head monitors; |
40 | | |
41 | | // value |
42 | | rb_ractor_t *successor; |
43 | | VALUE legacy; |
44 | | bool legacy_exc; |
45 | | }; |
46 | | |
47 | | // created |
48 | | // | ready to run |
49 | | // ====================== inserted to vm->ractor |
50 | | // v |
51 | | // blocking <---+ all threads are blocking |
52 | | // | | |
53 | | // v | |
54 | | // running -----+ |
55 | | // | all threads are terminated. |
56 | | // ====================== removed from vm->ractor |
57 | | // v |
58 | | // terminated |
59 | | // |
60 | | // status is protected by VM lock (global state) |
61 | | enum ractor_status { |
62 | | ractor_created, |
63 | | ractor_running, |
64 | | ractor_blocking, |
65 | | ractor_terminated, |
66 | | }; |
67 | | |
68 | | struct rb_ractor_struct { |
69 | | struct rb_ractor_pub pub; |
70 | | struct rb_ractor_sync sync; |
71 | | |
72 | | // thread management |
73 | | struct { |
74 | | struct ccan_list_head set; |
75 | | unsigned int cnt; |
76 | | unsigned int blocking_cnt; |
77 | | unsigned int sleeper; |
78 | | struct rb_thread_sched sched; |
79 | | rb_execution_context_t *running_ec; |
80 | | rb_thread_t *main; |
81 | | } threads; |
82 | | |
83 | | VALUE thgroup_default; |
84 | | |
85 | | VALUE name; |
86 | | VALUE loc; |
87 | | |
88 | | enum ractor_status status_; |
89 | | |
90 | | struct ccan_list_node vmlr_node; |
91 | | |
92 | | // ractor local data |
93 | | |
94 | | rb_serial_t next_ec_serial; |
95 | | |
96 | | st_table *local_storage; |
97 | | struct rb_id_table *idkey_local_storage; |
98 | | VALUE local_storage_store_lock; |
99 | | |
100 | | VALUE r_stdin; |
101 | | VALUE r_stdout; |
102 | | VALUE r_stderr; |
103 | | VALUE verbose; |
104 | | VALUE debug; |
105 | | |
106 | | bool malloc_gc_disabled; |
107 | | bool main_ractor; |
108 | | void *newobj_cache; |
109 | | }; // rb_ractor_t is defined in vm_core.h |
110 | | |
111 | | enum ractor_wakeup_status { |
112 | | wakeup_none, |
113 | | wakeup_by_send, |
114 | | wakeup_by_interrupt, |
115 | | // wakeup_by_close, |
116 | | }; |
117 | | |
118 | | struct ractor_waiter { |
119 | | enum ractor_wakeup_status wakeup_status; |
120 | | rb_thread_t *th; |
121 | | struct ccan_list_node node; |
122 | | rb_atomic_t event_serial; |
123 | | }; |
124 | | |
125 | | static inline VALUE |
126 | | rb_ractor_self(const rb_ractor_t *r) |
127 | 91.0k | { |
128 | 91.0k | return r->pub.self; |
129 | 91.0k | } Unexecuted instantiation: eval.c:rb_ractor_self Unexecuted instantiation: gc.c:rb_ractor_self Unexecuted instantiation: iseq.c:rb_ractor_self Unexecuted instantiation: load.c:rb_ractor_self Unexecuted instantiation: proc.c:rb_ractor_self Unexecuted instantiation: process.c:rb_ractor_self Unexecuted instantiation: ractor.c:rb_ractor_self Unexecuted instantiation: re.c:rb_ractor_self Unexecuted instantiation: signal.c:rb_ractor_self Unexecuted instantiation: thread.c:rb_ractor_self Unexecuted instantiation: variable.c:rb_ractor_self Line | Count | Source | 127 | 91.0k | { | 128 | 91.0k | return r->pub.self; | 129 | 91.0k | } |
Unexecuted instantiation: vm_dump.c:rb_ractor_self Unexecuted instantiation: vm_sync.c:rb_ractor_self Unexecuted instantiation: vm_trace.c:rb_ractor_self Unexecuted instantiation: cont.c:rb_ractor_self Unexecuted instantiation: debug.c:rb_ractor_self |
130 | | |
131 | | rb_ractor_t *rb_ractor_main_alloc(void); |
132 | | void rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *main_ractor, rb_thread_t *main_thread); |
133 | | void rb_ractor_atexit(rb_execution_context_t *ec, VALUE result); |
134 | | void rb_ractor_atexit_exception(rb_execution_context_t *ec); |
135 | | void rb_ractor_teardown(rb_execution_context_t *ec); |
136 | | void rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *g, int len, VALUE *ptr); |
137 | | void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE args); |
138 | | |
139 | | VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc); // defined in thread.c |
140 | | |
141 | | int rb_ractor_living_thread_num(const rb_ractor_t *); |
142 | | VALUE rb_ractor_thread_list(void); |
143 | | bool rb_ractor_p(VALUE rv); |
144 | | |
145 | | void rb_ractor_living_threads_init(rb_ractor_t *r); |
146 | | void rb_ractor_living_threads_insert(rb_ractor_t *r, rb_thread_t *th); |
147 | | void rb_ractor_living_threads_remove(rb_ractor_t *r, rb_thread_t *th); |
148 | | void rb_ractor_blocking_threads_inc(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG |
149 | | void rb_ractor_blocking_threads_dec(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG |
150 | | |
151 | | void rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r); |
152 | | void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r); |
153 | | void rb_ractor_terminate_all(void); |
154 | | bool rb_ractor_main_p_(void); |
155 | | void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th); |
156 | | void rb_ractor_terminate_atfork(rb_vm_t *vm, rb_ractor_t *th); |
157 | | VALUE rb_ractor_require(VALUE feature, bool silent); |
158 | | VALUE rb_ractor_autoload_load(VALUE space, ID id); |
159 | | |
160 | | VALUE rb_ractor_ensure_shareable(VALUE obj, VALUE name); |
161 | | st_table *rb_ractor_targeted_hooks(rb_ractor_t *cr); |
162 | | |
163 | | RUBY_SYMBOL_EXPORT_BEGIN |
164 | | void rb_ractor_finish_marking(void); |
165 | | |
166 | | bool rb_ractor_shareable_p_continue(VALUE obj); |
167 | | |
168 | | // THIS FUNCTION SHOULD NOT CALL WHILE INCREMENTAL MARKING!! |
169 | | // This function is for T_DATA::free_func |
170 | | void rb_ractor_local_storage_delkey(rb_ractor_local_key_t key); |
171 | | |
172 | | RUBY_SYMBOL_EXPORT_END |
173 | | |
174 | | static inline bool |
175 | | rb_ractor_main_p(void) |
176 | 1.02M | { |
177 | 1.02M | if (ruby_single_main_ractor) { |
178 | 1.02M | return true; |
179 | 1.02M | } |
180 | 0 | else { |
181 | 0 | return rb_ractor_main_p_(); |
182 | 0 | } |
183 | 1.02M | } Unexecuted instantiation: eval.c:rb_ractor_main_p Unexecuted instantiation: gc.c:rb_ractor_main_p Unexecuted instantiation: iseq.c:rb_ractor_main_p Line | Count | Source | 176 | 28.9k | { | 177 | 28.9k | if (ruby_single_main_ractor) { | 178 | 28.9k | return true; | 179 | 28.9k | } | 180 | 0 | else { | 181 | 0 | return rb_ractor_main_p_(); | 182 | 0 | } | 183 | 28.9k | } |
Unexecuted instantiation: proc.c:rb_ractor_main_p Unexecuted instantiation: process.c:rb_ractor_main_p ractor.c:rb_ractor_main_p Line | Count | Source | 176 | 979k | { | 177 | 979k | if (ruby_single_main_ractor) { | 178 | 979k | return true; | 179 | 979k | } | 180 | 0 | else { | 181 | 0 | return rb_ractor_main_p_(); | 182 | 0 | } | 183 | 979k | } |
Line | Count | Source | 176 | 6.54k | { | 177 | 6.54k | if (ruby_single_main_ractor) { | 178 | 6.54k | return true; | 179 | 6.54k | } | 180 | 0 | else { | 181 | 0 | return rb_ractor_main_p_(); | 182 | 0 | } | 183 | 6.54k | } |
Unexecuted instantiation: signal.c:rb_ractor_main_p Unexecuted instantiation: thread.c:rb_ractor_main_p variable.c:rb_ractor_main_p Line | Count | Source | 176 | 6.38k | { | 177 | 6.38k | if (ruby_single_main_ractor) { | 178 | 6.38k | return true; | 179 | 6.38k | } | 180 | 0 | else { | 181 | 0 | return rb_ractor_main_p_(); | 182 | 0 | } | 183 | 6.38k | } |
Unexecuted instantiation: vm.c:rb_ractor_main_p Unexecuted instantiation: vm_dump.c:rb_ractor_main_p Unexecuted instantiation: vm_sync.c:rb_ractor_main_p Unexecuted instantiation: vm_trace.c:rb_ractor_main_p Unexecuted instantiation: cont.c:rb_ractor_main_p Unexecuted instantiation: debug.c:rb_ractor_main_p |
184 | | |
185 | | static inline bool |
186 | | rb_ractor_status_p(rb_ractor_t *r, enum ractor_status status) |
187 | 0 | { |
188 | 0 | return r->status_ == status; |
189 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_status_p Unexecuted instantiation: gc.c:rb_ractor_status_p Unexecuted instantiation: iseq.c:rb_ractor_status_p Unexecuted instantiation: load.c:rb_ractor_status_p Unexecuted instantiation: proc.c:rb_ractor_status_p Unexecuted instantiation: process.c:rb_ractor_status_p Unexecuted instantiation: ractor.c:rb_ractor_status_p Unexecuted instantiation: re.c:rb_ractor_status_p Unexecuted instantiation: signal.c:rb_ractor_status_p Unexecuted instantiation: thread.c:rb_ractor_status_p Unexecuted instantiation: variable.c:rb_ractor_status_p Unexecuted instantiation: vm.c:rb_ractor_status_p Unexecuted instantiation: vm_dump.c:rb_ractor_status_p Unexecuted instantiation: vm_sync.c:rb_ractor_status_p Unexecuted instantiation: vm_trace.c:rb_ractor_status_p Unexecuted instantiation: cont.c:rb_ractor_status_p Unexecuted instantiation: debug.c:rb_ractor_status_p |
190 | | |
191 | | static inline void |
192 | | rb_ractor_sleeper_threads_inc(rb_ractor_t *r) |
193 | 0 | { |
194 | 0 | r->threads.sleeper++; |
195 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: gc.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: iseq.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: load.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: proc.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: process.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: ractor.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: re.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: signal.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: thread.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: variable.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: vm.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: cont.c:rb_ractor_sleeper_threads_inc Unexecuted instantiation: debug.c:rb_ractor_sleeper_threads_inc |
196 | | |
197 | | static inline void |
198 | | rb_ractor_sleeper_threads_dec(rb_ractor_t *r) |
199 | 0 | { |
200 | 0 | r->threads.sleeper--; |
201 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: gc.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: iseq.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: load.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: proc.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: process.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: ractor.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: re.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: signal.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: thread.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: variable.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: vm.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: cont.c:rb_ractor_sleeper_threads_dec Unexecuted instantiation: debug.c:rb_ractor_sleeper_threads_dec |
202 | | |
203 | | static inline void |
204 | | rb_ractor_sleeper_threads_clear(rb_ractor_t *r) |
205 | 0 | { |
206 | 0 | r->threads.sleeper = 0; |
207 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: gc.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: iseq.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: load.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: proc.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: process.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: ractor.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: re.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: signal.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: thread.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: variable.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: vm.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: cont.c:rb_ractor_sleeper_threads_clear Unexecuted instantiation: debug.c:rb_ractor_sleeper_threads_clear |
208 | | |
209 | | static inline int |
210 | | rb_ractor_sleeper_thread_num(rb_ractor_t *r) |
211 | 0 | { |
212 | 0 | return r->threads.sleeper; |
213 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: gc.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: iseq.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: load.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: proc.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: process.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: ractor.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: re.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: signal.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: thread.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: variable.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: vm.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: cont.c:rb_ractor_sleeper_thread_num Unexecuted instantiation: debug.c:rb_ractor_sleeper_thread_num |
214 | | |
215 | | static inline void |
216 | | rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th, bool always_reset) |
217 | 35 | { |
218 | 35 | RUBY_DEBUG_LOG("th:%d->%u%s", |
219 | 35 | cr->threads.running_ec ? (int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1, |
220 | 35 | rb_th_serial(th), cr->threads.running_ec == th->ec ? " (same)" : ""); |
221 | | |
222 | 35 | if (cr->threads.running_ec != th->ec || always_reset) { |
223 | 0 | th->running_time_us = 0; |
224 | 0 | } |
225 | | |
226 | 35 | if (cr->threads.running_ec != th->ec) { |
227 | 0 | if (0) { |
228 | 0 | ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n", |
229 | 0 | (void *)cr->threads.running_ec, (void *)th->ec); |
230 | 0 | } |
231 | 0 | } |
232 | 35 | else { |
233 | 35 | return; |
234 | 35 | } |
235 | | |
236 | 0 | cr->threads.running_ec = th->ec; |
237 | |
|
238 | 0 | VM_ASSERT(cr == GET_RACTOR()); |
239 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_thread_switch Unexecuted instantiation: gc.c:rb_ractor_thread_switch Unexecuted instantiation: iseq.c:rb_ractor_thread_switch Unexecuted instantiation: load.c:rb_ractor_thread_switch Unexecuted instantiation: proc.c:rb_ractor_thread_switch Unexecuted instantiation: process.c:rb_ractor_thread_switch Unexecuted instantiation: ractor.c:rb_ractor_thread_switch Unexecuted instantiation: re.c:rb_ractor_thread_switch Unexecuted instantiation: signal.c:rb_ractor_thread_switch thread.c:rb_ractor_thread_switch Line | Count | Source | 217 | 35 | { | 218 | 35 | RUBY_DEBUG_LOG("th:%d->%u%s", | 219 | 35 | cr->threads.running_ec ? (int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1, | 220 | 35 | rb_th_serial(th), cr->threads.running_ec == th->ec ? " (same)" : ""); | 221 | | | 222 | 35 | if (cr->threads.running_ec != th->ec || always_reset) { | 223 | 0 | th->running_time_us = 0; | 224 | 0 | } | 225 | | | 226 | 35 | if (cr->threads.running_ec != th->ec) { | 227 | 0 | if (0) { | 228 | 0 | ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n", | 229 | 0 | (void *)cr->threads.running_ec, (void *)th->ec); | 230 | 0 | } | 231 | 0 | } | 232 | 35 | else { | 233 | 35 | return; | 234 | 35 | } | 235 | | | 236 | 0 | cr->threads.running_ec = th->ec; | 237 | |
| 238 | 0 | VM_ASSERT(cr == GET_RACTOR()); | 239 | 0 | } |
Unexecuted instantiation: variable.c:rb_ractor_thread_switch Unexecuted instantiation: vm.c:rb_ractor_thread_switch Unexecuted instantiation: vm_dump.c:rb_ractor_thread_switch Unexecuted instantiation: vm_sync.c:rb_ractor_thread_switch Unexecuted instantiation: vm_trace.c:rb_ractor_thread_switch Unexecuted instantiation: cont.c:rb_ractor_thread_switch Unexecuted instantiation: debug.c:rb_ractor_thread_switch |
240 | | |
241 | 9 | #define rb_ractor_set_current_ec(cr, ec) rb_ractor_set_current_ec_(cr, ec, __FILE__, __LINE__) |
242 | | #ifdef RB_THREAD_LOCAL_SPECIFIER |
243 | | void rb_current_ec_set(rb_execution_context_t *ec); |
244 | | #endif |
245 | | |
246 | | static inline void |
247 | | rb_ractor_set_current_ec_(rb_ractor_t *cr, rb_execution_context_t *ec, const char *file, int line) |
248 | 9 | { |
249 | 9 | #ifdef RB_THREAD_LOCAL_SPECIFIER |
250 | 9 | rb_current_ec_set(ec); |
251 | | #else |
252 | | native_tls_set(ruby_current_ec_key, ec); |
253 | | #endif |
254 | 9 | RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec); |
255 | 9 | VM_ASSERT(ec == NULL || cr->threads.running_ec != ec); |
256 | 9 | cr->threads.running_ec = ec; |
257 | 9 | } Unexecuted instantiation: eval.c:rb_ractor_set_current_ec_ Unexecuted instantiation: gc.c:rb_ractor_set_current_ec_ Unexecuted instantiation: iseq.c:rb_ractor_set_current_ec_ Unexecuted instantiation: load.c:rb_ractor_set_current_ec_ Unexecuted instantiation: proc.c:rb_ractor_set_current_ec_ Unexecuted instantiation: process.c:rb_ractor_set_current_ec_ Unexecuted instantiation: ractor.c:rb_ractor_set_current_ec_ Unexecuted instantiation: re.c:rb_ractor_set_current_ec_ Unexecuted instantiation: signal.c:rb_ractor_set_current_ec_ Unexecuted instantiation: thread.c:rb_ractor_set_current_ec_ Unexecuted instantiation: variable.c:rb_ractor_set_current_ec_ vm.c:rb_ractor_set_current_ec_ Line | Count | Source | 248 | 9 | { | 249 | 9 | #ifdef RB_THREAD_LOCAL_SPECIFIER | 250 | 9 | rb_current_ec_set(ec); | 251 | | #else | 252 | | native_tls_set(ruby_current_ec_key, ec); | 253 | | #endif | 254 | 9 | RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec); | 255 | 9 | VM_ASSERT(ec == NULL || cr->threads.running_ec != ec); | 256 | 9 | cr->threads.running_ec = ec; | 257 | 9 | } |
Unexecuted instantiation: vm_dump.c:rb_ractor_set_current_ec_ Unexecuted instantiation: vm_sync.c:rb_ractor_set_current_ec_ Unexecuted instantiation: vm_trace.c:rb_ractor_set_current_ec_ Unexecuted instantiation: cont.c:rb_ractor_set_current_ec_ Unexecuted instantiation: debug.c:rb_ractor_set_current_ec_ |
258 | | |
259 | | void rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line); |
260 | | void rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line); |
261 | | |
262 | | static inline uint32_t |
263 | | rb_ractor_id(const rb_ractor_t *r) |
264 | 9 | { |
265 | 9 | return r->pub.id; |
266 | 9 | } Unexecuted instantiation: eval.c:rb_ractor_id Unexecuted instantiation: gc.c:rb_ractor_id Unexecuted instantiation: iseq.c:rb_ractor_id Unexecuted instantiation: load.c:rb_ractor_id Unexecuted instantiation: proc.c:rb_ractor_id Unexecuted instantiation: process.c:rb_ractor_id Unexecuted instantiation: ractor.c:rb_ractor_id Unexecuted instantiation: re.c:rb_ractor_id Unexecuted instantiation: signal.c:rb_ractor_id Unexecuted instantiation: thread.c:rb_ractor_id Unexecuted instantiation: variable.c:rb_ractor_id Line | Count | Source | 264 | 9 | { | 265 | 9 | return r->pub.id; | 266 | 9 | } |
Unexecuted instantiation: vm_dump.c:rb_ractor_id Unexecuted instantiation: vm_sync.c:rb_ractor_id Unexecuted instantiation: vm_trace.c:rb_ractor_id Unexecuted instantiation: cont.c:rb_ractor_id Unexecuted instantiation: debug.c:rb_ractor_id |
267 | | |
268 | | static inline void |
269 | | rb_ractor_targeted_hooks_incr(rb_ractor_t *cr) |
270 | 0 | { |
271 | 0 | cr->pub.targeted_hooks_cnt++; |
272 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: gc.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: iseq.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: load.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: proc.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: process.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: ractor.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: re.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: signal.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: thread.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: variable.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: vm.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: vm_dump.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: vm_sync.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: vm_trace.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: cont.c:rb_ractor_targeted_hooks_incr Unexecuted instantiation: debug.c:rb_ractor_targeted_hooks_incr |
273 | | |
274 | | static inline void |
275 | | rb_ractor_targeted_hooks_decr(rb_ractor_t *cr) |
276 | 0 | { |
277 | 0 | RUBY_ASSERT(cr->pub.targeted_hooks_cnt > 0); |
278 | 0 | cr->pub.targeted_hooks_cnt--; |
279 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: gc.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: iseq.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: load.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: proc.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: process.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: ractor.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: re.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: signal.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: thread.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: variable.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: vm.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: vm_dump.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: vm_sync.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: vm_trace.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: cont.c:rb_ractor_targeted_hooks_decr Unexecuted instantiation: debug.c:rb_ractor_targeted_hooks_decr |
280 | | |
281 | | static inline unsigned int |
282 | | rb_ractor_targeted_hooks_cnt(rb_ractor_t *cr) |
283 | 0 | { |
284 | 0 | return cr->pub.targeted_hooks_cnt; |
285 | 0 | } Unexecuted instantiation: eval.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: gc.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: iseq.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: load.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: proc.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: process.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: ractor.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: re.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: signal.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: thread.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: variable.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: vm.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: vm_dump.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: vm_sync.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: vm_trace.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: cont.c:rb_ractor_targeted_hooks_cnt Unexecuted instantiation: debug.c:rb_ractor_targeted_hooks_cnt |
286 | | |
287 | | #if RACTOR_CHECK_MODE > 0 |
288 | | # define RACTOR_BELONGING_ID(obj) (*(uint32_t *)(((uintptr_t)(obj)) + rb_gc_obj_slot_size(obj))) |
289 | | |
290 | | uint32_t rb_ractor_current_id(void); |
291 | | |
292 | | static inline void |
293 | | rb_ractor_setup_belonging_to(VALUE obj, uint32_t rid) |
294 | | { |
295 | | RACTOR_BELONGING_ID(obj) = rid; |
296 | | } |
297 | | |
298 | | static inline uint32_t |
299 | | rb_ractor_belonging(VALUE obj) |
300 | | { |
301 | | if (SPECIAL_CONST_P(obj) || RB_OBJ_SHAREABLE_P(obj)) { |
302 | | return 0; |
303 | | } |
304 | | else { |
305 | | return RACTOR_BELONGING_ID(obj); |
306 | | } |
307 | | } |
308 | | |
309 | | extern bool rb_ractor_ignore_belonging_flag; |
310 | | |
311 | | static inline VALUE |
312 | | rb_ractor_confirm_belonging(VALUE obj) |
313 | | { |
314 | | if (rb_ractor_ignore_belonging_flag) return obj; |
315 | | |
316 | | uint32_t id = rb_ractor_belonging(obj); |
317 | | |
318 | | if (id == 0) { |
319 | | if (UNLIKELY(!rb_ractor_shareable_p(obj))) { |
320 | | rp(obj); |
321 | | rb_bug("id == 0 but not shareable"); |
322 | | } |
323 | | } |
324 | | else if (UNLIKELY(id != rb_ractor_current_id())) { |
325 | | if (rb_ractor_shareable_p(obj)) { |
326 | | // ok |
327 | | } |
328 | | else { |
329 | | rp(obj); |
330 | | rb_bug("rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u", id, rb_ractor_current_id()); |
331 | | } |
332 | | } |
333 | | return obj; |
334 | | } |
335 | | |
336 | | static inline void |
337 | | rb_ractor_ignore_belonging(bool flag) |
338 | | { |
339 | | rb_ractor_ignore_belonging_flag = flag; |
340 | | } |
341 | | |
342 | | #else |
343 | 0 | #define rb_ractor_confirm_belonging(obj) obj |
344 | 0 | #define rb_ractor_ignore_belonging(flag) (0) |
345 | | #endif |