1 #include "internal/gc.h"
8 #ifndef RACTOR_CHECK_MODE
9 #define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
12 enum rb_ractor_basket_type {
29 basket_type_take_basket,
43 enum rb_ractor_basket_type e;
64 return b->type.e ==
type;
70 return basket_type_p(b, basket_type_none);
79 unsigned int reserved_cnt;
82 enum rb_ractor_wait_status {
84 wait_receiving = 0x01,
90 enum rb_ractor_wakeup_status {
102 rb_nativethread_lock_t lock;
103 #if RACTOR_CHECK_MODE > 0
107 bool incoming_port_closed;
108 bool outgoing_port_closed;
120 enum rb_ractor_wait_status status;
121 enum rb_ractor_wakeup_status wakeup_status;
125 #ifndef RUBY_THREAD_PTHREAD_H
126 rb_nativethread_cond_t cond;
155 VALUE receiving_mutex;
158 rb_nativethread_cond_t barrier_wait_cond;
162 struct ccan_list_head set;
164 unsigned int blocking_cnt;
165 unsigned int sleeper;
170 VALUE thgroup_default;
175 enum ractor_status status_;
177 struct ccan_list_node vmlr_node;
210 int rb_ractor_living_thread_num(
const rb_ractor_t *);
211 VALUE rb_ractor_thread_list(
void);
212 bool rb_ractor_p(
VALUE rv);
214 void rb_ractor_living_threads_init(
rb_ractor_t *r);
217 void rb_ractor_blocking_threads_inc(
rb_ractor_t *r,
const char *file,
int line);
218 void rb_ractor_blocking_threads_dec(
rb_ractor_t *r,
const char *file,
int line);
220 void rb_ractor_vm_barrier_interrupt_running_thread(
rb_ractor_t *r);
221 void rb_ractor_terminate_interrupt_main_thread(
rb_ractor_t *r);
222 void rb_ractor_terminate_all(
void);
223 bool rb_ractor_main_p_(
void);
230 RUBY_SYMBOL_EXPORT_BEGIN
231 void rb_ractor_finish_marking(
void);
233 bool rb_ractor_shareable_p_continue(
VALUE obj);
239 RUBY_SYMBOL_EXPORT_END
242 rb_ractor_main_p(
void)
244 if (ruby_single_main_ractor) {
248 return rb_ractor_main_p_();
253 rb_ractor_status_p(
rb_ractor_t *r,
enum ractor_status status)
255 return r->status_ == status;
261 r->threads.sleeper++;
267 r->threads.sleeper--;
273 r->threads.sleeper = 0;
279 return r->threads.sleeper;
285 RUBY_DEBUG_LOG(
"th:%d->%u%s",
286 cr->threads.running_ec ? (
int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1,
287 rb_th_serial(th), cr->threads.running_ec == th->ec ?
" (same)" :
"");
289 if (cr->threads.running_ec != th->ec) {
291 ruby_debug_printf(
"rb_ractor_thread_switch ec:%p->%p\n",
292 (
void *)cr->threads.running_ec, (
void *)th->ec);
299 if (cr->threads.running_ec != th->ec) {
300 th->running_time_us = 0;
303 cr->threads.running_ec = th->ec;
305 VM_ASSERT(cr == GET_RACTOR());
308 #define rb_ractor_set_current_ec(cr, ec) rb_ractor_set_current_ec_(cr, ec, __FILE__, __LINE__)
313 #ifdef RB_THREAD_LOCAL_SPECIFIER
316 rb_current_ec_set(ec);
318 ruby_current_ec = ec;
322 native_tls_set(ruby_current_ec_key, ec);
324 RUBY_DEBUG_LOG2(file, line,
"ec:%p->%p", (
void *)cr->threads.running_ec, (
void *)ec);
325 VM_ASSERT(ec == NULL || cr->threads.running_ec != ec);
326 cr->threads.running_ec = ec;
329 void rb_vm_ractor_blocking_cnt_inc(
rb_vm_t *vm,
rb_ractor_t *cr,
const char *file,
int line);
330 void rb_vm_ractor_blocking_cnt_dec(
rb_vm_t *vm,
rb_ractor_t *cr,
const char *file,
int line);
332 static inline uint32_t
338 #if RACTOR_CHECK_MODE > 0
339 # define RACTOR_BELONGING_ID(obj) (*(uint32_t *)(((uintptr_t)(obj)) + rb_gc_obj_slot_size(obj)))
341 uint32_t rb_ractor_current_id(
void);
344 rb_ractor_setup_belonging_to(
VALUE obj, uint32_t rid)
346 RACTOR_BELONGING_ID(obj) = rid;
349 static inline uint32_t
350 rb_ractor_belonging(
VALUE obj)
356 return RACTOR_BELONGING_ID(obj);
361 rb_ractor_confirm_belonging(
VALUE obj)
363 uint32_t
id = rb_ractor_belonging(obj);
368 rb_bug(
"id == 0 but not shareable");
371 else if (UNLIKELY(
id != rb_ractor_current_id())) {
377 rb_bug(
"rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u",
id, rb_ractor_current_id());
383 #define rb_ractor_confirm_belonging(obj) obj
std::atomic< unsigned > rb_atomic_t
Type that is eligible for atomic operations.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
int len
Length of the buffer.
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.
VALUE type(ANYARGS)
ANYARGS-ed function type.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.