1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #ifndef _PTHREADP_H
21: #define _PTHREADP_H 1
22:
23: #include <pthread.h>
24: #include <setjmp.h>
25: #include <stdbool.h>
26: #include <sys/syscall.h>
27: #include "descr.h"
28: #include <tls.h>
29: #include <lowlevellock.h>
30: #include <stackinfo.h>
31: #include <internaltypes.h>
32: #include <pthread-functions.h>
33: #include <atomic.h>
34: #include <kernel-features.h>
35:
36:
37:
38: #ifndef THREAD_ATOMIC_CMPXCHG_VAL
39: # define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, new, old) \
40: atomic_compare_and_exchange_val_acq (&(descr)->member, new, old)
41: #endif
42:
43: #ifndef THREAD_ATOMIC_BIT_SET
44: # define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
45: atomic_bit_set (&(descr)->member, bit)
46: #endif
47:
48:
49:
50: #ifndef MAX_ADAPTIVE_COUNT
51: # define MAX_ADAPTIVE_COUNT 100
52: #endif
53:
54:
55:
56: #define PTHREAD_MUTEX_INCONSISTENT INT_MAX
57:
58: #define PTHREAD_MUTEX_NOTRECOVERABLE (INT_MAX - 1)
59:
60:
61:
62: enum
63: {
64: PTHREAD_MUTEX_KIND_MASK_NP = 3,
65: PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
66: PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
67: = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
68: PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP
69: = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
70: PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
71: = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
72: PTHREAD_MUTEX_PRIO_INHERIT_NP = 32,
73: PTHREAD_MUTEX_PI_NORMAL_NP
74: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_NORMAL,
75: PTHREAD_MUTEX_PI_RECURSIVE_NP
76: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
77: PTHREAD_MUTEX_PI_ERRORCHECK_NP
78: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
79: PTHREAD_MUTEX_PI_ADAPTIVE_NP
80: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
81: PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP
82: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP,
83: PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP
84: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_RECURSIVE_NP,
85: PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP
86: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP,
87: PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP
88: = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP,
89: PTHREAD_MUTEX_PRIO_PROTECT_NP = 64,
90: PTHREAD_MUTEX_PP_NORMAL_NP
91: = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_NORMAL,
92: PTHREAD_MUTEX_PP_RECURSIVE_NP
93: = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
94: PTHREAD_MUTEX_PP_ERRORCHECK_NP
95: = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
96: PTHREAD_MUTEX_PP_ADAPTIVE_NP
97: = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP
98: };
99: #define PTHREAD_MUTEX_PSHARED_BIT 128
100:
101: #define PTHREAD_MUTEX_TYPE(m) \
102: ((m)->__data.__kind & 127)
103:
104: #if LLL_PRIVATE == 0 && LLL_SHARED == 128
105: # define PTHREAD_MUTEX_PSHARED(m) \
106: ((m)->__data.__kind & 128)
107: #else
108: # define PTHREAD_MUTEX_PSHARED(m) \
109: (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
110: #endif
111:
112:
113:
114: #define PTHREAD_ROBUST_MUTEX_PSHARED(m) LLL_SHARED
115:
116:
117:
118:
119:
120:
121: #define PTHREAD_MUTEX_PRIO_CEILING_SHIFT 19
122: #define PTHREAD_MUTEX_PRIO_CEILING_MASK 0xfff80000
123:
124:
125:
126: #define PTHREAD_MUTEXATTR_PROTOCOL_SHIFT 28
127: #define PTHREAD_MUTEXATTR_PROTOCOL_MASK 0x30000000
128: #define PTHREAD_MUTEXATTR_PRIO_CEILING_SHIFT 12
129: #define PTHREAD_MUTEXATTR_PRIO_CEILING_MASK 0x00fff000
130: #define PTHREAD_MUTEXATTR_FLAG_ROBUST 0x40000000
131: #define PTHREAD_MUTEXATTR_FLAG_PSHARED 0x80000000
132: #define PTHREAD_MUTEXATTR_FLAG_BITS \
133: (PTHREAD_MUTEXATTR_FLAG_ROBUST | PTHREAD_MUTEXATTR_FLAG_PSHARED \
134: | PTHREAD_MUTEXATTR_PROTOCOL_MASK | PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
135:
136:
137:
138: #define PTHREAD_RWLOCK_PREFER_READER_P(rwlock) \
139: ((rwlock)->__data.__flags == 0)
140:
141:
142:
143: #define FUTEX_WAITERS 0x80000000
144: #define FUTEX_OWNER_DIED 0x40000000
145: #define FUTEX_TID_MASK 0x3fffffff
146:
147:
148:
149:
150:
151:
152: extern size_t __default_stacksize attribute_hidden;
153:
154:
155: extern size_t __static_tls_size attribute_hidden;
156: extern size_t __static_tls_align_m1 attribute_hidden;
157:
158:
159: extern int __is_smp attribute_hidden;
160:
161:
162: extern list_t __stack_user;
163: hidden_proto (__stack_user)
164:
165:
166: extern struct pthread_attr *__attr_list attribute_hidden;
167: extern int __attr_list_lock attribute_hidden;
168:
169:
170: extern int __current_sigrtmin attribute_hidden;
171:
172: extern int __current_sigrtmax attribute_hidden;
173:
174:
175: extern int __concurrency_level attribute_hidden;
176:
177:
178: extern struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX];
179: hidden_proto (__pthread_keys)
180:
181:
182: extern unsigned int __nptl_nthreads attribute_hidden;
183:
184: #ifndef __ASSUME_SET_ROBUST_LIST
185:
186: extern int __set_robust_list_avail attribute_hidden;
187: #endif
188:
189:
190: extern int __sched_fifo_min_prio attribute_hidden;
191: extern int __sched_fifo_max_prio attribute_hidden;
192: extern void __init_sched_fifo_prio (void) attribute_hidden;
193: extern int __pthread_tpp_change_priority (int prev_prio, int new_prio)
194: attribute_hidden;
195: extern int __pthread_current_priority (void) attribute_hidden;
196:
197:
198:
199: extern int __pthread_debug attribute_hidden;
200:
201: #if 0
202: # define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
203: # define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
204: # define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd)
205: #else
206: # define DEBUGGING_P 0
207:
208:
209:
210: # define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0)
211: # define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0)
212: #endif
213:
214:
215:
216: #define CANCELLATION_P(self) \
217: do { \
218: int cancelhandling = THREAD_GETMEM (self, cancelhandling); \
219: if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
220: { \
221: THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
222: __do_cancel (); \
223: } \
224: } while (0)
225:
226:
227: extern void __pthread_unwind (__pthread_unwind_buf_t *__buf)
228: __cleanup_fct_attribute __attribute ((__noreturn__))
229: #if !defined SHARED && !defined IS_IN_libpthread
230: weak_function
231: #endif
232: ;
233: extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
234: __cleanup_fct_attribute __attribute ((__noreturn__))
235: #ifndef SHARED
236: weak_function
237: #endif
238: ;
239: extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
240: __cleanup_fct_attribute;
241: extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
242: __cleanup_fct_attribute;
243: #if defined NOT_IN_libc && defined IS_IN_libpthread
244: hidden_proto (__pthread_unwind)
245: hidden_proto (__pthread_unwind_next)
246: hidden_proto (__pthread_register_cancel)
247: hidden_proto (__pthread_unregister_cancel)
248: # ifdef SHARED
249: extern void attribute_hidden pthread_cancel_init (void);
250: # endif
251: #endif
252:
253:
254:
255: static inline void
256: __attribute ((noreturn, always_inline))
257: __do_cancel (void)
258: {
259: struct pthread *self = THREAD_SELF;
260:
261:
262: THREAD_ATOMIC_BIT_SET (self, cancelhandling, EXITING_BIT);
263:
264: __pthread_unwind ((__pthread_unwind_buf_t *)
265: THREAD_GETMEM (self, cleanup_jmp_buf));
266: }
267:
268:
269:
270: #define CANCEL_ASYNC() \
271: __pthread_enable_asynccancel ()
272:
273: #define CANCEL_RESET(oldtype) \
274: __pthread_disable_asynccancel (oldtype)
275:
276: #if !defined NOT_IN_libc
277:
278: # define LIBC_CANCEL_ASYNC() \
279: __libc_enable_asynccancel ()
280:
281: # define LIBC_CANCEL_RESET(oldtype) \
282: __libc_disable_asynccancel (oldtype)
283: # define LIBC_CANCEL_HANDLED() \
284: __asm (".globl " __SYMBOL_PREFIX "__libc_enable_asynccancel"); \
285: __asm (".globl " __SYMBOL_PREFIX "__libc_disable_asynccancel")
286: #elif defined NOT_IN_libc && defined IS_IN_libpthread
287: # define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
288: # define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
289: # define LIBC_CANCEL_HANDLED() \
290: __asm (".globl " __SYMBOL_PREFIX "__pthread_enable_asynccancel"); \
291: __asm (".globl " __SYMBOL_PREFIX "__pthread_disable_asynccancel")
292: #elif defined NOT_IN_libc && defined IS_IN_librt
293: # define LIBC_CANCEL_ASYNC() \
294: __librt_enable_asynccancel ()
295: # define LIBC_CANCEL_RESET(val) \
296: __librt_disable_asynccancel (val)
297: # define LIBC_CANCEL_HANDLED() \
298: __asm (".globl " __SYMBOL_PREFIX "__librt_enable_asynccancel"); \
299: __asm (".globl " __SYMBOL_PREFIX "__librt_disable_asynccancel")
300: #else
301: # define LIBC_CANCEL_ASYNC() 0
302: # define LIBC_CANCEL_RESET(val) ((void)(val))
303: # define LIBC_CANCEL_HANDLED()
304: #endif
305:
306:
307: #define SIGCANCEL __SIGRTMIN
308:
309:
310:
311:
312:
313: #define SIGTIMER SIGCANCEL
314:
315:
316:
317: #define SIGSETXID (__SIGRTMIN + 1)
318:
319:
320: extern struct xid_command *__xidcmd attribute_hidden;
321:
322:
323:
324:
325:
326: extern struct pthread *__find_in_stack_list (struct pthread *pd)
327: attribute_hidden internal_function;
328:
329:
330:
331: extern void __free_tcb (struct pthread *pd) attribute_hidden internal_function;
332:
333:
334: extern void __deallocate_stack (struct pthread *pd)
335: attribute_hidden internal_function;
336:
337:
338:
339: extern void __reclaim_stacks (void) attribute_hidden;
340:
341:
342: extern int __make_stacks_executable (void **stack_endp)
343: internal_function attribute_hidden;
344:
345:
346: extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
347: #if defined NOT_IN_libc && defined IS_IN_libpthread
348: hidden_proto (__pthread_cleanup_upto)
349: #endif
350:
351:
352:
353: extern int __pthread_create_2_1 (pthread_t *newthread,
354: const pthread_attr_t *attr,
355: void *(*start_routine) (void *), void *arg);
356: extern int __pthread_create_2_0 (pthread_t *newthread,
357: const pthread_attr_t *attr,
358: void *(*start_routine) (void *), void *arg);
359: extern int __pthread_attr_init_2_1 (pthread_attr_t *attr);
360: extern int __pthread_attr_init_2_0 (pthread_attr_t *attr);
361:
362:
363:
364: extern void __nptl_create_event (void);
365: extern void __nptl_death_event (void);
366: hidden_proto (__nptl_create_event)
367: hidden_proto (__nptl_death_event)
368:
369:
370: #ifdef TLS_MULTIPLE_THREADS_IN_TCB
371: extern void __libc_pthread_init (unsigned long int *ptr,
372: void (*reclaim) (void),
373: const struct pthread_functions *functions)
374: internal_function;
375: #else
376: extern int *__libc_pthread_init (unsigned long int *ptr,
377: void (*reclaim) (void),
378: const struct pthread_functions *functions)
379: internal_function;
380:
381:
382: extern int __pthread_multiple_threads attribute_hidden;
383:
384: extern int *__libc_multiple_threads_ptr attribute_hidden;
385: #endif
386:
387:
388: extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden
389: #ifdef SHARED
390: ;
391: #else
392: weak_function;
393: #define __find_thread_by_id(tid) \
394: (__find_thread_by_id ? (__find_thread_by_id) (tid) : (struct pthread *) NULL)
395: #endif
396:
397: extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
398:
399:
400:
401: extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
402: struct sched_param *param);
403: extern int __pthread_setschedparam (pthread_t thread_id, int policy,
404: const struct sched_param *param);
405: extern int __pthread_setcancelstate (int state, int *oldstate);
406: extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
407: __const pthread_mutexattr_t *__mutexattr);
408: extern int __pthread_mutex_init_internal (pthread_mutex_t *__mutex,
409: __const pthread_mutexattr_t *__mutexattr)
410: attribute_hidden;
411: extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
412: extern int __pthread_mutex_destroy_internal (pthread_mutex_t *__mutex)
413: attribute_hidden;
414: extern int __pthread_mutex_trylock (pthread_mutex_t *_mutex);
415: extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
416: extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
417: attribute_hidden;
418: extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
419: attribute_hidden internal_function;
420: extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
421: extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
422: attribute_hidden;
423: extern int __pthread_mutex_unlock_usercnt (pthread_mutex_t *__mutex,
424: int __decr)
425: attribute_hidden internal_function;
426: extern int __pthread_mutexattr_init (pthread_mutexattr_t *attr);
427: extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
428: extern int __pthread_mutexattr_settype (pthread_mutexattr_t *attr, int kind);
429: extern int __pthread_attr_destroy (pthread_attr_t *attr);
430: extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr,
431: int *detachstate);
432: extern int __pthread_attr_setdetachstate (pthread_attr_t *attr,
433: int detachstate);
434: extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr,
435: int *inherit);
436: extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit);
437: extern int __pthread_attr_getschedparam (const pthread_attr_t *attr,
438: struct sched_param *param);
439: extern int __pthread_attr_setschedparam (pthread_attr_t *attr,
440: const struct sched_param *param);
441: extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr,
442: int *policy);
443: extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
444: extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
445: extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope);
446: extern int __pthread_attr_getstackaddr (__const pthread_attr_t *__restrict
447: __attr, void **__restrict __stackaddr);
448: extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr,
449: void *__stackaddr);
450: extern int __pthread_attr_getstacksize (__const pthread_attr_t *__restrict
451: __attr,
452: size_t *__restrict __stacksize);
453: extern int __pthread_attr_setstacksize (pthread_attr_t *__attr,
454: size_t __stacksize);
455: extern int __pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
456: void **__restrict __stackaddr,
457: size_t *__restrict __stacksize);
458: extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
459: size_t __stacksize);
460: extern int __pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
461: __const pthread_rwlockattr_t *__restrict
462: __attr);
463: extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
464: extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
465: extern int __pthread_rwlock_rdlock_internal (pthread_rwlock_t *__rwlock);
466: extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
467: extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
468: extern int __pthread_rwlock_wrlock_internal (pthread_rwlock_t *__rwlock);
469: extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
470: extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
471: extern int __pthread_rwlock_unlock_internal (pthread_rwlock_t *__rwlock);
472: extern int __pthread_cond_broadcast (pthread_cond_t *cond);
473: extern int __pthread_cond_destroy (pthread_cond_t *cond);
474: extern int __pthread_cond_init (pthread_cond_t *cond,
475: const pthread_condattr_t *cond_attr);
476: extern int __pthread_cond_signal (pthread_cond_t *cond);
477: extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
478: extern int __pthread_cond_timedwait (pthread_cond_t *cond,
479: pthread_mutex_t *mutex,
480: const struct timespec *abstime);
481: extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
482: extern int __pthread_condattr_init (pthread_condattr_t *attr);
483: extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
484: extern int __pthread_key_create_internal (pthread_key_t *key,
485: void (*destr) (void *));
486: extern void *__pthread_getspecific (pthread_key_t key);
487: extern void *__pthread_getspecific_internal (pthread_key_t key);
488: extern int __pthread_setspecific (pthread_key_t key, const void *value);
489: extern int __pthread_setspecific_internal (pthread_key_t key,
490: const void *value);
491: extern int __pthread_once (pthread_once_t *once_control,
492: void (*init_routine) (void));
493: extern int __pthread_once_internal (pthread_once_t *once_control,
494: void (*init_routine) (void));
495: extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
496: void (*child) (void));
497: extern pthread_t __pthread_self (void);
498: extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
499: extern int __pthread_kill (pthread_t threadid, int signo);
500: extern void __pthread_exit (void *value);
501: extern int __pthread_setcanceltype (int type, int *oldtype);
502: extern int __pthread_enable_asynccancel (void) attribute_hidden;
503: extern void __pthread_disable_asynccancel (int oldtype)
504: internal_function attribute_hidden;
505:
506: extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond);
507: