Ruby  3.4.0dev (2024-12-06 revision 892c46283a5ea4179500d951c9d4866c0051f27b)
thread_pthread.h (892c46283a5ea4179500d951c9d4866c0051f27b)
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
46 struct rb_thread_sched_item {
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 
74 struct 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
117 struct 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  # ifdef __APPLE__
137  // on Darwin, 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
147 typedef pthread_key_t native_tls_key_t;
148 
149 static inline void *
150 native_tls_get(native_tls_key_t key)
151 {
152  // return value should be checked by caller
153  return pthread_getspecific(key);
154 }
155 
156 static inline void
157 native_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 
164 RUBY_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
void rb_bug(const char *fmt,...)
Interpreter panic switch.
Definition: error.c:1089
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
Definition: io.h:2