Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)
ractor_core.h
Go to the documentation of this file.
1#include "ruby/ruby.h"
2#include "ruby/ractor.h"
3#include "vm_core.h"
4#include "id_table.h"
5#include "vm_debug.h"
6
7#ifndef RACTOR_CHECK_MODE
8#define RACTOR_CHECK_MODE (0 || VM_CHECK_MODE || RUBY_DEBUG)
9#endif
10
19};
20
26};
27
30 int start;
31 int cnt;
32 int size;
33 unsigned int serial;
34 unsigned int reserved_cnt;
35};
36
38 int cnt;
39 int size;
41};
42
44 // ractor lock
45 rb_nativethread_lock_t lock;
46#if RACTOR_CHECK_MODE > 0
47 VALUE locked_by;
48#endif
50
51 // communication
54
57
58 struct ractor_wait {
60 wait_none = 0x00,
66
76
80};
81
84
88
89 // vm wide barrier synchronization
91
92 // thread management
93 struct {
94 struct list_head set;
95 unsigned int cnt;
96 unsigned int blocking_cnt;
97 unsigned int sleeper;
103
106
107 // created
108 // | ready to run
109 // ====================== inserted to vm->ractor
110 // v
111 // blocking <---+ all threads are blocking
112 // | |
113 // v |
114 // running -----+
115 // | all threads are terminated.
116 // ====================== removed from vm->ractor
117 // v
118 // terminated
119 //
120 // status is protected by VM lock (global state)
121
128
129 struct list_node vmlr_node;
130
131 // ractor local data
132
135
141
143
144 // gc.c rb_objspace_reachable_objects_from
146 void *data;
147 void (*mark_func)(VALUE v, void *data);
148 } *mfd;
149}; // rb_ractor_t is defined in vm_core.h
150
151
152static inline VALUE
153rb_ractor_self(const rb_ractor_t *r)
154{
155 return r->pub.self;
156}
157
159void rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *main_ractor, rb_thread_t *main_thread);
165
166VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc); // defined in thread.c
167
171
175void rb_ractor_blocking_threads_inc(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG
176void rb_ractor_blocking_threads_dec(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG
177
180void rb_ractor_terminate_all(void);
181bool rb_ractor_main_p_(void);
182void rb_ractor_finish_marking(void);
184
186
187RUBY_SYMBOL_EXPORT_BEGIN
189
190// THIS FUNCTION SHOULD NOT CALL WHILE INCREMENTAL MARKING!!
191// This function is for T_DATA::free_func
193
194RUBY_SYMBOL_EXPORT_END
195
196static inline bool
197rb_ractor_main_p(void)
198{
200 return true;
201 }
202 else {
203 return rb_ractor_main_p_();
204 }
205}
206
207static inline bool
208rb_ractor_status_p(rb_ractor_t *r, enum ractor_status status)
209{
210 return r->status_ == status;
211}
212
213static inline void
214rb_ractor_sleeper_threads_inc(rb_ractor_t *r)
215{
216 r->threads.sleeper++;
217}
218
219static inline void
220rb_ractor_sleeper_threads_dec(rb_ractor_t *r)
221{
222 r->threads.sleeper--;
223}
224
225static inline void
226rb_ractor_sleeper_threads_clear(rb_ractor_t *r)
227{
228 r->threads.sleeper = 0;
229}
230
231static inline int
232rb_ractor_sleeper_thread_num(rb_ractor_t *r)
233{
234 return r->threads.sleeper;
235}
236
237static inline void
238rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th)
239{
240 if (cr->threads.running_ec != th->ec) {
241 if (0) fprintf(stderr, "rb_ractor_thread_switch ec:%p->%p\n",
242 (void *)cr->threads.running_ec, (void *)th->ec);
243 }
244 else {
245 return;
246 }
247
248 if (cr->threads.running_ec != th->ec) {
249 th->running_time_us = 0;
250 }
251
252 cr->threads.running_ec = th->ec;
253
254 VM_ASSERT(cr == GET_RACTOR());
255}
256
257static inline void
258rb_ractor_set_current_ec(rb_ractor_t *cr, rb_execution_context_t *ec)
259{
260#ifdef RB_THREAD_LOCAL_SPECIFIER
261 #if __APPLE__
262 rb_current_ec_set(ec);
263 #else
264 ruby_current_ec = ec;
265 #endif
266#else
267 native_tls_set(ruby_current_ec_key, ec);
268#endif
269
270 if (cr->threads.running_ec != ec) {
271 if (0) fprintf(stderr, "rb_ractor_set_current_ec ec:%p->%p\n",
272 (void *)cr->threads.running_ec, (void *)ec);
273 }
274 else {
275 VM_ASSERT(0); // should be different
276 }
277
278 cr->threads.running_ec = ec;
279}
280
281void rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
282void rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
283
284static inline uint32_t
285rb_ractor_id(const rb_ractor_t *r)
286{
287 return r->pub.id;
288}
289
290#if RACTOR_CHECK_MODE > 0
291uint32_t rb_ractor_current_id(void);
292
293static inline void
294rb_ractor_setup_belonging_to(VALUE obj, uint32_t rid)
295{
296 VALUE flags = RBASIC(obj)->flags & 0xffffffff; // 4B
297 RBASIC(obj)->flags = flags | ((VALUE)rid << 32);
298}
299
300static inline void
301rb_ractor_setup_belonging(VALUE obj)
302{
303 rb_ractor_setup_belonging_to(obj, rb_ractor_current_id());
304}
305
306static inline uint32_t
307rb_ractor_belonging(VALUE obj)
308{
309 if (SPECIAL_CONST_P(obj) || RB_OBJ_SHAREABLE_P(obj)) {
310 return 0;
311 }
312 else {
313 return RBASIC(obj)->flags >> 32;
314 }
315}
316
317static inline VALUE
319{
320 uint32_t id = rb_ractor_belonging(obj);
321
322 if (id == 0) {
323 if (UNLIKELY(!rb_ractor_shareable_p(obj))) {
324 rp(obj);
325 rb_bug("id == 0 but not shareable");
326 }
327 }
328 else if (UNLIKELY(id != rb_ractor_current_id())) {
329 if (rb_ractor_shareable_p(obj)) {
330 // ok
331 }
332 else {
333 rp(obj);
334 rb_bug("rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u", id, rb_ractor_current_id());
335 }
336 }
337 return obj;
338}
339#else
340#define rb_ractor_confirm_belonging(obj) obj
341#endif
struct RIMemo * ptr
Definition: debug.c:88
struct @77 g
uint8_t len
Definition: escape.c:17
#define UNLIKELY(x)
Definition: ffi_common.h:126
void rb_bug(const char *fmt,...)
Definition: error.c:768
#define rp(obj)
Definition: internal.h:95
const char * name
Definition: nkf.c:208
#define RB_OBJ_SHAREABLE_P(obj)
Definition: ractor.h:50
rb_ractor_t * rb_ractor_main_alloc(void)
Definition: ractor.c:1508
void rb_ractor_local_storage_delkey(rb_ractor_local_key_t key)
Definition: ractor.c:3112
VALUE rb_ractor_ensure_shareable(VALUE obj, VALUE name)
Definition: ractor.c:2518
rb_ractor_basket_type
Definition: ractor_core.h:11
@ basket_type_will
Definition: ractor_core.h:16
@ basket_type_copy
Definition: ractor_core.h:14
@ basket_type_deleted
Definition: ractor_core.h:17
@ basket_type_reserved
Definition: ractor_core.h:18
@ basket_type_none
Definition: ractor_core.h:12
@ basket_type_ref
Definition: ractor_core.h:13
@ basket_type_move
Definition: ractor_core.h:15
void rb_ractor_teardown(rb_execution_context_t *ec)
Definition: ractor.c:1652
void rb_ractor_terminate_all(void)
Definition: ractor.c:1946
void rb_ractor_living_threads_insert(rb_ractor_t *r, rb_thread_t *th)
Definition: ractor.c:1760
void rb_ractor_blocking_threads_dec(rb_ractor_t *r, const char *file, int line)
Definition: ractor.c:1870
VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc)
Definition: thread.c:1130
void rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line)
Definition: ractor.c:1798
void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th)
void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE args)
Definition: ractor.c:1690
void rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *g, int len, VALUE *ptr)
Definition: ractor.c:1682
void rb_ractor_blocking_threads_inc(rb_ractor_t *r, const char *file, int line)
Definition: ractor.c:1858
bool rb_ractor_main_p_(void)
Definition: ractor.c:1699
void rb_ractor_finish_marking(void)
Definition: ractor.c:3215
void rb_ractor_living_threads_remove(rb_ractor_t *r, rb_thread_t *th)
Definition: ractor.c:1838
rb_global_vm_lock_t * rb_ractor_gvl(rb_ractor_t *)
Definition: ractor.c:1715
void rb_ractor_atexit_exception(rb_execution_context_t *ec)
Definition: ractor.c:1675
void rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r)
Definition: ractor.c:1892
void rb_ractor_atexit(rb_execution_context_t *ec, VALUE result)
Definition: ractor.c:1668
VALUE rb_ractor_thread_list(rb_ractor_t *r)
Definition: ractor.c:1727
void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r)
Definition: ractor.c:1911
void rb_ractor_living_threads_init(rb_ractor_t *r)
Definition: ractor.c:1546
#define rb_ractor_confirm_belonging(obj)
Definition: ractor_core.h:340
bool rb_ractor_shareable_p_continue(VALUE obj)
Definition: ractor.c:2550
void rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *main_ractor, rb_thread_t *main_thread)
Definition: ractor.c:1581
int rb_ractor_living_thread_num(const rb_ractor_t *)
Definition: ractor.c:1721
void rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line)
Definition: ractor.c:1790
#define RBASIC(obj)
Definition: rbasic.h:34
unsigned int uint32_t
Definition: sha2.h:101
#define SPECIAL_CONST_P
Definition: gzappend.c:170
enum rb_ractor_basket_type type
Definition: ractor_core.h:23
uint32_t id
Definition: vm_core.h:1990
VALUE self
Definition: vm_core.h:1989
struct rb_ractor_basket * baskets
Definition: ractor_core.h:29
unsigned int serial
Definition: ractor_core.h:33
unsigned int reserved_cnt
Definition: ractor_core.h:34
void(* mark_func)(VALUE v, void *data)
Definition: ractor_core.h:147
unsigned int sleeper
Definition: ractor_core.h:97
rb_nativethread_cond_t barrier_wait_cond
Definition: ractor_core.h:90
rb_global_vm_lock_t gvl
Definition: ractor_core.h:98
struct list_node vmlr_node
Definition: ractor_core.h:129
rb_thread_t * main
Definition: ractor_core.h:100
unsigned int blocking_cnt
Definition: ractor_core.h:96
unsigned int cnt
Definition: ractor_core.h:95
rb_execution_context_t * running_ec
Definition: ractor_core.h:99
st_table * local_storage
Definition: ractor_core.h:133
struct rb_ractor_struct::@141 threads
enum rb_ractor_struct::ractor_status status_
struct rb_ractor_sync sync
Definition: ractor_core.h:85
struct rb_ractor_pub pub
Definition: ractor_core.h:83
struct rb_ractor_struct::gc_mark_func_data_struct * mfd
VALUE receiving_mutex
Definition: ractor_core.h:86
struct rb_id_table * idkey_local_storage
Definition: ractor_core.h:134
rb_ractor_newobj_cache_t newobj_cache
Definition: ractor_core.h:142
struct rb_ractor_basket taken_basket
Definition: ractor_core.h:78
enum rb_ractor_sync::ractor_wait::ractor_wait_status status
enum rb_ractor_sync::ractor_wait::ractor_wakeup_status wakeup_status
struct rb_ractor_basket yielded_basket
Definition: ractor_core.h:77
struct rb_ractor_waiting_list taking_ractors
Definition: ractor_core.h:53
struct rb_ractor_sync::ractor_wait wait
bool incoming_port_closed
Definition: ractor_core.h:55
struct rb_ractor_queue incoming_queue
Definition: ractor_core.h:52
rb_nativethread_cond_t cond
Definition: ractor_core.h:49
bool outgoing_port_closed
Definition: ractor_core.h:56
rb_nativethread_lock_t lock
Definition: ractor_core.h:45
rb_ractor_t ** ractors
Definition: ractor_core.h:40
rb_execution_context_t * ec
Definition: vm_core.h:941
uint32_t running_time_us
Definition: vm_core.h:964
Definition: st.h:79
RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct * ruby_current_ec
native_tls_key_t ruby_current_ec_key
Definition: vm.c:400
unsigned long VALUE
Definition: value.h:38
rb_ractor_t * ruby_single_main_ractor
Definition: vm.c:381
#define VM_ASSERT(expr)
Definition: vm_core.h:61