Ruby 3.2.2p53 (2023-03-30 revision e51014f9c05aa65cbf203442d37fef7c12390015)
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)
34{
35}
36
37static void
38thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
39{
40}
41
42void
43rb_thread_sched_init(struct rb_thread_sched *sched)
44{
45}
46
47#if 0
48static void
49rb_thread_sched_destroy(struct rb_thread_sched *sched)
50{
51}
52#endif
53
54// Do nothing for mutex guard
55void
57{
58}
59
60void
62{
63}
64
65int
67{
68 return 0;
69}
70
71void
73{
74}
75
76void
78{
79}
80
81void
83{
84}
85
86void
88{
89}
90
91void
93{
94}
95
96void
98{
99}
100
101void
103{
104}
105
106void
108{
109}
110
111// The only one thread in process
112static rb_thread_t *ruby_native_thread;
113
115ruby_thread_from_native(void)
116{
117 return ruby_native_thread;
118}
119
120int
121ruby_thread_set_native(rb_thread_t *th)
122{
123 if (th && th->ec) {
124 rb_ractor_set_current_ec(th->ractor, th->ec);
125 }
126 ruby_native_thread = th;
127 return 1; // always succeed
128}
129
130void
131Init_native_thread(rb_thread_t *main_th)
132{
133 // no TLS setup and no thread id setup
134 ruby_thread_set_native(main_th);
135}
136
137static void
138native_thread_destroy(rb_thread_t *th)
139{
140}
141
142void
143ruby_init_stack(volatile VALUE *addr)
144{
145}
146
147static int
148native_thread_init_stack(rb_thread_t *th)
149{
150#if defined(__wasm__) && !defined(__EMSCRIPTEN__)
151 th->ec->machine.stack_start = (VALUE *)rb_wasm_stack_get_base();
152#endif
153 return 0; // success
154}
155
156static int
157native_thread_create(rb_thread_t *th)
158{
159 th->status = THREAD_KILLED;
160 rb_ractor_living_threads_remove(th->ractor, th);
162}
163
164// Do nothing for handling ubf because no other thread doesn't exist and unblock anything
165#define register_ubf_list(th) (void)(th)
166#define unregister_ubf_list(th) (void)(th)
167#define ubf_select 0
168
169inline static void
170ubf_wakeup_all_threads(void)
171{
172 return;
173}
174
175inline static int
176ubf_threads_empty(void)
177{
178 return 1; // true
179}
180
181inline static void
182ubf_list_atfork()
183{
184}
185
186inline static void
187ubf_timer_disarm(void)
188{
189}
190
191
192// No timer thread because thread switching won't happen
193#define TIMER_THREAD_CREATED_P() (1)
194inline static void
195rb_thread_create_timer_thread(void)
196{
197}
198
199void
200rb_thread_wakeup_timer_thread(int sig)
201{
202}
203
204inline static int
205native_stop_timer_thread(void)
206{
207 return 1; // success
208}
209
210inline static void
211native_reset_timer_thread(void)
212{
213}
214
215// Do nothing for thread naming
216inline static void
217native_set_thread_name(rb_thread_t *th)
218{
219}
220
221inline static void
222native_set_another_thread_name(rb_nativethread_id_t thread_id, VALUE name)
223{
224}
225
226// Don't expose native thread id for now to keep system's thread API agnostic
227#define USE_NATIVE_THREAD_NATIVE_THREAD_ID 0
228
229// No reserved fd for piping threads
230int
231rb_reserved_fd_p(int fd)
232{
233 return 0; // not reserved
234}
235
236// Don't expose native thread info for now to keep system's thread API agnostic
239{
240 return NULL;
241}
242
243// Do nothing for sigwait things because of no signal assumption
244// Q(katei): is this correct description?
245int
246rb_sigwait_fd_get(const rb_thread_t *th)
247{
248 return -1;
249}
250
251NORETURN(void rb_sigwait_fd_put(rb_thread_t *, int));
252void
253rb_sigwait_fd_put(rb_thread_t *th, int fd)
254{
255 rb_bug("not implemented, should not be called rb_sigwait_fd_put");
256}
257
258NORETURN(void rb_sigwait_sleep(const rb_thread_t *, int, const rb_hrtime_t *));
259void
260rb_sigwait_sleep(const rb_thread_t *th, int sigwait_fd, const rb_hrtime_t *rel)
261{
262 rb_bug("not implemented, should not be called rb_sigwait_sleep");
263}
264
265static void
266native_sleep(rb_thread_t *th, rb_hrtime_t *rel)
267{
268 // No signal assumption allows the use of uninterruptible sleep
269 struct timespec ts;
270 (void)clock_nanosleep(CLOCK_REALTIME, 0, rb_hrtime2timespec(&ts, rel), NULL);
271}
272
273static int
274native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th)
275{
276 return rb_fd_select(n, readfds, writefds, exceptfds, timeout);
277}
278
279static VALUE
280rb_thread_start_unblock_thread(void)
281{
282 return Qfalse;
283}
284#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
#define Qfalse
Old name of RUBY_Qfalse.
void ruby_init_stack(volatile VALUE *addr)
Set stack bottom of Ruby implementation.
void rb_notimplement(void)
Definition error.c:3191
void rb_bug(const char *fmt,...)
Interpreter panic switch.
Definition error.c:794
int rb_reserved_fd_p(int fd)
Queries if the given FD is reserved or not.
#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