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