diff options
Diffstat (limited to 'ractor_core.h')
-rw-r--r-- | ractor_core.h | 112 |
1 files changed, 76 insertions, 36 deletions
diff --git a/ractor_core.h b/ractor_core.h index 968c12d291..fd3cba3a1f 100644 --- a/ractor_core.h +++ b/ractor_core.h @@ -1,3 +1,4 @@ +#include "internal/gc.h" #include "ruby/ruby.h" #include "ruby/ractor.h" #include "vm_core.h" @@ -9,22 +10,66 @@ #endif enum rb_ractor_basket_type { + // basket is empty basket_type_none, + + // value is available basket_type_ref, basket_type_copy, basket_type_move, basket_type_will, + + // basket should be deleted basket_type_deleted, + + // basket is reserved basket_type_reserved, + + // take_basket is available + basket_type_take_basket, + + // basket is keeping by yielding ractor + basket_type_yielding, +}; + +// per ractor taking configuration +struct rb_ractor_selector_take_config { + bool closed; + bool oneshot; }; struct rb_ractor_basket { - bool exception; - enum rb_ractor_basket_type type; - VALUE v; + union { + enum rb_ractor_basket_type e; + rb_atomic_t atomic; + } type; VALUE sender; + + union { + struct { + VALUE v; + bool exception; + } send; + + struct { + struct rb_ractor_basket *basket; + struct rb_ractor_selector_take_config *config; + } take; + } p; // payload }; +static inline bool +basket_type_p(struct rb_ractor_basket *b, enum rb_ractor_basket_type type) +{ + return b->type.e == type; +} + +static inline bool +basket_none_p(struct rb_ractor_basket *b) +{ + return basket_type_p(b, basket_type_none); +} + struct rb_ractor_queue { struct rb_ractor_basket *baskets; int start; @@ -34,12 +79,6 @@ struct rb_ractor_queue { unsigned int reserved_cnt; }; -struct rb_ractor_waiting_list { - int cnt; - int size; - rb_ractor_t **ractors; -}; - enum rb_ractor_wait_status { wait_none = 0x00, wait_receiving = 0x01, @@ -64,21 +103,28 @@ struct rb_ractor_sync { #if RACTOR_CHECK_MODE > 0 VALUE locked_by; #endif - rb_nativethread_cond_t cond; - - // communication - struct rb_ractor_queue incoming_queue; - struct rb_ractor_waiting_list taking_ractors; bool incoming_port_closed; bool outgoing_port_closed; + // All sent messages will be pushed into recv_queue + struct rb_ractor_queue recv_queue; + + // The following ractors waiting for the yielding by this ractor + struct rb_ractor_queue takers_queue; + + // Enabled if the ractor already terminated and not taken yet. + struct rb_ractor_basket will_basket; + struct ractor_wait { enum rb_ractor_wait_status status; enum rb_ractor_wakeup_status wakeup_status; - struct rb_ractor_basket yielded_basket; - struct rb_ractor_basket taken_basket; + rb_thread_t *waiting_thread; } wait; + +#ifndef RUBY_THREAD_PTHREAD_H + rb_nativethread_cond_t cond; +#endif }; // created @@ -107,7 +153,6 @@ struct rb_ractor_struct { struct rb_ractor_sync sync; VALUE receiving_mutex; - bool yield_atexit; // vm wide barrier synchronization rb_nativethread_cond_t barrier_wait_cond; @@ -142,13 +187,7 @@ struct rb_ractor_struct { VALUE verbose; VALUE debug; - rb_ractor_newobj_cache_t newobj_cache; - - // gc.c rb_objspace_reachable_objects_from - struct gc_mark_func_data_struct { - void *data; - void (*mark_func)(VALUE v, void *data); - } *mfd; + void *newobj_cache; }; // rb_ractor_t is defined in vm_core.h @@ -169,7 +208,7 @@ void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc); // defined in thread.c int rb_ractor_living_thread_num(const rb_ractor_t *); -VALUE rb_ractor_thread_list(rb_ractor_t *r); +VALUE rb_ractor_thread_list(void); bool rb_ractor_p(VALUE rv); void rb_ractor_living_threads_init(rb_ractor_t *r); @@ -182,12 +221,13 @@ void rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r); void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r); void rb_ractor_terminate_all(void); bool rb_ractor_main_p_(void); -void rb_ractor_finish_marking(void); void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th); VALUE rb_ractor_ensure_shareable(VALUE obj, VALUE name); RUBY_SYMBOL_EXPORT_BEGIN +void rb_ractor_finish_marking(void); + bool rb_ractor_shareable_p_continue(VALUE obj); // THIS FUNCTION SHOULD NOT CALL WHILE INCREMENTAL MARKING!! @@ -240,6 +280,10 @@ rb_ractor_sleeper_thread_num(rb_ractor_t *r) static inline void rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th) { + RUBY_DEBUG_LOG("th:%d->%u%s", + cr->threads.running_ec ? (int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1, + rb_th_serial(th), cr->threads.running_ec == th->ec ? " (same)" : ""); + if (cr->threads.running_ec != th->ec) { if (0) { ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n", @@ -265,16 +309,18 @@ static inline void rb_ractor_set_current_ec_(rb_ractor_t *cr, rb_execution_context_t *ec, const char *file, int line) { #ifdef RB_THREAD_LOCAL_SPECIFIER - #ifdef __APPLE__ + +# ifdef __APPLE__ rb_current_ec_set(ec); - #else +# else ruby_current_ec = ec; - #endif +# endif + #else native_tls_set(ruby_current_ec_key, ec); #endif RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec); - VM_ASSERT(cr->threads.running_ec != ec); + VM_ASSERT(ec == NULL || cr->threads.running_ec != ec); cr->threads.running_ec = ec; } @@ -298,12 +344,6 @@ rb_ractor_setup_belonging_to(VALUE obj, uint32_t rid) RACTOR_BELONGING_ID(obj) = rid; } -static inline void -rb_ractor_setup_belonging(VALUE obj) -{ - rb_ractor_setup_belonging_to(obj, rb_ractor_current_id()); -} - static inline uint32_t rb_ractor_belonging(VALUE obj) { |