]>
Commit | Line | Data |
---|---|---|
33574c17 | 1 | /* Internal defenitions for pthreads library. |
d614a753 | 2 | Copyright (C) 2000-2020 Free Software Foundation, Inc. |
33574c17 ST |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
ad2b41bf ST |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
33574c17 ST |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
ad2b41bf | 13 | Lesser General Public License for more details. |
33574c17 | 14 | |
ad2b41bf ST |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
33574c17 ST |
18 | |
19 | #ifndef _PT_INTERNAL_H | |
20 | #define _PT_INTERNAL_H 1 | |
21 | ||
22 | #include <pthread.h> | |
23 | #include <stddef.h> | |
24 | #include <sched.h> | |
25 | #include <signal.h> | |
26 | #include <assert.h> | |
27 | #include <bits/types/res_state.h> | |
28 | ||
29 | #include <atomic.h> | |
30 | ||
31 | #include <pt-key.h> | |
32 | ||
33 | #include <pt-sysdep.h> | |
34 | #include <pt-machdep.h> | |
35 | ||
36 | #if IS_IN (libpthread) | |
37 | # include <ldsodefs.h> | |
38 | #endif | |
39 | ||
12e166dd ST |
40 | #include <tls.h> |
41 | ||
33574c17 ST |
42 | /* Thread state. */ |
43 | enum pthread_state | |
44 | { | |
45 | /* The thread is running and joinable. */ | |
46 | PTHREAD_JOINABLE = 0, | |
47 | /* The thread is running and detached. */ | |
48 | PTHREAD_DETACHED, | |
49 | /* A joinable thread exited and its return code is available. */ | |
50 | PTHREAD_EXITED, | |
51 | /* The thread structure is unallocated and available for reuse. */ | |
52 | PTHREAD_TERMINATED | |
53 | }; | |
54 | ||
55 | #ifndef PTHREAD_KEY_MEMBERS | |
56 | # define PTHREAD_KEY_MEMBERS | |
57 | #endif | |
58 | ||
59 | #ifndef PTHREAD_SYSDEP_MEMBERS | |
60 | # define PTHREAD_SYSDEP_MEMBERS | |
61 | #endif | |
62 | ||
33574c17 ST |
63 | /* This structure describes a POSIX thread. */ |
64 | struct __pthread | |
65 | { | |
66 | /* Thread ID. */ | |
67 | pthread_t thread; | |
68 | ||
69 | unsigned int nr_refs; /* Detached threads have a self reference only, | |
70 | while joinable threads have two references. | |
71 | These are used to keep the structure valid at | |
72 | thread destruction. Detaching/joining a thread | |
73 | drops a reference. */ | |
74 | ||
75 | /* Cancellation. */ | |
76 | pthread_mutex_t cancel_lock; /* Protect cancel_xxx members. */ | |
77 | void (*cancel_hook) (void *); /* Called to unblock a thread blocking | |
78 | in a cancellation point (namely, | |
79 | __pthread_cond_timedwait_internal). */ | |
80 | void *cancel_hook_arg; | |
81 | int cancel_state; | |
82 | int cancel_type; | |
83 | int cancel_pending; | |
84 | struct __pthread_cancelation_handler *cancelation_handlers; | |
85 | ||
86 | /* Thread stack. */ | |
87 | void *stackaddr; | |
88 | size_t stacksize; | |
89 | size_t guardsize; | |
90 | int stack; /* Nonzero if the stack was allocated. */ | |
91 | ||
92 | /* Exit status. */ | |
93 | void *status; | |
94 | ||
95 | /* Thread state. */ | |
96 | enum pthread_state state; | |
97 | pthread_mutex_t state_lock; /* Locks the state. */ | |
98 | pthread_cond_t state_cond; /* Signalled when the state changes. */ | |
99 | ||
100 | /* Resolver state. */ | |
101 | struct __res_state res_state; | |
102 | ||
0c036123 ST |
103 | /* Indicates whether is a C11 thread created by thrd_creat. */ |
104 | bool c11; | |
105 | ||
33574c17 ST |
106 | /* Thread context. */ |
107 | struct pthread_mcontext mcontext; | |
108 | ||
109 | PTHREAD_KEY_MEMBERS | |
110 | ||
111 | PTHREAD_SYSDEP_MEMBERS | |
112 | ||
113 | tcbhead_t *tcb; | |
114 | ||
115 | /* Queue links. Since PREVP is used to determine if a thread has been | |
116 | awaken, it must be protected by the queue lock. */ | |
117 | struct __pthread *next, **prevp; | |
118 | }; | |
119 | ||
120 | /* Enqueue an element THREAD on the queue *HEAD. */ | |
121 | static inline void | |
122 | __pthread_enqueue (struct __pthread **head, struct __pthread *thread) | |
123 | { | |
124 | assert (thread->prevp == 0); | |
125 | ||
126 | thread->next = *head; | |
127 | thread->prevp = head; | |
128 | if (*head) | |
129 | (*head)->prevp = &thread->next; | |
130 | *head = thread; | |
131 | } | |
132 | ||
133 | /* Dequeue the element THREAD from the queue it is connected to. */ | |
134 | static inline void | |
135 | __pthread_dequeue (struct __pthread *thread) | |
136 | { | |
137 | assert (thread); | |
138 | assert (thread->prevp); | |
139 | ||
140 | if (thread->next) | |
141 | thread->next->prevp = thread->prevp; | |
142 | *thread->prevp = thread->next; | |
143 | thread->prevp = 0; | |
144 | } | |
145 | ||
146 | /* Iterate over QUEUE storing each element in ELEMENT. */ | |
147 | #define __pthread_queue_iterate(queue, element) \ | |
148 | for (struct __pthread *__pdi_next = (queue); \ | |
149 | ((element) = __pdi_next) \ | |
150 | && ((__pdi_next = __pdi_next->next), \ | |
151 | 1); \ | |
152 | ) | |
153 | ||
154 | /* Iterate over QUEUE dequeuing each element, storing it in | |
155 | ELEMENT. */ | |
156 | #define __pthread_dequeuing_iterate(queue, element) \ | |
157 | for (struct __pthread *__pdi_next = (queue); \ | |
158 | ((element) = __pdi_next) \ | |
159 | && ((__pdi_next = __pdi_next->next), \ | |
160 | ((element)->prevp = 0), \ | |
161 | 1); \ | |
162 | ) | |
163 | ||
164 | /* The total number of threads currently active. */ | |
165 | extern unsigned int __pthread_total; | |
166 | ||
167 | /* The total number of thread IDs currently in use, or on the list of | |
168 | available thread IDs. */ | |
169 | extern int __pthread_num_threads; | |
170 | ||
171 | /* Concurrency hint. */ | |
172 | extern int __pthread_concurrency; | |
173 | ||
174 | /* Array of __pthread structures and its lock. Indexed by the pthread | |
175 | id minus one. (Why not just use the pthread id? Because some | |
176 | brain-dead users of the pthread interface incorrectly assume that 0 | |
177 | is an invalid pthread id.) */ | |
178 | extern struct __pthread **__pthread_threads; | |
1d62a403 | 179 | extern int __pthread_max_threads; |
33574c17 ST |
180 | extern pthread_rwlock_t __pthread_threads_lock; |
181 | ||
182 | #define __pthread_getid(thread) \ | |
1d62a403 | 183 | ({ struct __pthread *__t = NULL; \ |
33574c17 | 184 | __pthread_rwlock_rdlock (&__pthread_threads_lock); \ |
1d62a403 ST |
185 | if (thread <= __pthread_max_threads) \ |
186 | __t = __pthread_threads[thread - 1]; \ | |
33574c17 ST |
187 | __pthread_rwlock_unlock (&__pthread_threads_lock); \ |
188 | __t; }) | |
189 | ||
190 | #define __pthread_setid(thread, pthread) \ | |
191 | __pthread_rwlock_wrlock (&__pthread_threads_lock); \ | |
192 | __pthread_threads[thread - 1] = pthread; \ | |
193 | __pthread_rwlock_unlock (&__pthread_threads_lock); | |
194 | ||
195 | /* Similar to pthread_self, but returns the thread descriptor instead | |
196 | of the thread ID. */ | |
197 | #ifndef _pthread_self | |
198 | extern struct __pthread *_pthread_self (void); | |
199 | #endif | |
200 | \f | |
201 | ||
202 | /* Initialize the pthreads library. */ | |
203 | extern void ___pthread_init (void); | |
204 | ||
205 | /* Internal version of pthread_create. Rather than return the new | |
206 | tid, we return the whole __pthread structure in *PTHREAD. */ | |
207 | extern int __pthread_create_internal (struct __pthread **__restrict pthread, | |
208 | const pthread_attr_t *__restrict attr, | |
209 | void *(*start_routine) (void *), | |
210 | void *__restrict arg); | |
211 | ||
212 | /* Allocate a new thread structure and a pthread thread ID (but not a | |
213 | kernel thread or a stack). THREAD has one reference. */ | |
214 | extern int __pthread_alloc (struct __pthread **thread); | |
215 | ||
216 | /* Deallocate the thread structure. This is the dual of | |
217 | __pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor | |
218 | __pthread_thread_terminate). THREAD loses one reference and is | |
219 | released if the reference counter drops to 0. */ | |
220 | extern void __pthread_dealloc (struct __pthread *thread); | |
221 | ||
222 | ||
223 | /* Allocate a stack of size STACKSIZE. The stack base shall be | |
224 | returned in *STACKADDR. */ | |
225 | extern int __pthread_stack_alloc (void **stackaddr, size_t stacksize); | |
226 | ||
227 | /* Deallocate the stack STACKADDR of size STACKSIZE. */ | |
228 | extern void __pthread_stack_dealloc (void *stackaddr, size_t stacksize); | |
229 | ||
230 | ||
231 | /* Setup thread THREAD's context. */ | |
232 | extern int __pthread_setup (struct __pthread *__restrict thread, | |
233 | void (*entry_point) (struct __pthread *, | |
234 | void *(*)(void *), | |
235 | void *), | |
236 | void *(*start_routine) (void *), | |
237 | void *__restrict arg); | |
238 | ||
239 | ||
240 | /* Allocate a kernel thread (and any miscellaneous system dependent | |
241 | resources) for THREAD; it must not be placed on the run queue. */ | |
242 | extern int __pthread_thread_alloc (struct __pthread *thread); | |
243 | ||
244 | /* Start THREAD making it eligible to run. */ | |
245 | extern int __pthread_thread_start (struct __pthread *thread); | |
246 | ||
247 | /* Terminate the kernel thread associated with THREAD, and deallocate its | |
248 | stack as well as any other kernel resource associated with it. | |
249 | In addition, THREAD looses one reference. | |
250 | ||
251 | This function can be called by any thread, including the target thread. | |
252 | Since some resources that are destroyed along the kernel thread are | |
253 | stored in thread-local variables, the conditions required for this | |
254 | function to behave correctly are a bit unusual : as long as the target | |
255 | thread hasn't been started, any thread can terminate it, but once it | |
256 | has started, no other thread can terminate it, so that thread-local | |
257 | variables created by that thread are correctly released. */ | |
258 | extern void __pthread_thread_terminate (struct __pthread *thread); | |
259 | ||
260 | ||
261 | /* Called by a thread just before it calls the provided start | |
262 | routine. */ | |
263 | extern void __pthread_startup (void); | |
264 | ||
265 | /* Block THREAD. */ | |
266 | extern void __pthread_block (struct __pthread *thread); | |
267 | ||
268 | /* Block THREAD until *ABSTIME is reached. */ | |
269 | extern error_t __pthread_timedblock (struct __pthread *__restrict thread, | |
270 | const struct timespec *__restrict abstime, | |
271 | clockid_t clock_id); | |
272 | ||
e9644c20 ST |
273 | /* Block THREAD with interrupts. */ |
274 | extern error_t __pthread_block_intr (struct __pthread *thread); | |
275 | ||
276 | /* Block THREAD until *ABSTIME is reached, with interrupts. */ | |
277 | extern error_t __pthread_timedblock_intr (struct __pthread *__restrict thread, | |
278 | const struct timespec *__restrict abstime, | |
279 | clockid_t clock_id); | |
280 | ||
33574c17 ST |
281 | /* Wakeup THREAD. */ |
282 | extern void __pthread_wakeup (struct __pthread *thread); | |
283 | ||
284 | ||
285 | /* Perform a cancelation. The CANCEL_LOCK member of the given thread must | |
286 | be locked before calling this function, which must unlock it. */ | |
287 | extern int __pthread_do_cancel (struct __pthread *thread); | |
288 | ||
289 | ||
290 | /* Initialize the thread specific data structures. THREAD must be the | |
291 | calling thread. */ | |
292 | extern error_t __pthread_init_specific (struct __pthread *thread); | |
293 | ||
294 | /* Call the destructors on all of the thread specific data in THREAD. | |
295 | THREAD must be the calling thread. */ | |
296 | extern void __pthread_destroy_specific (struct __pthread *thread); | |
297 | ||
298 | ||
299 | /* Initialize newly create thread *THREAD's signal state data | |
300 | structures. */ | |
301 | extern error_t __pthread_sigstate_init (struct __pthread *thread); | |
302 | ||
303 | /* Destroy the signal state data structures associcated with thread | |
304 | *THREAD. */ | |
305 | extern void __pthread_sigstate_destroy (struct __pthread *thread); | |
306 | ||
307 | /* Modify thread *THREAD's signal state. */ | |
308 | extern error_t __pthread_sigstate (struct __pthread *__restrict thread, int how, | |
309 | const sigset_t *__restrict set, | |
310 | sigset_t *__restrict oset, | |
311 | int clear_pending); | |
cd94860c ST |
312 | |
313 | /* If supported, check that MUTEX is locked by the caller. */ | |
314 | extern int __pthread_mutex_checklocked (pthread_mutex_t *mtx); | |
33574c17 ST |
315 | \f |
316 | ||
317 | /* Default thread attributes. */ | |
34f168fb | 318 | extern struct __pthread_attr __pthread_default_attr; |
33574c17 ST |
319 | |
320 | /* Default barrier attributes. */ | |
321 | extern const struct __pthread_barrierattr __pthread_default_barrierattr; | |
322 | ||
33574c17 ST |
323 | /* Default rdlock attributes. */ |
324 | extern const struct __pthread_rwlockattr __pthread_default_rwlockattr; | |
325 | ||
326 | /* Default condition attributes. */ | |
327 | extern const struct __pthread_condattr __pthread_default_condattr; | |
328 | ||
329 | #endif /* pt-internal.h */ |