Coverage Report

Created: 2026-03-31 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ruby/ractor_core.h
Line
Count
Source
1
#include "internal/gc.h"
2
#include "ruby/ruby.h"
3
#include "ruby/ractor.h"
4
#include "vm_core.h"
5
#include "id_table.h"
6
#include "vm_debug.h"
7
8
#ifndef RACTOR_CHECK_MODE
9
#define RACTOR_CHECK_MODE (VM_CHECK_MODE || RUBY_DEBUG) && (SIZEOF_UINT64_T == SIZEOF_VALUE)
10
#endif
11
12
// experimental flag because it is not sure it is the common pattern
13
0
#define RUBY_TYPED_FROZEN_SHAREABLE_NO_REC RUBY_FL_FINALIZE
14
15
struct rb_ractor_sync {
16
    // ractor lock
17
    rb_nativethread_lock_t lock;
18
19
#if RACTOR_CHECK_MODE > 0
20
    VALUE locked_by;
21
#endif
22
23
#ifndef RUBY_THREAD_PTHREAD_H
24
    rb_nativethread_cond_t wakeup_cond;
25
#endif
26
27
    // incoming messages
28
    struct ractor_queue *recv_queue;
29
30
    // waiting threads for receiving
31
    struct ccan_list_head waiters;
32
33
    // ports
34
    VALUE default_port_value;
35
    struct st_table *ports;
36
    size_t next_port_id;
37
38
    // monitors
39
    struct ccan_list_head monitors;
40
41
    // value
42
    rb_ractor_t *successor;
43
    VALUE legacy;
44
    bool legacy_exc;
45
};
46
47
// created
48
//   | ready to run
49
// ====================== inserted to vm->ractor
50
//   v
51
// blocking <---+ all threads are blocking
52
//   |          |
53
//   v          |
54
// running -----+
55
//   | all threads are terminated.
56
// ====================== removed from vm->ractor
57
//   v
58
// terminated
59
//
60
// status is protected by VM lock (global state)
61
enum ractor_status {
62
    ractor_created,
63
    ractor_running,
64
    ractor_blocking,
65
    ractor_terminated,
66
};
67
68
struct rb_ractor_struct {
69
    struct rb_ractor_pub pub;
70
    struct rb_ractor_sync sync;
71
72
    // thread management
73
    struct {
74
        struct ccan_list_head set;
75
        unsigned int cnt;
76
        unsigned int blocking_cnt;
77
        unsigned int sleeper;
78
        struct rb_thread_sched sched;
79
        rb_execution_context_t *running_ec;
80
        rb_thread_t *main;
81
    } threads;
82
83
    VALUE thgroup_default;
84
85
    VALUE name;
86
    VALUE loc;
87
88
    enum ractor_status status_;
89
90
    struct ccan_list_node vmlr_node;
91
92
    // ractor local data
93
94
    rb_serial_t next_ec_serial;
95
96
    st_table *local_storage;
97
    struct rb_id_table *idkey_local_storage;
98
    VALUE local_storage_store_lock;
99
100
    VALUE r_stdin;
101
    VALUE r_stdout;
102
    VALUE r_stderr;
103
    VALUE verbose;
104
    VALUE debug;
105
106
    bool malloc_gc_disabled;
107
    bool main_ractor;
108
    void *newobj_cache;
109
}; // rb_ractor_t is defined in vm_core.h
110
111
enum ractor_wakeup_status {
112
    wakeup_none,
113
    wakeup_by_send,
114
    wakeup_by_interrupt,
115
    // wakeup_by_close,
116
};
117
118
struct ractor_waiter {
119
    enum ractor_wakeup_status wakeup_status;
120
    rb_thread_t *th;
121
    struct ccan_list_node node;
122
    rb_atomic_t event_serial;
123
};
124
125
static inline VALUE
126
rb_ractor_self(const rb_ractor_t *r)
127
91.0k
{
128
91.0k
    return r->pub.self;
129
91.0k
}
Unexecuted instantiation: eval.c:rb_ractor_self
Unexecuted instantiation: gc.c:rb_ractor_self
Unexecuted instantiation: iseq.c:rb_ractor_self
Unexecuted instantiation: load.c:rb_ractor_self
Unexecuted instantiation: proc.c:rb_ractor_self
Unexecuted instantiation: process.c:rb_ractor_self
Unexecuted instantiation: ractor.c:rb_ractor_self
Unexecuted instantiation: re.c:rb_ractor_self
Unexecuted instantiation: signal.c:rb_ractor_self
Unexecuted instantiation: thread.c:rb_ractor_self
Unexecuted instantiation: variable.c:rb_ractor_self
vm.c:rb_ractor_self
Line
Count
Source
127
91.0k
{
128
91.0k
    return r->pub.self;
129
91.0k
}
Unexecuted instantiation: vm_dump.c:rb_ractor_self
Unexecuted instantiation: vm_sync.c:rb_ractor_self
Unexecuted instantiation: vm_trace.c:rb_ractor_self
Unexecuted instantiation: cont.c:rb_ractor_self
Unexecuted instantiation: debug.c:rb_ractor_self
130
131
rb_ractor_t *rb_ractor_main_alloc(void);
132
void rb_ractor_main_setup(rb_vm_t *vm, rb_ractor_t *main_ractor, rb_thread_t *main_thread);
133
void rb_ractor_atexit(rb_execution_context_t *ec, VALUE result);
134
void rb_ractor_atexit_exception(rb_execution_context_t *ec);
135
void rb_ractor_teardown(rb_execution_context_t *ec);
136
void rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *g, int len, VALUE *ptr);
137
void rb_ractor_send_parameters(rb_execution_context_t *ec, rb_ractor_t *g, VALUE args);
138
139
VALUE rb_thread_create_ractor(rb_ractor_t *g, VALUE args, VALUE proc); // defined in thread.c
140
141
int rb_ractor_living_thread_num(const rb_ractor_t *);
142
VALUE rb_ractor_thread_list(void);
143
bool rb_ractor_p(VALUE rv);
144
145
void rb_ractor_living_threads_init(rb_ractor_t *r);
146
void rb_ractor_living_threads_insert(rb_ractor_t *r, rb_thread_t *th);
147
void rb_ractor_living_threads_remove(rb_ractor_t *r, rb_thread_t *th);
148
void rb_ractor_blocking_threads_inc(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG
149
void rb_ractor_blocking_threads_dec(rb_ractor_t *r, const char *file, int line); // TODO: file, line only for RUBY_DEBUG_LOG
150
151
void rb_ractor_vm_barrier_interrupt_running_thread(rb_ractor_t *r);
152
void rb_ractor_terminate_interrupt_main_thread(rb_ractor_t *r);
153
void rb_ractor_terminate_all(void);
154
bool rb_ractor_main_p_(void);
155
void rb_ractor_atfork(rb_vm_t *vm, rb_thread_t *th);
156
void rb_ractor_terminate_atfork(rb_vm_t *vm, rb_ractor_t *th);
157
VALUE rb_ractor_require(VALUE feature, bool silent);
158
VALUE rb_ractor_autoload_load(VALUE space, ID id);
159
160
VALUE rb_ractor_ensure_shareable(VALUE obj, VALUE name);
161
st_table *rb_ractor_targeted_hooks(rb_ractor_t *cr);
162
163
RUBY_SYMBOL_EXPORT_BEGIN
164
void rb_ractor_finish_marking(void);
165
166
bool rb_ractor_shareable_p_continue(VALUE obj);
167
168
// THIS FUNCTION SHOULD NOT CALL WHILE INCREMENTAL MARKING!!
169
// This function is for T_DATA::free_func
170
void rb_ractor_local_storage_delkey(rb_ractor_local_key_t key);
171
172
RUBY_SYMBOL_EXPORT_END
173
174
static inline bool
175
rb_ractor_main_p(void)
176
1.02M
{
177
1.02M
    if (ruby_single_main_ractor) {
178
1.02M
        return true;
179
1.02M
    }
180
0
    else {
181
0
        return rb_ractor_main_p_();
182
0
    }
183
1.02M
}
Unexecuted instantiation: eval.c:rb_ractor_main_p
Unexecuted instantiation: gc.c:rb_ractor_main_p
Unexecuted instantiation: iseq.c:rb_ractor_main_p
load.c:rb_ractor_main_p
Line
Count
Source
176
28.9k
{
177
28.9k
    if (ruby_single_main_ractor) {
178
28.9k
        return true;
179
28.9k
    }
180
0
    else {
181
0
        return rb_ractor_main_p_();
182
0
    }
183
28.9k
}
Unexecuted instantiation: proc.c:rb_ractor_main_p
Unexecuted instantiation: process.c:rb_ractor_main_p
ractor.c:rb_ractor_main_p
Line
Count
Source
176
979k
{
177
979k
    if (ruby_single_main_ractor) {
178
979k
        return true;
179
979k
    }
180
0
    else {
181
0
        return rb_ractor_main_p_();
182
0
    }
183
979k
}
re.c:rb_ractor_main_p
Line
Count
Source
176
6.54k
{
177
6.54k
    if (ruby_single_main_ractor) {
178
6.54k
        return true;
179
6.54k
    }
180
0
    else {
181
0
        return rb_ractor_main_p_();
182
0
    }
183
6.54k
}
Unexecuted instantiation: signal.c:rb_ractor_main_p
Unexecuted instantiation: thread.c:rb_ractor_main_p
variable.c:rb_ractor_main_p
Line
Count
Source
176
6.38k
{
177
6.38k
    if (ruby_single_main_ractor) {
178
6.38k
        return true;
179
6.38k
    }
180
0
    else {
181
0
        return rb_ractor_main_p_();
182
0
    }
183
6.38k
}
Unexecuted instantiation: vm.c:rb_ractor_main_p
Unexecuted instantiation: vm_dump.c:rb_ractor_main_p
Unexecuted instantiation: vm_sync.c:rb_ractor_main_p
Unexecuted instantiation: vm_trace.c:rb_ractor_main_p
Unexecuted instantiation: cont.c:rb_ractor_main_p
Unexecuted instantiation: debug.c:rb_ractor_main_p
184
185
static inline bool
186
rb_ractor_status_p(rb_ractor_t *r, enum ractor_status status)
187
0
{
188
0
    return r->status_ == status;
189
0
}
Unexecuted instantiation: eval.c:rb_ractor_status_p
Unexecuted instantiation: gc.c:rb_ractor_status_p
Unexecuted instantiation: iseq.c:rb_ractor_status_p
Unexecuted instantiation: load.c:rb_ractor_status_p
Unexecuted instantiation: proc.c:rb_ractor_status_p
Unexecuted instantiation: process.c:rb_ractor_status_p
Unexecuted instantiation: ractor.c:rb_ractor_status_p
Unexecuted instantiation: re.c:rb_ractor_status_p
Unexecuted instantiation: signal.c:rb_ractor_status_p
Unexecuted instantiation: thread.c:rb_ractor_status_p
Unexecuted instantiation: variable.c:rb_ractor_status_p
Unexecuted instantiation: vm.c:rb_ractor_status_p
Unexecuted instantiation: vm_dump.c:rb_ractor_status_p
Unexecuted instantiation: vm_sync.c:rb_ractor_status_p
Unexecuted instantiation: vm_trace.c:rb_ractor_status_p
Unexecuted instantiation: cont.c:rb_ractor_status_p
Unexecuted instantiation: debug.c:rb_ractor_status_p
190
191
static inline void
192
rb_ractor_sleeper_threads_inc(rb_ractor_t *r)
193
0
{
194
0
    r->threads.sleeper++;
195
0
}
Unexecuted instantiation: eval.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: gc.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: iseq.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: load.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: proc.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: process.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: ractor.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: re.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: signal.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: thread.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: variable.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: vm.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: cont.c:rb_ractor_sleeper_threads_inc
Unexecuted instantiation: debug.c:rb_ractor_sleeper_threads_inc
196
197
static inline void
198
rb_ractor_sleeper_threads_dec(rb_ractor_t *r)
199
0
{
200
0
    r->threads.sleeper--;
201
0
}
Unexecuted instantiation: eval.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: gc.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: iseq.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: load.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: proc.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: process.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: ractor.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: re.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: signal.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: thread.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: variable.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: vm.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: cont.c:rb_ractor_sleeper_threads_dec
Unexecuted instantiation: debug.c:rb_ractor_sleeper_threads_dec
202
203
static inline void
204
rb_ractor_sleeper_threads_clear(rb_ractor_t *r)
205
0
{
206
0
    r->threads.sleeper = 0;
207
0
}
Unexecuted instantiation: eval.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: gc.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: iseq.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: load.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: proc.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: process.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: ractor.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: re.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: signal.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: thread.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: variable.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: vm.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: cont.c:rb_ractor_sleeper_threads_clear
Unexecuted instantiation: debug.c:rb_ractor_sleeper_threads_clear
208
209
static inline int
210
rb_ractor_sleeper_thread_num(rb_ractor_t *r)
211
0
{
212
0
    return r->threads.sleeper;
213
0
}
Unexecuted instantiation: eval.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: gc.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: iseq.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: load.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: proc.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: process.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: ractor.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: re.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: signal.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: thread.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: variable.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: vm.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: vm_dump.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: vm_sync.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: vm_trace.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: cont.c:rb_ractor_sleeper_thread_num
Unexecuted instantiation: debug.c:rb_ractor_sleeper_thread_num
214
215
static inline void
216
rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th, bool always_reset)
217
35
{
218
35
    RUBY_DEBUG_LOG("th:%d->%u%s",
219
35
                   cr->threads.running_ec ? (int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1,
220
35
                   rb_th_serial(th), cr->threads.running_ec == th->ec ? " (same)" : "");
221
222
35
    if (cr->threads.running_ec != th->ec || always_reset) {
223
0
        th->running_time_us = 0;
224
0
    }
225
226
35
    if (cr->threads.running_ec != th->ec) {
227
0
        if (0) {
228
0
            ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n",
229
0
                              (void *)cr->threads.running_ec, (void *)th->ec);
230
0
        }
231
0
    }
232
35
    else {
233
35
        return;
234
35
    }
235
236
0
    cr->threads.running_ec = th->ec;
237
238
0
    VM_ASSERT(cr == GET_RACTOR());
239
0
}
Unexecuted instantiation: eval.c:rb_ractor_thread_switch
Unexecuted instantiation: gc.c:rb_ractor_thread_switch
Unexecuted instantiation: iseq.c:rb_ractor_thread_switch
Unexecuted instantiation: load.c:rb_ractor_thread_switch
Unexecuted instantiation: proc.c:rb_ractor_thread_switch
Unexecuted instantiation: process.c:rb_ractor_thread_switch
Unexecuted instantiation: ractor.c:rb_ractor_thread_switch
Unexecuted instantiation: re.c:rb_ractor_thread_switch
Unexecuted instantiation: signal.c:rb_ractor_thread_switch
thread.c:rb_ractor_thread_switch
Line
Count
Source
217
35
{
218
35
    RUBY_DEBUG_LOG("th:%d->%u%s",
219
35
                   cr->threads.running_ec ? (int)rb_th_serial(cr->threads.running_ec->thread_ptr) : -1,
220
35
                   rb_th_serial(th), cr->threads.running_ec == th->ec ? " (same)" : "");
221
222
35
    if (cr->threads.running_ec != th->ec || always_reset) {
223
0
        th->running_time_us = 0;
224
0
    }
225
226
35
    if (cr->threads.running_ec != th->ec) {
227
0
        if (0) {
228
0
            ruby_debug_printf("rb_ractor_thread_switch ec:%p->%p\n",
229
0
                              (void *)cr->threads.running_ec, (void *)th->ec);
230
0
        }
231
0
    }
232
35
    else {
233
35
        return;
234
35
    }
235
236
0
    cr->threads.running_ec = th->ec;
237
238
0
    VM_ASSERT(cr == GET_RACTOR());
239
0
}
Unexecuted instantiation: variable.c:rb_ractor_thread_switch
Unexecuted instantiation: vm.c:rb_ractor_thread_switch
Unexecuted instantiation: vm_dump.c:rb_ractor_thread_switch
Unexecuted instantiation: vm_sync.c:rb_ractor_thread_switch
Unexecuted instantiation: vm_trace.c:rb_ractor_thread_switch
Unexecuted instantiation: cont.c:rb_ractor_thread_switch
Unexecuted instantiation: debug.c:rb_ractor_thread_switch
240
241
9
#define rb_ractor_set_current_ec(cr, ec) rb_ractor_set_current_ec_(cr, ec, __FILE__, __LINE__)
242
#ifdef RB_THREAD_LOCAL_SPECIFIER
243
void rb_current_ec_set(rb_execution_context_t *ec);
244
#endif
245
246
static inline void
247
rb_ractor_set_current_ec_(rb_ractor_t *cr, rb_execution_context_t *ec, const char *file, int line)
248
9
{
249
9
#ifdef RB_THREAD_LOCAL_SPECIFIER
250
9
    rb_current_ec_set(ec);
251
#else
252
    native_tls_set(ruby_current_ec_key, ec);
253
#endif
254
9
    RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec);
