summaryrefslogtreecommitdiff
path: root/vm_core.h
diff options
context:
space:
mode:
Diffstat (limited to 'vm_core.h')
-rw-r--r--vm_core.h119
1 files changed, 72 insertions, 47 deletions
diff --git a/vm_core.h b/vm_core.h
index bf04288f56..70714420f2 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -419,6 +419,7 @@ struct rb_iseq_constant_body {
char catch_except_p; /* If a frame of this ISeq may catch exception, set TRUE */
bool builtin_inline_p; // This ISeq's builtin func is safe to be inlined by MJIT
+ char access_outer_variables;
#if USE_MJIT
/* The following fields are MJIT related info. */
@@ -554,12 +555,30 @@ typedef const struct rb_builtin_function *RB_BUILTIN;
typedef struct rb_vm_struct {
VALUE self;
- rb_global_vm_lock_t gvl;
+ struct {
+ struct list_head set;
+ unsigned int cnt;
+ unsigned int blocking_cnt;
- struct rb_thread_struct *main_thread;
+ struct rb_ractor_struct *main_ractor;
+ struct rb_thread_struct *main_thread; // == vm->ractor.main_ractor->threads.main
- /* persists across uncontended GVL release/acquire for time slice */
- const struct rb_thread_struct *running_thread;
+ struct {
+ // monitor
+ rb_nativethread_lock_t lock;
+ struct rb_ractor_struct *lock_owner;
+ unsigned int lock_rec;
+
+ // barrier
+ bool barrier_waiting;
+ unsigned int barrier_cnt;
+ rb_nativethread_cond_t barrier_cond;
+
+ // join at exit
+ rb_nativethread_cond_t terminate_cond;
+ bool terminate_waiting;
+ } sync;
+ } ractor;
#ifdef USE_SIGALTSTACK
void *main_altstack;
@@ -570,9 +589,6 @@ typedef struct rb_vm_struct {
struct list_head waiting_pids; /* PID > 0: <=> struct waitpid_state */
struct list_head waiting_grps; /* PID <= 0: <=> struct waitpid_state */
struct list_head waiting_fds; /* <=> struct waiting_fd */
- struct list_head living_threads;
- VALUE thgroup_default;
- int living_thread_num;
/* set in single-threaded processes only: */
volatile int ubf_async_safe;
@@ -580,9 +596,7 @@ typedef struct rb_vm_struct {
unsigned int running: 1;
unsigned int thread_abort_on_exception: 1;
unsigned int thread_report_on_exception: 1;
-
unsigned int safe_level_: 1;
- int sleeper;
/* object management */
VALUE mark_object_ary;
@@ -890,9 +904,12 @@ void rb_ec_initialize_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t
// @param ec the execution context to update.
void rb_ec_clear_vm_stack(rb_execution_context_t *ec);
+typedef struct rb_ractor_struct rb_ractor_t;
+
typedef struct rb_thread_struct {
- struct list_node vmlt_node;
+ struct list_node lt_node; // managed by a ractor
VALUE self;
+ rb_ractor_t *ractor;
rb_vm_t *vm;
rb_execution_context_t *ec;
@@ -955,9 +972,10 @@ typedef struct rb_thread_struct {
} func;
} invoke_arg;
- enum {
+ enum thread_invoke_type {
thread_invoke_type_none = 0,
thread_invoke_type_proc,
+ thread_invoke_type_ractor_proc,
thread_invoke_type_func
} invoke_type;
@@ -1039,8 +1057,12 @@ typedef struct {
const struct rb_block block;
unsigned int is_from_method: 1; /* bool */
unsigned int is_lambda: 1; /* bool */
+ unsigned int is_isolated: 1; /* bool */
} rb_proc_t;
+VALUE rb_proc_isolate(VALUE self);
+VALUE rb_proc_isolate_bang(VALUE self);
+
typedef struct {
VALUE flags; /* imemo header */
rb_iseq_t *iseq;
@@ -1628,11 +1650,12 @@ VALUE rb_vm_env_local_variables(const rb_env_t *env);
const rb_env_t *rb_vm_env_prev_env(const rb_env_t *env);
const VALUE *rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const ID *dynvars);
void rb_vm_inc_const_missing_count(void);
-void rb_vm_gvl_destroy(rb_vm_t *vm);
VALUE rb_vm_call_kw(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc,
const VALUE *argv, const rb_callable_method_entry_t *me, int kw_splat);
MJIT_STATIC void rb_vm_pop_frame(rb_execution_context_t *ec);
+void rb_gvl_destroy(rb_global_vm_lock_t *gvl);
+
void rb_thread_start_timer_thread(void);
void rb_thread_stop_timer_thread(void);
void rb_thread_reset_timer_thread(void);
@@ -1645,22 +1668,7 @@ rb_vm_living_threads_init(rb_vm_t *vm)
list_head_init(&vm->waiting_pids);
list_head_init(&vm->workqueue);
list_head_init(&vm->waiting_grps);
- list_head_init(&vm->living_threads);
- vm->living_thread_num = 0;
-}
-
-static inline void
-rb_vm_living_threads_insert(rb_vm_t *vm, rb_thread_t *th)
-{
- list_add_tail(&vm->living_threads, &th->vmlt_node);
- vm->living_thread_num++;
-}
-
-static inline void
-rb_vm_living_threads_remove(rb_vm_t *vm, rb_thread_t *th)
-{
- list_del(&th->vmlt_node);
- vm->living_thread_num--;
+ list_head_init(&vm->ractor.set);
}
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
@@ -1700,20 +1708,24 @@ MJIT_STATIC const rb_callable_method_entry_t *rb_vm_frame_method_entry(const rb_
VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, enum ruby_tag_type *stateptr);
+rb_execution_context_t *rb_vm_main_ractor_ec(rb_vm_t *vm); // ractor.c
+
/* for thread */
#if RUBY_VM_THREAD_MODEL == 2
RUBY_SYMBOL_EXPORT_BEGIN
RUBY_EXTERN rb_vm_t *ruby_current_vm_ptr;
-RUBY_EXTERN rb_execution_context_t *ruby_current_execution_context_ptr;
RUBY_EXTERN rb_event_flag_t ruby_vm_event_flags;
RUBY_EXTERN rb_event_flag_t ruby_vm_event_enabled_global_flags;
RUBY_EXTERN unsigned int ruby_vm_event_local_num;
+RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
+
RUBY_SYMBOL_EXPORT_END
#define GET_VM() rb_current_vm()
+#define GET_RACTOR() rb_current_ractor()
#define GET_THREAD() rb_current_thread()
#define GET_EC() rb_current_execution_context()
@@ -1723,6 +1735,19 @@ rb_ec_thread_ptr(const rb_execution_context_t *ec)
return ec->thread_ptr;
}
+static inline rb_ractor_t *
+rb_ec_ractor_ptr(const rb_execution_context_t *ec)
+{
+ const rb_thread_t *th = rb_ec_thread_ptr(ec);
+ if (th) {
+ VM_ASSERT(th->ractor != NULL);
+ return th->ractor;
+ }
+ else {
+ return NULL;
+ }
+}
+
static inline rb_vm_t *
rb_ec_vm_ptr(const rb_execution_context_t *ec)
{
@@ -1738,7 +1763,9 @@ rb_ec_vm_ptr(const rb_execution_context_t *ec)
static inline rb_execution_context_t *
rb_current_execution_context(void)
{
- return ruby_current_execution_context_ptr;
+ rb_execution_context_t *ec = native_tls_get(ruby_current_ec_key);
+ VM_ASSERT(ec != NULL);
+ return ec;
}
static inline rb_thread_t *
@@ -1748,31 +1775,25 @@ rb_current_thread(void)
return rb_ec_thread_ptr(ec);
}
+static inline rb_ractor_t *
+rb_current_ractor(void)
+{
+ const rb_execution_context_t *ec = GET_EC();
+ return rb_ec_ractor_ptr(ec);
+}
+
static inline rb_vm_t *
rb_current_vm(void)
{
+#if 0 // TODO: reconsider the assertions
VM_ASSERT(ruby_current_vm_ptr == NULL ||
ruby_current_execution_context_ptr == NULL ||
rb_ec_thread_ptr(GET_EC()) == NULL ||
rb_ec_thread_ptr(GET_EC())->status == THREAD_KILLED ||
rb_ec_vm_ptr(GET_EC()) == ruby_current_vm_ptr);
- return ruby_current_vm_ptr;
-}
-
-static inline void
-rb_thread_set_current_raw(const rb_thread_t *th)
-{
- ruby_current_execution_context_ptr = th->ec;
-}
+#endif
-static inline void
-rb_thread_set_current(rb_thread_t *th)
-{
- if (th->vm->running_thread != th) {
- th->running_time_us = 0;
- }
- rb_thread_set_current_raw(th);
- th->vm->running_thread = th;
+ return ruby_current_vm_ptr;
}
#else
@@ -1783,13 +1804,17 @@ enum {
TIMER_INTERRUPT_MASK = 0x01,
PENDING_INTERRUPT_MASK = 0x02,
POSTPONED_JOB_INTERRUPT_MASK = 0x04,
- TRAP_INTERRUPT_MASK = 0x08
+ TRAP_INTERRUPT_MASK = 0x08,
+ TERMINATE_INTERRUPT_MASK = 0x10,
+ VM_BARRIER_INTERRUPT_MASK = 0x20,
};
#define RUBY_VM_SET_TIMER_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TIMER_INTERRUPT_MASK)
#define RUBY_VM_SET_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, PENDING_INTERRUPT_MASK)
#define RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, POSTPONED_JOB_INTERRUPT_MASK)
#define RUBY_VM_SET_TRAP_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TRAP_INTERRUPT_MASK)
+#define RUBY_VM_SET_TERMINATE_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TERMINATE_INTERRUPT_MASK)
+#define RUBY_VM_SET_VM_BARRIER_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, VM_BARRIER_INTERRUPT_MASK)
#define RUBY_VM_INTERRUPTED(ec) ((ec)->interrupt_flag & ~(ec)->interrupt_mask & \
(PENDING_INTERRUPT_MASK|TRAP_INTERRUPT_MASK))
#define RUBY_VM_INTERRUPTED_ANY(ec) ((ec)->interrupt_flag & ~(ec)->interrupt_mask)