Ruby: thread_none.c Source File

Ruby 3.3.7p123 (2025-01-15 revision be31f993d7fa0219d85f7b3c694d454da4ecc10b)

thread_none.c
1/*
2 A thread interface implementation without any system thread.
3
4 Assumption:
5 * There is a only single thread in the ruby process
6 * No signal happens targeting the ruby process
7
8 Note:
9 * No thread switching in the VM
10 * No timer thread because thread switching won't happen
11 * No mutex guard because the VM won't be racy
12*/
13
14#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
15
16#include <time.h>
17
18#if defined(__wasm__) && !defined(__EMSCRIPTEN__)
19# include "wasm/machine.h"
20#endif
21
22#define TIME_QUANTUM_MSEC (100)
23#define TIME_QUANTUM_USEC (TIME_QUANTUM_MSEC * 1000)
24#define TIME_QUANTUM_NSEC (TIME_QUANTUM_USEC * 1000)
25
26// Do nothing for GVL
27static void
28thread_sched_to_running(struct rb_thread_sched *sched, rb_thread_t *th)
29{
30}
31
32static void
33thread_sched_to_waiting(struct rb_thread_sched *sched, rb_thread_t *th)
34{
35}
36
37#define thread_sched_to_dead thread_sched_to_waiting
38
39static void
40thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
41{
42}
43
44void
45rb_thread_sched_init(struct rb_thread_sched *sched, bool atfork)
46{
47}
48
49#if 0
50static void
51rb_thread_sched_destroy(struct rb_thread_sched *sched)
52{
53}
54#endif
55
56// Do nothing for mutex guard
57void
58 rb_native_mutex_lock(rb_nativethread_lock_t *lock)
59{
60}
61
62void
63 rb_native_mutex_unlock(rb_nativethread_lock_t *lock)
64{
65}
66
67int
68 rb_native_mutex_trylock(rb_nativethread_lock_t *lock)
69{
70 return 0;
71}
72
73void
74 rb_native_mutex_initialize(rb_nativethread_lock_t *lock)
75{
76}
77
78void
79 rb_native_mutex_destroy(rb_nativethread_lock_t *lock)
80{
81}
82
83void
84 rb_native_cond_initialize(rb_nativethread_cond_t *cond)
85{
86}
87
88void
89 rb_native_cond_destroy(rb_nativethread_cond_t *cond)
90{
91}
92
93void
94 rb_native_cond_signal(rb_nativethread_cond_t *cond)
95{
96}
97
98void
99 rb_native_cond_broadcast(rb_nativethread_cond_t *cond)
100{
101}
102
103void
104 rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex)
105{
106}
107
108void
109 rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec)
110{
111}
112
113// The only one thread in process
114static rb_thread_t *ruby_native_thread;
115
116rb_thread_t *
117ruby_thread_from_native(void)
118{
119 return ruby_native_thread;
120}
121
122int
123ruby_thread_set_native(rb_thread_t *th)
124{
125 if (th && th->ec) {
126 rb_ractor_set_current_ec(th->ractor, th->ec);
127 }
128 ruby_native_thread = th;
129 return 1; // always succeed
130}
131
132void
133Init_native_thread(rb_thread_t *main_th)
134{
135 // no TLS setup and no thread id setup
136 ruby_thread_set_native(main_th);
137}
138
139void
140ruby_mn_threads_params(void)
141{
142}
143
144void
145 ruby_init_stack(volatile VALUE *addr)
146{
147}
148
149static int
150native_thread_init_stack(rb_thread_t *th)
151{
152#if defined(__wasm__) && !defined(__EMSCRIPTEN__)
153 th->ec->machine.stack_start = (VALUE *)rb_wasm_stack_get_base();
154#endif
155 return 0; // success
156}
157
158static int
159native_thread_create(rb_thread_t *th)
160{
161 th->status = THREAD_KILLED;
162 rb_ractor_living_threads_remove(th->ractor, th);
163 rb_notimplement();
164}
165
166// Do nothing for handling ubf because no other thread doesn't exist and unblock anything
167#define register_ubf_list(th) (void)(th)
168#define unregister_ubf_list(th) (void)(th)
169#define ubf_select 0
170
171inline static void
172ubf_wakeup_all_threads(void)
173{
174 return;
175}
176
177inline static int
178ubf_threads_empty(void)
179{
180 return 1; // true
181}
182
183inline static void
184ubf_list_atfork()
185{
186}
187
188inline static void
189ubf_timer_disarm(void)
190{
191}
192
193
194// No timer thread because thread switching won't happen
195#define TIMER_THREAD_CREATED_P() (1)
196inline static void
197rb_thread_create_timer_thread(void)
198{
199}
200
201void
202rb_thread_wakeup_timer_thread(int sig)
203{
204}
205
206inline static int
207native_stop_timer_thread(void)
208{
209 return 1; // success
210}
211
212inline static void
213native_reset_timer_thread(void)
214{
215}
216
217// Do nothing for thread naming
218inline static void
219native_set_thread_name(rb_thread_t *th)
220{
221}
222
223inline static void
224native_set_another_thread_name(rb_nativethread_id_t thread_id, VALUE name)
225{
226}
227
228// Don't expose native thread id for now to keep system's thread API agnostic
229#define USE_NATIVE_THREAD_NATIVE_THREAD_ID 0
230
231// No reserved fd for piping threads
232int
233 rb_reserved_fd_p(int fd)
234{
235 return 0; // not reserved
236}
237
238// Don't expose native thread info for now to keep system's thread API agnostic
239rb_nativethread_id_t
240 rb_nativethread_self(void)
241{
242 return NULL;
243}
244
245// Do nothing for sigwait things because of no signal assumption
246// Q(katei): is this correct description?
247int
248rb_sigwait_fd_get(const rb_thread_t *th)
249{
250 return -1;
251}
252
253NORETURN(void rb_sigwait_fd_put(rb_thread_t *, int));
254void
255rb_sigwait_fd_put(rb_thread_t *th, int fd)
256{
257 rb_bug("not implemented, should not be called rb_sigwait_fd_put");
258}
259
260NORETURN(void rb_sigwait_sleep(const rb_thread_t *, int, const rb_hrtime_t *));
261void
262rb_sigwait_sleep(const rb_thread_t *th, int sigwait_fd, const rb_hrtime_t *rel)
263{
264 rb_bug("not implemented, should not be called rb_sigwait_sleep");
265}
266
267static void
268native_sleep(rb_thread_t *th, rb_hrtime_t *rel)
269{
270 // No signal assumption allows the use of uninterruptible sleep
271 struct timespec ts;
272 (void)clock_nanosleep(CLOCK_REALTIME, 0, rb_hrtime2timespec(&ts, rel), NULL);
273}
274
275static int
276native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th)
277{
278 return rb_fd_select(n, readfds, writefds, exceptfds, timeout);
279}
280
281static bool
282th_has_dedicated_nt(const rb_thread_t *th)
283{
284 return true;
285}
286
287void
288rb_add_running_thread(rb_thread_t *th){
289 // do nothing
290}
291
292void
293rb_del_running_thread(rb_thread_t *th)
294{
295 // do nothing
296}
297
298void
299rb_threadptr_sched_free(rb_thread_t *th)
300{
301 // do nothing
302}
303
304void
305rb_ractor_sched_barrier_start(rb_vm_t *vm, rb_ractor_t *cr)
306{
307 // do nothing
308}
309
310void
311rb_ractor_sched_barrier_join(rb_vm_t *vm, rb_ractor_t *cr)
312{
313 // do nothing
314}
315
316void
317rb_threadptr_remove(rb_thread_t *th)
318{
319 // do nothing
320}
321
322void
323rb_thread_sched_mark_zombies(rb_vm_t *vm)
324{
325 // do nothing
326}
327
328#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
ruby_init_stack
void ruby_init_stack(volatile VALUE *addr)
Set stack bottom of Ruby implementation.
rb_notimplement
void rb_notimplement(void)
Definition error.c:3498
rb_reserved_fd_p
int rb_reserved_fd_p(int fd)
Queries if the given FD is reserved or not.
rb_fd_select
#define rb_fd_select
Waits for multiple file descriptors at once.
Definition posix.h:66
rb_fdset_t
The data structure which wraps the fd_set bitmap used by select(2).
Definition largesize.h:71
rb_thread_sched
Definition thread_none.h:16
timespec
Definition missing.h:74
timeval
Definition missing.h:63
rb_nativethread_self
rb_nativethread_id_t rb_nativethread_self(void)
Queries the ID of the native thread that is calling this function.
rb_native_mutex_lock
void rb_native_mutex_lock(rb_nativethread_lock_t *lock)
Just another name of rb_nativethread_lock_lock.
rb_native_cond_initialize
void rb_native_cond_initialize(rb_nativethread_cond_t *cond)
Fills the passed condition variable with an initial value.
rb_native_mutex_trylock
int rb_native_mutex_trylock(rb_nativethread_lock_t *lock)
Identical to rb_native_mutex_lock(), except it doesn't block in case rb_native_mutex_lock() would.
rb_native_cond_broadcast
void rb_native_cond_broadcast(rb_nativethread_cond_t *cond)
Signals a condition variable.
rb_native_mutex_initialize
void rb_native_mutex_initialize(rb_nativethread_lock_t *lock)
Just another name of rb_nativethread_lock_initialize.
rb_native_mutex_unlock
void rb_native_mutex_unlock(rb_nativethread_lock_t *lock)
Just another name of rb_nativethread_lock_unlock.
rb_native_mutex_destroy
void rb_native_mutex_destroy(rb_nativethread_lock_t *lock)
Just another name of rb_nativethread_lock_destroy.
rb_native_cond_destroy
void rb_native_cond_destroy(rb_nativethread_cond_t *cond)
Destroys the passed condition variable.
rb_native_cond_signal
void rb_native_cond_signal(rb_nativethread_cond_t *cond)
Signals a condition variable.
rb_native_cond_wait
void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex)
Waits for the passed condition variable to be signalled.
rb_native_cond_timedwait
void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec)
Identical to rb_native_cond_wait(), except it additionally takes timeout in msec resolution.
VALUE
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40