Ruby 3.5.0dev (2025-02-22 revision b17f984e4e903d3ece3013c1488279d1947dfc39)
thread_pthread.h (b17f984e4e903d3ece3013c1488279d1947dfc39)
1#ifndef RUBY_THREAD_PTHREAD_H
2#define RUBY_THREAD_PTHREAD_H
3/**********************************************************************
4
5 thread_pthread.h -
6
7 $Author$
8
9 Copyright (C) 2004-2007 Koichi Sasada
10
11**********************************************************************/
12
13#ifdef HAVE_PTHREAD_NP_H
14#include <pthread_np.h>
15#endif
16
17#define RB_NATIVETHREAD_LOCK_INIT PTHREAD_MUTEX_INITIALIZER
18#define RB_NATIVETHREAD_COND_INIT PTHREAD_COND_INITIALIZER
19
20// this data should be protected by timer_th.waiting_lock
22 enum thread_sched_waiting_flag {
23 thread_sched_waiting_none = 0x00,
24 thread_sched_waiting_timeout = 0x01,
25 thread_sched_waiting_io_read = 0x02,
26 thread_sched_waiting_io_write = 0x08,
27 thread_sched_waiting_io_force = 0x40, // ignore readable
28 } flags;
29
30 struct {
31 // should be compat with hrtime.h
32#ifdef MY_RUBY_BUILD_MAY_TIME_TRAVEL
33 int128_t timeout;
34#else
35 uint64_t timeout;
36#endif
37 int fd; // -1 for timeout only
38 int result;
39 } data;
40
41 // connected to timer_th.waiting
42 struct ccan_list_node node;
43};
44
45// per-Thead scheduler helper data
47 struct {
48 struct ccan_list_node ubf;
49
50 // connected to ractor->threads.sched.reqdyq
51 // locked by ractor->threads.sched.lock
52 struct ccan_list_node readyq;
53
54 // connected to vm->ractor.sched.timeslice_threads
55 // locked by vm->ractor.sched.lock
56 struct ccan_list_node timeslice_threads;
57
58 // connected to vm->ractor.sched.running_threads
59 // locked by vm->ractor.sched.lock
60 struct ccan_list_node running_threads;
61
62 // connected to vm->ractor.sched.zombie_threads
63 struct ccan_list_node zombie_threads;
64 } node;
65
66 struct rb_thread_sched_waiting waiting_reason;
67
68 bool finished;
69 bool malloc_stack;
70 void *context_stack;
71 struct coroutine_context *context;
72};
73
74struct rb_native_thread {
75 rb_atomic_t serial;
76 struct rb_vm_struct *vm;
77
78 rb_nativethread_id_t thread_id;
79
80#ifdef RB_THREAD_T_HAS_NATIVE_ID
81 int tid;
82#endif
83
84 struct rb_thread_struct *running_thread;
85
86 // to control native thread
87#if defined(__GLIBC__) || defined(__FreeBSD__)
88 union
89#else
90 /*
91 * assume the platform condvars are badly implemented and have a
92 * "memory" of which mutex they're associated with
93 */
94 struct
95#endif
96 {
97 rb_nativethread_cond_t intr; /* th->interrupt_lock */
98 rb_nativethread_cond_t readyq; /* use sched->lock */
99 } cond;
100
101#ifdef USE_SIGALTSTACK
102 void *altstack;
103#endif
104
105 struct coroutine_context *nt_context;
106 int dedicated;
107
108 size_t machine_stack_maxsize;
109};
110
111#undef except
112#undef try
113#undef leave
114#undef finally
115
116// per-Ractor
117struct rb_thread_sched {
118 rb_nativethread_lock_t lock_;
119#if VM_CHECK_MODE
120 struct rb_thread_struct *lock_owner;
121#endif
122 struct rb_thread_struct *running; // running thread or NULL
123 bool is_running;
124 bool is_running_timeslice;
125 bool enable_mn_threads;
126
127 struct ccan_list_head readyq;
128 int readyq_cnt;
129 // ractor scheduling
130 struct ccan_list_node grq_node;
131};
132
133#ifdef RB_THREAD_LOCAL_SPECIFIER
134 NOINLINE(void rb_current_ec_set(struct rb_execution_context_struct *));
135
136 # if defined(__arm64__) || defined(__aarch64__)
137 // on Arm64, TLS can not be accessed across .so
138 NOINLINE(struct rb_execution_context_struct *rb_current_ec(void));
139 # else
140 RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
141
142 // for RUBY_DEBUG_LOG()
143 RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER rb_atomic_t ruby_nt_serial;
144 #define RUBY_NT_SERIAL 1
145 # endif
146#else
147typedef pthread_key_t native_tls_key_t;
148
149static inline void *
150native_tls_get(native_tls_key_t key)
151{
152 // return value should be checked by caller
153 return pthread_getspecific(key);
154}
155
156static inline void
157native_tls_set(native_tls_key_t key, void *ptr)
158{
159 if (UNLIKELY(pthread_setspecific(key, ptr) != 0)) {
160 rb_bug("pthread_setspecific error");
161 }
162}
163
164RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
165#endif
166
167#endif /* RUBY_THREAD_PTHREAD_H */
std::atomic< unsigned > rb_atomic_t
Type that is eligible for atomic operations.
Definition atomic.h:69
#define RUBY_EXTERN
Declaration of externally visible global variables.
Definition dllexport.h:45