1#ifndef _PTHREAD_IMPL_H 2#define _PTHREAD_IMPL_H 3 4#include <pthread.h> 5#include <signal.h> 6#include <errno.h> 7#include <limits.h> 8#include "libc.h" 9#include "syscall.h" 10#include "atomic.h" 11#include "futex.h" 12 13#define pthread __pthread 14 15struct pthread { 16 struct pthread *self; 17 void **dtv, *unused1, *unused2; 18 uintptr_t sysinfo; 19 uintptr_t canary, canary2; 20 pid_t tid, pid; 21 int tsd_used, errno_val; 22 volatile int cancel, canceldisable, cancelasync; 23 int detached; 24 unsigned char *map_base; 25 size_t map_size; 26 void *stack; 27 size_t stack_size; 28 void *start_arg; 29 void *(*start)(void *); 30 void *result; 31 struct __ptcb *cancelbuf; 32 void **tsd; 33 volatile int dead; 34 struct { 35 volatile void *volatile head; 36 long off; 37 volatile void *volatile pending; 38 } robust_list; 39 int unblock_cancel; 40 volatile int timer_id; 41 locale_t locale; 42 volatile int killlock[2]; 43 volatile int exitlock[2]; 44 volatile int startlock[2]; 45 unsigned long sigmask[_NSIG/8/sizeof(long)]; 46 char *dlerror_buf; 47 int dlerror_flag; 48 void *stdio_locks; 49 uintptr_t canary_at_end; 50 void **dtv_copy; 51}; 52 53struct __timer { 54 int timerid; 55 pthread_t thread; 56}; 57 58#define __SU (sizeof(size_t)/sizeof(int)) 59 60#define _a_stacksize __u.__s[0] 61#define _a_guardsize __u.__s[1] 62#define _a_stackaddr __u.__s[2] 63#define _a_detach __u.__i[3*__SU+0] 64#define _a_sched __u.__i[3*__SU+1] 65#define _a_policy __u.__i[3*__SU+2] 66#define _a_prio __u.__i[3*__SU+3] 67#define _m_type __u.__i[0] 68#define _m_lock __u.__vi[1] 69#define _m_waiters __u.__vi[2] 70#define _m_prev __u.__p[3] 71#define _m_next __u.__p[4] 72#define _m_count __u.__i[5] 73#define _c_shared __u.__p[0] 74#define _c_seq __u.__vi[2] 75#define _c_waiters __u.__vi[3] 76#define _c_clock __u.__i[4] 77#define _c_lock __u.__vi[8] 78#define _c_head __u.__p[1] 79#define _c_tail __u.__p[5] 80#define _rw_lock __u.__vi[0] 81#define _rw_waiters __u.__vi[1] 82#define _rw_shared __u.__i[2] 83#define _b_lock __u.__vi[0] 84#define _b_waiters __u.__vi[1] 85#define _b_limit __u.__i[2] 86#define _b_count __u.__vi[3] 87#define _b_waiters2 __u.__vi[4] 88#define _b_inst __u.__p[3] 89 90#include "pthread_arch.h" 91 92#ifndef CANARY 93#define CANARY canary 94#endif 95 96#ifndef DTP_OFFSET 97#define DTP_OFFSET 0 98#endif 99 100#define SIGTIMER 32 101#define SIGCANCEL 33 102#define SIGSYNCCALL 34 103 104#define SIGALL_SET ((sigset_t *)(const unsigned long long [2]){ -1,-1 }) 105#define SIGPT_SET \ 106 ((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \ 107 [sizeof(long)==4] = 3UL<<(32*(sizeof(long)>4)) }) 108#define SIGTIMER_SET \ 109 ((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \ 110 0x80000000 }) 111 112pthread_t __pthread_self_init(void); 113 114int __clone(int (*)(void *), void *, int, void *, ...); 115int __set_thread_area(void *); 116int __libc_sigaction(int, const struct sigaction *, struct sigaction *); 117int __libc_sigprocmask(int, const sigset_t *, sigset_t *); 118void __lock(volatile int *); 119void __unmapself(void *, size_t); 120 121void __vm_wait(void); 122void __vm_lock(void); 123void __vm_unlock(void); 124 125int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int); 126int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int); 127void __wait(volatile int *, volatile int *, int, int); 128static inline void __wake(volatile void *addr, int cnt, int priv) 129{ 130 if (priv) priv = 128; 131 if (cnt<0) cnt = INT_MAX; 132 __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || 133 __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); 134} 135 136void __acquire_ptc(void); 137void __release_ptc(void); 138void __inhibit_ptc(void); 139 140void __block_all_sigs(void *); 141void __block_app_sigs(void *); 142void __restore_sigs(void *); 143 144#define DEFAULT_STACK_SIZE 81920 145#define DEFAULT_GUARD_SIZE 4096 146 147#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1) 148 149#endif 150