7#ifndef RACTOR_CHECK_MODE
8#define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
11enum rb_ractor_basket_type {
23 enum rb_ractor_basket_type type;
34 unsigned int reserved_cnt;
43enum rb_ractor_wait_status {
45 wait_receiving = 0x01,
51enum rb_ractor_wakeup_status {
63 rb_nativethread_lock_t lock;
64#if RACTOR_CHECK_MODE > 0
67 rb_nativethread_cond_t cond;
73 bool incoming_port_closed;
74 bool outgoing_port_closed;
77 enum rb_ractor_wait_status status;
78 enum rb_ractor_wakeup_status wakeup_status;
109 VALUE receiving_mutex;
113 rb_nativethread_cond_t barrier_wait_cond;
117 struct ccan_list_head set;
119 unsigned int blocking_cnt;
120 unsigned int sleeper;
125 VALUE thgroup_default;
130 enum ractor_status status_;
132 struct ccan_list_node vmlr_node;
150 void (*mark_func)(
VALUE v,
void *data);
171int rb_ractor_living_thread_num(
const rb_ractor_t *);
173bool rb_ractor_p(
VALUE rv);
178void rb_ractor_blocking_threads_inc(
rb_ractor_t *r,
const char *file,
int line);
179void rb_ractor_blocking_threads_dec(
rb_ractor_t *r,
const char *file,
int line);
181void rb_ractor_vm_barrier_interrupt_running_thread(
rb_ractor_t *r);
182void rb_ractor_terminate_interrupt_main_thread(
rb_ractor_t *r);
183void rb_ractor_terminate_all(
void);
184bool rb_ractor_main_p_(
void);
185void rb_ractor_finish_marking(
void);
190RUBY_SYMBOL_EXPORT_BEGIN
191bool rb_ractor_shareable_p_continue(
VALUE obj);
197RUBY_SYMBOL_EXPORT_END
200rb_ractor_main_p(
void)
202 if (ruby_single_main_ractor) {
206 return rb_ractor_main_p_();
211rb_ractor_status_p(
rb_ractor_t *r,
enum ractor_status status)
213 return r->status_ == status;
219 r->threads.sleeper++;
225 r->threads.sleeper--;
231 r->threads.sleeper = 0;
237 return r->threads.sleeper;
243 if (cr->threads.running_ec != th->ec) {
245 ruby_debug_printf(
"rb_ractor_thread_switch ec:%p->%p\n",
246 (
void *)cr->threads.running_ec, (
void *)th->ec);
253 if (cr->threads.running_ec != th->ec) {
254 th->running_time_us = 0;
257 cr->threads.running_ec = th->ec;
259 VM_ASSERT(cr == GET_RACTOR());
262#define rb_ractor_set_current_ec(cr, ec) rb_ractor_set_current_ec_(cr, ec, __FILE__, __LINE__)
267#ifdef RB_THREAD_LOCAL_SPECIFIER
269 rb_current_ec_set(ec);
271 ruby_current_ec = ec;
274 native_tls_set(ruby_current_ec_key, ec);
276 RUBY_DEBUG_LOG2(file, line,
"ec:%p->%p", (
void *)cr->threads.running_ec, (
void *)ec);
277 VM_ASSERT(cr->threads.running_ec != ec);
278 cr->threads.running_ec = ec;
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);
284static inline uint32_t
290#if RACTOR_CHECK_MODE > 0
291# define RACTOR_BELONGING_ID(obj) (*(uint32_t *)(((uintptr_t)(obj)) + rb_gc_obj_slot_size(obj)))
293uint32_t rb_ractor_current_id(
void);
296rb_ractor_setup_belonging_to(
VALUE obj, uint32_t rid)
298 RACTOR_BELONGING_ID(obj) = rid;
302rb_ractor_setup_belonging(
VALUE obj)
304 rb_ractor_setup_belonging_to(obj, rb_ractor_current_id());
307static inline uint32_t
308rb_ractor_belonging(
VALUE obj)
314 return RACTOR_BELONGING_ID(obj);
319rb_ractor_confirm_belonging(
VALUE obj)
321 uint32_t
id = rb_ractor_belonging(obj);
326 rb_bug(
"id == 0 but not shareable");
329 else if (UNLIKELY(
id != rb_ractor_current_id())) {
335 rb_bug(
"rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u",
id, rb_ractor_current_id());
341#define rb_ractor_confirm_belonging(obj) obj
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
static bool rb_ractor_shareable_p(VALUE obj)
Queries if multiple Ractors can share the passed object or not.
#define RB_OBJ_SHAREABLE_P(obj)
Queries if the passed object has previously classified as shareable or not.
uintptr_t VALUE
Type that represents a Ruby object.