1 /* Internal defenitions for pthreads library.
2 Copyright (C) 2000-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
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.
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
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #ifndef _PT_INTERNAL_H
20 #define _PT_INTERNAL_H 1
27 #include <bits/types/res_state.h>
33 #include <pt-sysdep.h>
34 #include <pt-machdep.h>
36 #if IS_IN (libpthread)
37 # include <ldsodefs.h>
45 /* The thread is running and joinable. */
47 /* The thread is running and detached. */
49 /* A joinable thread exited and its return code is available. */
51 /* The thread structure is unallocated and available for reuse. */
55 #ifndef PTHREAD_KEY_MEMBERS
56 # define PTHREAD_KEY_MEMBERS
59 #ifndef PTHREAD_SYSDEP_MEMBERS
60 # define PTHREAD_SYSDEP_MEMBERS
63 /* This structure describes a POSIX thread. */
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
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
;
89 int stack
; /* Nonzero if the stack was allocated. */
95 enum pthread_state state
;
96 pthread_mutex_t state_lock
; /* Locks the state. */
97 pthread_cond_t state_cond
; /* Signalled when the state changes. */
100 struct __res_state res_state
;
102 /* Indicates whether is a C11 thread created by thrd_creat. */
105 /* Initial sigset for the thread. */
106 sigset_t init_sigset
;
108 /* Thread context. */
109 struct pthread_mcontext mcontext
;
113 PTHREAD_SYSDEP_MEMBERS
117 /* Queue links. Since PREVP is used to determine if a thread has been
118 awaken, it must be protected by the queue lock. */
119 struct __pthread
*next
, **prevp
;
122 /* Enqueue an element THREAD on the queue *HEAD. */
124 __pthread_enqueue (struct __pthread
**head
, struct __pthread
*thread
)
126 assert (thread
->prevp
== 0);
128 thread
->next
= *head
;
129 thread
->prevp
= head
;
131 (*head
)->prevp
= &thread
->next
;
135 /* Dequeue the element THREAD from the queue it is connected to. */
137 __pthread_dequeue (struct __pthread
*thread
)
140 assert (thread
->prevp
);
143 thread
->next
->prevp
= thread
->prevp
;
144 *thread
->prevp
= thread
->next
;
148 /* Iterate over QUEUE storing each element in ELEMENT. */
149 #define __pthread_queue_iterate(queue, element) \
150 for (struct __pthread *__pdi_next = (queue); \
151 ((element) = __pdi_next) \
152 && ((__pdi_next = __pdi_next->next), \
156 /* Iterate over QUEUE dequeuing each element, storing it in
158 #define __pthread_dequeuing_iterate(queue, element) \
159 for (struct __pthread *__pdi_next = (queue); \
160 ((element) = __pdi_next) \
161 && ((__pdi_next = __pdi_next->next), \
162 ((element)->prevp = 0), \
166 /* The total number of threads currently active. */
167 extern unsigned int __pthread_total
;
169 /* The total number of thread IDs currently in use, or on the list of
170 available thread IDs. */
171 extern int __pthread_num_threads
;
173 /* Concurrency hint. */
174 extern int __pthread_concurrency
;
176 /* Array of __pthread structures and its lock. Indexed by the pthread
177 id minus one. (Why not just use the pthread id? Because some
178 brain-dead users of the pthread interface incorrectly assume that 0
179 is an invalid pthread id.) */
180 extern struct __pthread
**__pthread_threads
;
181 extern int __pthread_max_threads
;
182 extern pthread_rwlock_t __pthread_threads_lock
;
184 #define __pthread_getid(thread) \
185 ({ struct __pthread *__t = NULL; \
186 __pthread_rwlock_rdlock (&__pthread_threads_lock); \
187 if (thread <= __pthread_max_threads) \
188 __t = __pthread_threads[thread - 1]; \
189 __pthread_rwlock_unlock (&__pthread_threads_lock); \
192 #define __pthread_setid(thread, pthread) \
193 __pthread_rwlock_wrlock (&__pthread_threads_lock); \
194 __pthread_threads[thread - 1] = pthread; \
195 __pthread_rwlock_unlock (&__pthread_threads_lock);
197 /* Similar to pthread_self, but returns the thread descriptor instead
199 #ifndef _pthread_self
200 extern struct __pthread
*_pthread_self (void);
203 /* Stores the stack of cleanup handlers for the thread. */
204 extern __thread
struct __pthread_cancelation_handler
*__pthread_cleanup_stack
;
207 /* Initialize the pthreads library. */
208 extern void ___pthread_init (void);
210 /* Internal version of pthread_create. Rather than return the new
211 tid, we return the whole __pthread structure in *PTHREAD. */
212 extern int __pthread_create_internal (struct __pthread
**__restrict pthread
,
213 const pthread_attr_t
*__restrict attr
,
214 void *(*start_routine
) (void *),
215 void *__restrict arg
);
217 /* Allocate a new thread structure and a pthread thread ID (but not a
218 kernel thread or a stack). THREAD has one reference. */
219 extern int __pthread_alloc (struct __pthread
**thread
);
221 /* Deallocate the thread structure. This is the dual of
222 __pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor
223 __pthread_thread_terminate). THREAD loses one reference and is
224 released if the reference counter drops to 0. */
225 extern void __pthread_dealloc (struct __pthread
*thread
);
228 /* Allocate a stack of size STACKSIZE. The stack base shall be
229 returned in *STACKADDR. */
230 extern int __pthread_stack_alloc (void **stackaddr
, size_t stacksize
);
232 /* Deallocate the stack STACKADDR of size STACKSIZE. */
233 extern void __pthread_stack_dealloc (void *stackaddr
, size_t stacksize
);
236 /* Setup thread THREAD's context. */
237 extern int __pthread_setup (struct __pthread
*__restrict thread
,
238 void (*entry_point
) (struct __pthread
*,
241 void *(*start_routine
) (void *),
242 void *__restrict arg
);
245 /* Allocate a kernel thread (and any miscellaneous system dependent
246 resources) for THREAD; it must not be placed on the run queue. */
247 extern int __pthread_thread_alloc (struct __pthread
*thread
);
249 /* Start THREAD making it eligible to run. */
250 extern int __pthread_thread_start (struct __pthread
*thread
);
252 /* Terminate the kernel thread associated with THREAD, and deallocate its
253 stack as well as any other kernel resource associated with it.
254 In addition, THREAD looses one reference.
256 This function can be called by any thread, including the target thread.
257 Since some resources that are destroyed along the kernel thread are
258 stored in thread-local variables, the conditions required for this
259 function to behave correctly are a bit unusual : as long as the target
260 thread hasn't been started, any thread can terminate it, but once it
261 has started, no other thread can terminate it, so that thread-local
262 variables created by that thread are correctly released. */
263 extern void __pthread_thread_terminate (struct __pthread
*thread
);
266 /* Called by a thread just before it calls the provided start
268 extern void __pthread_startup (void);
271 extern void __pthread_block (struct __pthread
*thread
);
273 /* Block THREAD until *ABSTIME is reached. */
274 extern error_t
__pthread_timedblock (struct __pthread
*__restrict thread
,
275 const struct timespec
*__restrict abstime
,
278 /* Block THREAD with interrupts. */
279 extern error_t
__pthread_block_intr (struct __pthread
*thread
);
281 /* Block THREAD until *ABSTIME is reached, with interrupts. */
282 extern error_t
__pthread_timedblock_intr (struct __pthread
*__restrict thread
,
283 const struct timespec
*__restrict abstime
,
287 extern void __pthread_wakeup (struct __pthread
*thread
);
290 /* Perform a cancelation. The CANCEL_LOCK member of the given thread must
291 be locked before calling this function, which must unlock it. */
292 extern int __pthread_do_cancel (struct __pthread
*thread
);
295 /* Initialize the thread specific data structures. THREAD must be the
297 extern error_t
__pthread_init_specific (struct __pthread
*thread
);
299 /* Call the destructors on all of the thread specific data in THREAD.
300 THREAD must be the calling thread. */
301 extern void __pthread_destroy_specific (struct __pthread
*thread
);
304 /* Initialize newly create thread *THREAD's signal state data
306 extern error_t
__pthread_sigstate_init (struct __pthread
*thread
);
308 /* Destroy the signal state data structures associcated with thread
310 extern void __pthread_sigstate_destroy (struct __pthread
*thread
);
312 /* Modify thread *THREAD's signal state. */
313 extern error_t
__pthread_sigstate (struct __pthread
*__restrict thread
, int how
,
314 const sigset_t
*__restrict set
,
315 sigset_t
*__restrict oset
,
318 /* If supported, check that MUTEX is locked by the caller. */
319 extern int __pthread_mutex_checklocked (pthread_mutex_t
*mtx
);
322 /* Default thread attributes. */
323 extern struct __pthread_attr __pthread_default_attr
;
325 /* Default barrier attributes. */
326 extern const struct __pthread_barrierattr __pthread_default_barrierattr
;
328 /* Default rdlock attributes. */
329 extern const struct __pthread_rwlockattr __pthread_default_rwlockattr
;
331 /* Default condition attributes. */
332 extern const struct __pthread_condattr __pthread_default_condattr
;
334 /* Semaphore encoding.
335 See nptl implementation for the details. */
338 #if __HAVE_64B_ATOMICS
339 /* The data field holds both value (in the least-significant 32 bits) and
341 # if __BYTE_ORDER == __LITTLE_ENDIAN
342 # define SEM_VALUE_OFFSET 0
343 # elif __BYTE_ORDER == __BIG_ENDIAN
344 # define SEM_VALUE_OFFSET 1
346 # error Unsupported byte order.
348 # define SEM_NWAITERS_SHIFT 32
349 # define SEM_VALUE_MASK (~(unsigned int)0)
352 #define __SEMAPHORE_INITIALIZER(value, pshared) \
353 { (value), (pshared) }
355 # define SEM_VALUE_SHIFT 1
356 # define SEM_NWAITERS_MASK ((unsigned int)1)
358 unsigned int nwaiters
;
360 #define __SEMAPHORE_INITIALIZER(value, pshared) \
361 { (value) << SEM_VALUE_SHIFT, 0, (pshared) }
365 extern int __sem_waitfast (struct new_sem
*isem
, int definitive_result
);
367 #endif /* pt-internal.h */