2 A thread interface implementation without any system thread.
5 * There is a only single thread in the ruby process
6 * No signal happens targeting the ruby process
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
14 #ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
18 #if defined(__wasm__) && !defined(__EMSCRIPTEN__)
19 # include "wasm/machine.h"
22 #define TIME_QUANTUM_MSEC (100)
23 #define TIME_QUANTUM_USEC (TIME_QUANTUM_MSEC * 1000)
24 #define TIME_QUANTUM_NSEC (TIME_QUANTUM_USEC * 1000)
28 thread_sched_to_running(struct rb_thread_sched
*sched
, rb_thread_t
*th
)
33 thread_sched_to_waiting(struct rb_thread_sched
*sched
, rb_thread_t
*th
)
37 #define thread_sched_to_dead thread_sched_to_waiting
40 thread_sched_yield(struct rb_thread_sched
*sched
, rb_thread_t
*th
)
45 rb_thread_sched_init(struct rb_thread_sched
*sched
, bool atfork
)
51 rb_thread_sched_destroy(struct rb_thread_sched
*sched
)
56 // Do nothing for mutex guard
58 rb_native_mutex_lock(rb_nativethread_lock_t
*lock
)
63 rb_native_mutex_unlock(rb_nativethread_lock_t
*lock
)
68 rb_native_mutex_trylock(rb_nativethread_lock_t
*lock
)
74 rb_native_mutex_initialize(rb_nativethread_lock_t
*lock
)
79 rb_native_mutex_destroy(rb_nativethread_lock_t
*lock
)
84 rb_native_cond_initialize(rb_nativethread_cond_t
*cond
)
89 rb_native_cond_destroy(rb_nativethread_cond_t
*cond
)
94 rb_native_cond_signal(rb_nativethread_cond_t
*cond
)
99 rb_native_cond_broadcast(rb_nativethread_cond_t
*cond
)
104 rb_native_cond_wait(rb_nativethread_cond_t
*cond
, rb_nativethread_lock_t
*mutex
)
109 rb_native_cond_timedwait(rb_nativethread_cond_t
*cond
, rb_nativethread_lock_t
*mutex
, unsigned long msec
)
113 // The only one thread in process
114 static rb_thread_t
*ruby_native_thread
;
117 ruby_thread_from_native(void)
119 return ruby_native_thread
;
123 ruby_thread_set_native(rb_thread_t
*th
)
126 rb_ractor_set_current_ec(th
->ractor
, th
->ec
);
128 ruby_native_thread
= th
;
129 return 1; // always succeed
133 Init_native_thread(rb_thread_t
*main_th
)
135 // no TLS setup and no thread id setup
136 ruby_thread_set_native(main_th
);
140 ruby_mn_threads_params(void)
145 native_thread_init_stack(rb_thread_t
*th
, void *local_in_parent_frame
)
147 #if defined(__wasm__) && !defined(__EMSCRIPTEN__)
148 th
->ec
->machine
.stack_start
= (VALUE
*)rb_wasm_stack_get_base();
154 native_thread_create(rb_thread_t
*th
)
156 th
->status
= THREAD_KILLED
;
157 rb_ractor_living_threads_remove(th
->ractor
, th
);
161 // Do nothing for handling ubf because no other thread doesn't exist and unblock anything
162 #define register_ubf_list(th) (void)(th)
163 #define unregister_ubf_list(th) (void)(th)
167 ubf_wakeup_all_threads(void)
173 ubf_threads_empty(void)
184 ubf_timer_disarm(void)
189 // No timer thread because thread switching won't happen
190 #define TIMER_THREAD_CREATED_P() (1)
192 rb_thread_create_timer_thread(void)
197 rb_thread_wakeup_timer_thread(int sig
)
202 native_stop_timer_thread(void)
208 native_reset_timer_thread(void)
212 // Do nothing for thread naming
214 native_set_thread_name(rb_thread_t
*th
)
219 native_set_another_thread_name(rb_nativethread_id_t thread_id
, VALUE name
)
223 // Don't expose native thread id for now to keep system's thread API agnostic
224 #define USE_NATIVE_THREAD_NATIVE_THREAD_ID 0
226 // No reserved fd for piping threads
228 rb_reserved_fd_p(int fd
)
230 return 0; // not reserved
233 // Don't expose native thread info for now to keep system's thread API agnostic
235 rb_nativethread_self(void)
240 // Do nothing for sigwait things because of no signal assumption
241 // Q(katei): is this correct description?
243 rb_sigwait_fd_get(const rb_thread_t
*th
)
248 NORETURN(void rb_sigwait_fd_put(rb_thread_t
*, int));
250 rb_sigwait_fd_put(rb_thread_t
*th
, int fd
)
252 rb_bug("not implemented, should not be called rb_sigwait_fd_put");
255 NORETURN(void rb_sigwait_sleep(const rb_thread_t
*, int, const rb_hrtime_t
*));
257 rb_sigwait_sleep(const rb_thread_t
*th
, int sigwait_fd
, const rb_hrtime_t
*rel
)
259 rb_bug("not implemented, should not be called rb_sigwait_sleep");
263 native_sleep(rb_thread_t
*th
, rb_hrtime_t
*rel
)
265 // No signal assumption allows the use of uninterruptible sleep
267 (void)clock_nanosleep(CLOCK_REALTIME
, 0, rb_hrtime2timespec(&ts
, rel
), NULL
);
271 native_fd_select(int n
, rb_fdset_t
*readfds
, rb_fdset_t
*writefds
, rb_fdset_t
*exceptfds
, struct timeval
*timeout
, rb_thread_t
*th
)
273 return rb_fd_select(n
, readfds
, writefds
, exceptfds
, timeout
);
277 th_has_dedicated_nt(const rb_thread_t
*th
)
283 rb_add_running_thread(rb_thread_t
*th
){
288 rb_del_running_thread(rb_thread_t
*th
)
294 rb_threadptr_sched_free(rb_thread_t
*th
)
300 rb_ractor_sched_barrier_start(rb_vm_t
*vm
, rb_ractor_t
*cr
)
306 rb_ractor_sched_barrier_join(rb_vm_t
*vm
, rb_ractor_t
*cr
)
312 rb_threadptr_remove(rb_thread_t
*th
)
318 rb_thread_sched_mark_zombies(rb_vm_t
*vm
)
324 rb_thread_lock_native_thread(void)
329 #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */