Ruby 3.2.1p31 (2023-02-08 revision 31819e82c88c6f8ecfaeb162519bfa26a14b21fd)
thread_pthread.h
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// per-Thead scheduler helper data
22 union {
23 struct ccan_list_node ubf;
24 struct ccan_list_node readyq; // protected by sched->lock
25 } node;
26};
27
28struct rb_native_thread {
29 int id;
30
31 rb_nativethread_id_t thread_id;
32
33#ifdef RB_THREAD_T_HAS_NATIVE_ID
34 int tid;
35#endif
36
37 struct rb_thread_struct *running_thread;
38
39 // to control native thread
40#if defined(__GLIBC__) || defined(__FreeBSD__)
41 union
42#else
43 /*
44 * assume the platform condvars are badly implemented and have a
45 * "memory" of which mutex they're associated with
46 */
47 struct
48#endif
49 {
50 rb_nativethread_cond_t intr; /* th->interrupt_lock */
51 rb_nativethread_cond_t readyq; /* use sched->lock */
52 } cond;
53
54#ifdef USE_SIGALTSTACK
55 void *altstack;
56#endif
57};
58
59#undef except
60#undef try
61#undef leave
62#undef finally
63
64// per-Ractor
65struct rb_thread_sched {
66 /* fast path */
67
68 const struct rb_thread_struct *running; // running thread or NULL
70
71 /*
72 * slow path, protected by ractor->thread_sched->lock
73 * - @readyq - FIFO queue of threads waiting for running
74 * - @timer - it handles timeslices for @current. It is any one thread
75 * in @waitq, there is no @timer if @waitq is empty, but always
76 * a @timer if @waitq has entries
77 * - @timer_err tracks timeslice limit, the timeslice only resets
78 * when pthread_cond_timedwait returns ETIMEDOUT, so frequent
79 * switching between contended/uncontended GVL won't reset the
80 * timer.
81 */
82 struct ccan_list_head readyq;
83 const struct rb_thread_struct *timer;
84 int timer_err;
85
86 /* yield */
87 rb_nativethread_cond_t switch_cond;
88 rb_nativethread_cond_t switch_wait_cond;
89 int need_yield;
90 int wait_yield;
91};
92
93#ifndef RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED
94# if __STDC_VERSION__ >= 201112
95# define RB_THREAD_LOCAL_SPECIFIER _Thread_local
96# elif defined(__GNUC__)
97 /* note that ICC (linux) and Clang are covered by __GNUC__ */
98# define RB_THREAD_LOCAL_SPECIFIER __thread
99# endif
100#endif
101
102RUBY_SYMBOL_EXPORT_BEGIN
103#ifdef RB_THREAD_LOCAL_SPECIFIER
104# ifdef __APPLE__
105// on Darwin, TLS can not be accessed across .so
106struct rb_execution_context_struct *rb_current_ec(void);
107void rb_current_ec_set(struct rb_execution_context_struct *);
108# else
109RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
110# endif
111#else
112typedef pthread_key_t native_tls_key_t;
113
114static inline void *
115native_tls_get(native_tls_key_t key)
116{
117 // return value should be checked by caller
118 return pthread_getspecific(key);
119}
120
121static inline void
122native_tls_set(native_tls_key_t key, void *ptr)
123{
124 if (UNLIKELY(pthread_setspecific(key, ptr) != 0)) {
125 rb_bug("pthread_setspecific error");
126 }
127}
128
129RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
130#endif
131RUBY_SYMBOL_EXPORT_END
132
133#endif /* RUBY_THREAD_PTHREAD_H */
#define RUBY_EXTERN
Declaration of externally visible global variables.
Definition dllexport.h:47
void rb_bug(const char *fmt,...)
Interpreter panic switch.
Definition error.c:794