255
9
    VM_ASSERT(ec == NULL || cr->threads.running_ec != ec);
256
9
    cr->threads.running_ec = ec;
257
9
}
Unexecuted instantiation: eval.c:rb_ractor_set_current_ec_
Unexecuted instantiation: gc.c:rb_ractor_set_current_ec_
Unexecuted instantiation: iseq.c:rb_ractor_set_current_ec_
Unexecuted instantiation: load.c:rb_ractor_set_current_ec_
Unexecuted instantiation: proc.c:rb_ractor_set_current_ec_
Unexecuted instantiation: process.c:rb_ractor_set_current_ec_
Unexecuted instantiation: ractor.c:rb_ractor_set_current_ec_
Unexecuted instantiation: re.c:rb_ractor_set_current_ec_
Unexecuted instantiation: signal.c:rb_ractor_set_current_ec_
Unexecuted instantiation: thread.c:rb_ractor_set_current_ec_
Unexecuted instantiation: variable.c:rb_ractor_set_current_ec_
vm.c:rb_ractor_set_current_ec_
Line
Count
Source
248
9
{
249
9
#ifdef RB_THREAD_LOCAL_SPECIFIER
250
9
    rb_current_ec_set(ec);
251
#else
252
    native_tls_set(ruby_current_ec_key, ec);
253
#endif
254
9
    RUBY_DEBUG_LOG2(file, line, "ec:%p->%p", (void *)cr->threads.running_ec, (void *)ec);
255
9
    VM_ASSERT(ec == NULL || cr->threads.running_ec != ec);
256
9
    cr->threads.running_ec = ec;
257
9
}
Unexecuted instantiation: vm_dump.c:rb_ractor_set_current_ec_
Unexecuted instantiation: vm_sync.c:rb_ractor_set_current_ec_
Unexecuted instantiation: vm_trace.c:rb_ractor_set_current_ec_
Unexecuted instantiation: cont.c:rb_ractor_set_current_ec_
Unexecuted instantiation: debug.c:rb_ractor_set_current_ec_
258
259
void rb_vm_ractor_blocking_cnt_inc(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
260
void rb_vm_ractor_blocking_cnt_dec(rb_vm_t *vm, rb_ractor_t *cr, const char *file, int line);
261
262
static inline uint32_t
263
rb_ractor_id(const rb_ractor_t *r)
264
9
{
265
9
    return r->pub.id;
266
9
}
Unexecuted instantiation: eval.c:rb_ractor_id
Unexecuted instantiation: gc.c:rb_ractor_id
Unexecuted instantiation: iseq.c:rb_ractor_id
Unexecuted instantiation: load.c:rb_ractor_id
Unexecuted instantiation: proc.c:rb_ractor_id
Unexecuted instantiation: process.c:rb_ractor_id
Unexecuted instantiation: ractor.c:rb_ractor_id
Unexecuted instantiation: re.c:rb_ractor_id
Unexecuted instantiation: signal.c:rb_ractor_id
Unexecuted instantiation: thread.c:rb_ractor_id
Unexecuted instantiation: variable.c:rb_ractor_id
vm.c:rb_ractor_id
Line
Count
Source
264
9
{
265
9
    return r->pub.id;
266
9
}
Unexecuted instantiation: vm_dump.c:rb_ractor_id
Unexecuted instantiation: vm_sync.c:rb_ractor_id
Unexecuted instantiation: vm_trace.c:rb_ractor_id
Unexecuted instantiation: cont.c:rb_ractor_id
Unexecuted instantiation: debug.c:rb_ractor_id
267
268
static inline void
269
rb_ractor_targeted_hooks_incr(rb_ractor_t *cr)
270
0
{
271
0
    cr->pub.targeted_hooks_cnt++;
272
0
}
Unexecuted instantiation: eval.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: gc.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: iseq.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: load.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: proc.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: process.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: ractor.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: re.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: signal.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: thread.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: variable.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: vm.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: vm_dump.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: vm_sync.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: vm_trace.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: cont.c:rb_ractor_targeted_hooks_incr
Unexecuted instantiation: debug.c:rb_ractor_targeted_hooks_incr
273
274
static inline void
275
rb_ractor_targeted_hooks_decr(rb_ractor_t *cr)
276
0
{
277
0
    RUBY_ASSERT(cr->pub.targeted_hooks_cnt > 0);
278
0
    cr->pub.targeted_hooks_cnt--;
279
0
}
Unexecuted instantiation: eval.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: gc.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: iseq.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: load.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: proc.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: process.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: ractor.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: re.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: signal.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: thread.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: variable.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: vm.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: vm_dump.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: vm_sync.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: vm_trace.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: cont.c:rb_ractor_targeted_hooks_decr
Unexecuted instantiation: debug.c:rb_ractor_targeted_hooks_decr
280
281
static inline unsigned int
282
rb_ractor_targeted_hooks_cnt(rb_ractor_t *cr)
283
0
{
284
0
    return cr->pub.targeted_hooks_cnt;
285
0
}
Unexecuted instantiation: eval.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: gc.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: iseq.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: load.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: proc.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: process.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: ractor.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: re.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: signal.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: thread.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: variable.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: vm.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: vm_dump.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: vm_sync.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: vm_trace.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: cont.c:rb_ractor_targeted_hooks_cnt
Unexecuted instantiation: debug.c:rb_ractor_targeted_hooks_cnt
286
287
#if RACTOR_CHECK_MODE > 0
288
# define RACTOR_BELONGING_ID(obj) (*(uint32_t *)(((uintptr_t)(obj)) + rb_gc_obj_slot_size(obj)))
289
290
uint32_t rb_ractor_current_id(void);
291
292
static inline void
293
rb_ractor_setup_belonging_to(VALUE obj, uint32_t rid)
294
{
295
    RACTOR_BELONGING_ID(obj) = rid;
296
}
297
298
static inline uint32_t
299
rb_ractor_belonging(VALUE obj)
300
{
301
    if (SPECIAL_CONST_P(obj) || RB_OBJ_SHAREABLE_P(obj)) {
302
        return 0;
303
    }
304
    else {
305
        return RACTOR_BELONGING_ID(obj);
306
    }
307
}
308
309
extern bool rb_ractor_ignore_belonging_flag;
310
311
static inline VALUE
312
rb_ractor_confirm_belonging(VALUE obj)
313
{
314
    if (rb_ractor_ignore_belonging_flag) return obj;
315
316
    uint32_t id = rb_ractor_belonging(obj);
317
318
    if (id == 0) {
319
        if (UNLIKELY(!rb_ractor_shareable_p(obj))) {
320
            rp(obj);
321
            rb_bug("id == 0 but not shareable");
322
        }
323
    }
324
    else if (UNLIKELY(id != rb_ractor_current_id())) {
325
        if (rb_ractor_shareable_p(obj)) {
326
            // ok
327
        }
328
        else {
329
            rp(obj);
330
            rb_bug("rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u", id, rb_ractor_current_id());
331
        }
332
    }
333
    return obj;
334
}
335
336
static inline void
337
rb_ractor_ignore_belonging(bool flag)
338
{
339
    rb_ractor_ignore_belonging_flag = flag;
340
}
341
342
#else
343
0
#define rb_ractor_confirm_belonging(obj) obj
344
0
#define rb_ractor_ignore_belonging(flag) (0)
345
#endif