Ruby  3.4.0dev (2024-11-05 revision e440268d51fe02b303e3817a7a733a0dac1c5091)
thread_pthread.h (e440268d51fe02b303e3817a7a733a0dac1c5091)
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  NOINLINE(struct rb_execution_context_struct *rb_current_ec_noinline(void));
136 
137  # ifdef __APPLE__
138  // on Darwin, TLS can not be accessed across .so
139  NOINLINE(struct rb_execution_context_struct *rb_current_ec(void));
140  # else
141  RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
142 
143  // for RUBY_DEBUG_LOG()
144  RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER rb_atomic_t ruby_nt_serial;
145  #define RUBY_NT_SERIAL 1
146  # endif
147 #else
148 typedef pthread_key_t native_tls_key_t;
149 
150 static inline void *
151 native_tls_get(native_tls_key_t key)
152 {
153  // return value should be checked by caller
154  return pthread_getspecific(key);
155 }
156 
157 static inline void
158 native_tls_set(native_tls_key_t key, void *ptr)
159 {
160  if (UNLIKELY(pthread_setspecific(key, ptr) != 0)) {
161  rb_bug("pthread_setspecific error");
162  }
163 }
164 
165 RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
166 #endif
167 
168 #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:1088
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
Definition: io.h:2