1570af302Sopenharmony_ci#ifndef _PTHREAD_IMPL_H 2570af302Sopenharmony_ci#define _PTHREAD_IMPL_H 3570af302Sopenharmony_ci 4570af302Sopenharmony_ci#include <pthread.h> 5570af302Sopenharmony_ci#include <signal.h> 6570af302Sopenharmony_ci#include <errno.h> 7570af302Sopenharmony_ci#include <limits.h> 8570af302Sopenharmony_ci#include <sys/mman.h> 9570af302Sopenharmony_ci#include "libc.h" 10570af302Sopenharmony_ci#include "syscall.h" 11570af302Sopenharmony_ci#include "atomic.h" 12570af302Sopenharmony_ci#include "futex.h" 13570af302Sopenharmony_ci#ifndef __LITEOS__ 14570af302Sopenharmony_ci#include "musl_log.h" 15570af302Sopenharmony_ci#endif 16570af302Sopenharmony_ci#include "pthread_arch.h" 17570af302Sopenharmony_ci 18570af302Sopenharmony_ci#define pthread __pthread 19570af302Sopenharmony_ci#define TLS_RESERVE_SLOT 15 20570af302Sopenharmony_ci 21570af302Sopenharmony_cistruct pthread { 22570af302Sopenharmony_ci /* Part 1 -- these fields may be external or 23570af302Sopenharmony_ci * internal (accessed via asm) ABI. Do not change. */ 24570af302Sopenharmony_ci struct pthread *self; 25570af302Sopenharmony_ci#ifndef TLS_ABOVE_TP 26570af302Sopenharmony_ci uintptr_t *dtv; 27570af302Sopenharmony_ci#endif 28570af302Sopenharmony_ci struct pthread *prev, *next; /* non-ABI */ 29570af302Sopenharmony_ci uintptr_t sysinfo; 30570af302Sopenharmony_ci#ifndef TLS_ABOVE_TP 31570af302Sopenharmony_ci#ifdef CANARY_PAD 32570af302Sopenharmony_ci uintptr_t canary_pad; 33570af302Sopenharmony_ci#endif 34570af302Sopenharmony_ci uintptr_t canary; 35570af302Sopenharmony_ci#endif 36570af302Sopenharmony_ci 37570af302Sopenharmony_ci /* Part 2 -- implementation details, non-ABI. */ 38570af302Sopenharmony_ci int tid; 39570af302Sopenharmony_ci int pid; 40570af302Sopenharmony_ci int proc_tid; 41570af302Sopenharmony_ci int errno_val; 42570af302Sopenharmony_ci int by_vfork; 43570af302Sopenharmony_ci volatile int detach_state; 44570af302Sopenharmony_ci#ifdef FEATURE_PTHREAD_CANCEL 45570af302Sopenharmony_ci volatile int cancel; 46570af302Sopenharmony_ci volatile unsigned char canceldisable, cancelasync; 47570af302Sopenharmony_ci#endif 48570af302Sopenharmony_ci unsigned char tsd_used:1; 49570af302Sopenharmony_ci unsigned char dlerror_flag:1; 50570af302Sopenharmony_ci unsigned char *map_base; 51570af302Sopenharmony_ci size_t map_size; 52570af302Sopenharmony_ci void *stack; 53570af302Sopenharmony_ci size_t stack_size; 54570af302Sopenharmony_ci size_t guard_size; 55570af302Sopenharmony_ci void *result; 56570af302Sopenharmony_ci struct __ptcb *cancelbuf; 57570af302Sopenharmony_ci void **tsd; 58570af302Sopenharmony_ci struct { 59570af302Sopenharmony_ci volatile void *volatile head; 60570af302Sopenharmony_ci long off; 61570af302Sopenharmony_ci volatile void *volatile pending; 62570af302Sopenharmony_ci } robust_list; 63570af302Sopenharmony_ci int h_errno_val; 64570af302Sopenharmony_ci volatile int timer_id; 65570af302Sopenharmony_ci locale_t locale; 66570af302Sopenharmony_ci volatile int killlock[1]; 67570af302Sopenharmony_ci char *dlerror_buf; 68570af302Sopenharmony_ci void *stdio_locks; 69570af302Sopenharmony_ci#ifdef RESERVE_SIGNAL_STACK 70570af302Sopenharmony_ci void *signal_stack; 71570af302Sopenharmony_ci#endif 72570af302Sopenharmony_ci 73570af302Sopenharmony_ci /* musl doesn't support libc using tls, so we reserve some slots here for gwp_asan to use. */ 74570af302Sopenharmony_ci struct { 75570af302Sopenharmony_ci uint32_t random_state; 76570af302Sopenharmony_ci uint32_t next_sample_counter : 31; 77570af302Sopenharmony_ci char recursive_guard : 1; 78570af302Sopenharmony_ci } gwp_asan_tls; 79570af302Sopenharmony_ci 80570af302Sopenharmony_ci #ifdef CXA_THREAD_USE_TLS 81570af302Sopenharmony_ci struct thread_local_dtor { 82570af302Sopenharmony_ci void (*func) (void *); 83570af302Sopenharmony_ci void *arg; 84570af302Sopenharmony_ci void *dso_handle; // Used to located dso. 85570af302Sopenharmony_ci struct thread_local_dtor* next; 86570af302Sopenharmony_ci } *thread_local_dtors; 87570af302Sopenharmony_ci #endif 88570af302Sopenharmony_ci 89570af302Sopenharmony_ci /* Part 3 -- the positions of these fields relative to 90570af302Sopenharmony_ci * the end of the structure is external and internal ABI. */ 91570af302Sopenharmony_ci#ifdef TLS_ABOVE_TP 92570af302Sopenharmony_ci /* The tls_slots will be accessed by kernel, so don't use it. 93570af302Sopenharmony_ci * To solve the problem that the kernel isn't synchronized with the musl, 94570af302Sopenharmony_ci * so make pre/post reserved slots for musl. 95570af302Sopenharmony_ci * pre-reserved : tls_slots[0-4] 96570af302Sopenharmony_ci * kernel used : tls_slots[5-9] 97570af302Sopenharmony_ci * post-reserved : tls_slot[10-14] */ 98570af302Sopenharmony_ci void *tls_slots[TLS_RESERVE_SLOT]; 99570af302Sopenharmony_ci uintptr_t canary; 100570af302Sopenharmony_ci uintptr_t *dtv; 101570af302Sopenharmony_ci#endif 102570af302Sopenharmony_ci}; 103570af302Sopenharmony_ci 104570af302Sopenharmony_cienum { 105570af302Sopenharmony_ci DT_EXITED = 0, 106570af302Sopenharmony_ci DT_EXITING, 107570af302Sopenharmony_ci DT_JOINABLE, 108570af302Sopenharmony_ci DT_DETACHED, 109570af302Sopenharmony_ci}; 110570af302Sopenharmony_ci 111570af302Sopenharmony_ci#define __SU (sizeof(size_t)/sizeof(int)) 112570af302Sopenharmony_ci 113570af302Sopenharmony_ci#define _a_stacksize __u.__s[0] 114570af302Sopenharmony_ci#define _a_guardsize __u.__s[1] 115570af302Sopenharmony_ci#define _a_stackaddr __u.__s[2] 116570af302Sopenharmony_ci#define _a_detach __u.__i[3*__SU+0] 117570af302Sopenharmony_ci#define _a_sched __u.__i[3*__SU+1] 118570af302Sopenharmony_ci#define _a_policy __u.__i[3*__SU+2] 119570af302Sopenharmony_ci#define _a_prio __u.__i[3*__SU+3] 120570af302Sopenharmony_ci#ifdef __LITEOS_A__ 121570af302Sopenharmony_ci#define _a_runtime __u.__i[3*__SU+3] 122570af302Sopenharmony_ci#define _a_deadline __u.__i[3*__SU+4] 123570af302Sopenharmony_ci#define _a_period __u.__i[3*__SU+5] 124570af302Sopenharmony_ci#endif 125570af302Sopenharmony_ci#define _m_type __u.__i[0] 126570af302Sopenharmony_ci#define _m_lock __u.__vi[1] 127570af302Sopenharmony_ci#define _m_waiters __u.__vi[2] 128570af302Sopenharmony_ci#define _m_prev __u.__p[3] 129570af302Sopenharmony_ci#define _m_next __u.__p[4] 130570af302Sopenharmony_ci#define _m_clock __u.__i[4] 131570af302Sopenharmony_ci#define _m_count __u.__i[5] 132570af302Sopenharmony_ci#define _c_shared __u.__p[0] 133570af302Sopenharmony_ci#define _c_seq __u.__vi[2] 134570af302Sopenharmony_ci#define _c_waiters __u.__vi[3] 135570af302Sopenharmony_ci#define _c_clock __u.__i[4] 136570af302Sopenharmony_ci#define _c_lock __u.__vi[8] 137570af302Sopenharmony_ci#define _c_head __u.__p[1] 138570af302Sopenharmony_ci#define _c_tail __u.__p[5] 139570af302Sopenharmony_ci#define _rw_lock __u.__vi[0] 140570af302Sopenharmony_ci#define _rw_waiters __u.__vi[1] 141570af302Sopenharmony_ci#define _rw_shared __u.__i[2] 142570af302Sopenharmony_ci#define _rw_clock __u.__i[4] 143570af302Sopenharmony_ci#define _b_lock __u.__vi[0] 144570af302Sopenharmony_ci#define _b_waiters __u.__vi[1] 145570af302Sopenharmony_ci#define _b_limit __u.__i[2] 146570af302Sopenharmony_ci#define _b_count __u.__vi[3] 147570af302Sopenharmony_ci#define _b_waiters2 __u.__vi[4] 148570af302Sopenharmony_ci#define _b_inst __u.__p[3] 149570af302Sopenharmony_ci 150570af302Sopenharmony_ci#ifndef TP_OFFSET 151570af302Sopenharmony_ci#define TP_OFFSET 0 152570af302Sopenharmony_ci#endif 153570af302Sopenharmony_ci 154570af302Sopenharmony_ci#ifndef DTP_OFFSET 155570af302Sopenharmony_ci#define DTP_OFFSET 0 156570af302Sopenharmony_ci#endif 157570af302Sopenharmony_ci 158570af302Sopenharmony_ci#ifdef TLS_ABOVE_TP 159570af302Sopenharmony_ci#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + TP_OFFSET) 160570af302Sopenharmony_ci#ifndef __LITEOS_A__ 161570af302Sopenharmony_ci#define __pthread_self() ((pthread_t)(__get_tp() - sizeof(struct __pthread) - TP_OFFSET)) 162570af302Sopenharmony_ci#endif 163570af302Sopenharmony_ci#else 164570af302Sopenharmony_ci#define TP_ADJ(p) (p) 165570af302Sopenharmony_ci#ifndef __LITEOS_A__ 166570af302Sopenharmony_ci#define __pthread_self() ((pthread_t)__get_tp()) 167570af302Sopenharmony_ci#endif 168570af302Sopenharmony_ci#endif 169570af302Sopenharmony_ci 170570af302Sopenharmony_ci#ifndef tls_mod_off_t 171570af302Sopenharmony_ci#define tls_mod_off_t size_t 172570af302Sopenharmony_ci#endif 173570af302Sopenharmony_ci 174570af302Sopenharmony_ci#define SIGTIMER 32 175570af302Sopenharmony_ci#define SIGCANCEL 33 176570af302Sopenharmony_ci#define SIGSYNCCALL 34 177570af302Sopenharmony_ci 178570af302Sopenharmony_ci#define SIGALL_SET ((sigset_t *)(const unsigned long long [2]){ -1,-1 }) 179570af302Sopenharmony_ci#define SIGPT_SET \ 180570af302Sopenharmony_ci ((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \ 181570af302Sopenharmony_ci [sizeof(long)==4] = 3UL<<(32*(sizeof(long)>4)) }) 182570af302Sopenharmony_ci#define SIGTIMER_SET \ 183570af302Sopenharmony_ci ((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \ 184570af302Sopenharmony_ci 0x80000000 }) 185570af302Sopenharmony_ci 186570af302Sopenharmony_civoid *__tls_get_addr(tls_mod_off_t *); 187570af302Sopenharmony_cihidden int __init_tp(void *); 188570af302Sopenharmony_cihidden void *__copy_tls(unsigned char *); 189570af302Sopenharmony_cihidden void __reset_tls(); 190570af302Sopenharmony_ci 191570af302Sopenharmony_cihidden void __membarrier_init(void); 192570af302Sopenharmony_cihidden void __dl_thread_cleanup(void); 193570af302Sopenharmony_cihidden void __testcancel(); 194570af302Sopenharmony_cihidden void __do_cleanup_push(struct __ptcb *); 195570af302Sopenharmony_cihidden void __do_cleanup_pop(struct __ptcb *); 196570af302Sopenharmony_cihidden void __pthread_tsd_run_dtors(); 197570af302Sopenharmony_ci 198570af302Sopenharmony_cihidden void __pthread_key_delete_synccall(void (*)(void *), void *); 199570af302Sopenharmony_cihidden int __pthread_key_delete_impl(pthread_key_t); 200570af302Sopenharmony_ci 201570af302Sopenharmony_ciextern hidden volatile size_t __pthread_tsd_size; 202570af302Sopenharmony_ciextern hidden void *__pthread_tsd_main[]; 203570af302Sopenharmony_ciextern hidden volatile int __eintr_valid_flag; 204570af302Sopenharmony_ci 205570af302Sopenharmony_cihidden int __clone(int (*)(void *), void *, int, void *, ...); 206570af302Sopenharmony_cihidden int __set_thread_area(void *); 207570af302Sopenharmony_cihidden int __libc_sigaction(int, const struct sigaction *, struct sigaction *); 208570af302Sopenharmony_cihidden void __unmapself(void *, size_t); 209570af302Sopenharmony_ci 210570af302Sopenharmony_cihidden int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int); 211570af302Sopenharmony_cihidden int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int); 212570af302Sopenharmony_cihidden void __wait(volatile int *, volatile int *, int, int); 213570af302Sopenharmony_cistatic inline void __wake(volatile void *addr, int cnt, int priv) 214570af302Sopenharmony_ci{ 215570af302Sopenharmony_ci if (priv) priv = FUTEX_PRIVATE; 216570af302Sopenharmony_ci if (cnt<0) cnt = INT_MAX; 217570af302Sopenharmony_ci __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || 218570af302Sopenharmony_ci __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); 219570af302Sopenharmony_ci} 220570af302Sopenharmony_cistatic inline void __futexwait(volatile void *addr, int val, int priv) 221570af302Sopenharmony_ci{ 222570af302Sopenharmony_ci if (priv) priv = FUTEX_PRIVATE; 223570af302Sopenharmony_ci#ifdef __LITEOS_A__ 224570af302Sopenharmony_ci __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0xffffffffu) != -ENOSYS || 225570af302Sopenharmony_ci __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0xffffffffu); 226570af302Sopenharmony_ci#else 227570af302Sopenharmony_ci __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || 228570af302Sopenharmony_ci __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); 229570af302Sopenharmony_ci#endif 230570af302Sopenharmony_ci} 231570af302Sopenharmony_ci 232570af302Sopenharmony_ci#define MS_PER_S 1000 233570af302Sopenharmony_ci#define US_PER_S 1000000 234570af302Sopenharmony_cistatic inline void __timespec_from_ms(struct timespec* ts, const unsigned ms) 235570af302Sopenharmony_ci{ 236570af302Sopenharmony_ci if (ts == NULL) { 237570af302Sopenharmony_ci return; 238570af302Sopenharmony_ci } 239570af302Sopenharmony_ci ts->tv_sec = ms / MS_PER_S; 240570af302Sopenharmony_ci ts->tv_nsec = (ms % MS_PER_S) * US_PER_S; 241570af302Sopenharmony_ci} 242570af302Sopenharmony_ci 243570af302Sopenharmony_ci#define NS_PER_S 1000000000 244570af302Sopenharmony_cistatic inline void __absolute_timespec_from_timespec(struct timespec *abs_ts, 245570af302Sopenharmony_ci const struct timespec *ts, clockid_t clock) 246570af302Sopenharmony_ci{ 247570af302Sopenharmony_ci if (abs_ts == NULL || ts == NULL) { 248570af302Sopenharmony_ci return; 249570af302Sopenharmony_ci } 250570af302Sopenharmony_ci clock_gettime(clock, abs_ts); 251570af302Sopenharmony_ci abs_ts->tv_sec += ts->tv_sec; 252570af302Sopenharmony_ci abs_ts->tv_nsec += ts->tv_nsec; 253570af302Sopenharmony_ci if (abs_ts->tv_nsec >= NS_PER_S) { 254570af302Sopenharmony_ci abs_ts->tv_nsec -= NS_PER_S; 255570af302Sopenharmony_ci abs_ts->tv_sec++; 256570af302Sopenharmony_ci } 257570af302Sopenharmony_ci} 258570af302Sopenharmony_ci 259570af302Sopenharmony_cistatic inline int __is_mutex_destroyed(int mutex_type) 260570af302Sopenharmony_ci{ 261570af302Sopenharmony_ci return mutex_type == PTHREAD_MUTEX_DESTROYED; 262570af302Sopenharmony_ci} 263570af302Sopenharmony_ci 264570af302Sopenharmony_cistatic inline void __handle_using_destroyed_mutex(pthread_mutex_t *mutex, const char *function_name) 265570af302Sopenharmony_ci{ 266570af302Sopenharmony_ci#ifndef __LITEOS__ 267570af302Sopenharmony_ci MUSL_LOGE("Fortify Error: %{public}s called on a destroyed mutex (%{public}p)", function_name, mutex); 268570af302Sopenharmony_ci#endif 269570af302Sopenharmony_ci} 270570af302Sopenharmony_ci 271570af302Sopenharmony_ci#ifdef RESERVE_SIGNAL_STACK 272570af302Sopenharmony_cihidden void pthread_reserve_signal_stack(); 273570af302Sopenharmony_cihidden void pthread_release_signal_stack(); 274570af302Sopenharmony_ci#endif 275570af302Sopenharmony_ci 276570af302Sopenharmony_cihidden void __acquire_ptc(void); 277570af302Sopenharmony_cihidden void __release_ptc(void); 278570af302Sopenharmony_cihidden void __inhibit_ptc(void); 279570af302Sopenharmony_ci 280570af302Sopenharmony_cihidden void __tl_lock(void); 281570af302Sopenharmony_cihidden void __tl_unlock(void); 282570af302Sopenharmony_cihidden void __tl_sync(pthread_t); 283570af302Sopenharmony_cihidden int get_tl_lock_count(void); 284570af302Sopenharmony_cihidden int get_tl_lock_waiters(void); 285570af302Sopenharmony_cihidden int get_tl_lock_tid_fail(void); 286570af302Sopenharmony_cihidden int get_tl_lock_count_tid(void); 287570af302Sopenharmony_cihidden int get_tl_lock_count_fail(void); 288570af302Sopenharmony_cihidden int get_thread_list_lock_pre_unlock(void); 289570af302Sopenharmony_cihidden struct pthread* __pthread_list_find(pthread_t, const char*); 290570af302Sopenharmony_ci 291570af302Sopenharmony_ciextern hidden volatile int __thread_list_lock; 292570af302Sopenharmony_ci 293570af302Sopenharmony_ciextern hidden volatile int __abort_lock[1]; 294570af302Sopenharmony_ci 295570af302Sopenharmony_ciextern hidden unsigned __default_stacksize; 296570af302Sopenharmony_ciextern hidden unsigned __default_guardsize; 297570af302Sopenharmony_ci 298570af302Sopenharmony_ci#ifdef TARGET_STACK_SIZE 299570af302Sopenharmony_ci#define DEFAULT_STACK_SIZE TARGET_STACK_SIZE 300570af302Sopenharmony_ci#else 301570af302Sopenharmony_ci#define DEFAULT_STACK_SIZE 131072 302570af302Sopenharmony_ci#endif 303570af302Sopenharmony_ci 304570af302Sopenharmony_ci#ifdef TARGET_GUARD_SIZE 305570af302Sopenharmony_ci#define DEFAULT_GUARD_SIZE TARGET_GUARD_SIZE 306570af302Sopenharmony_ci#else 307570af302Sopenharmony_ci#define DEFAULT_GUARD_SIZE 8192 308570af302Sopenharmony_ci#endif 309570af302Sopenharmony_ci 310570af302Sopenharmony_ci#define DEFAULT_STACK_MAX (8<<20) 311570af302Sopenharmony_ci#define DEFAULT_GUARD_MAX (1<<20) 312570af302Sopenharmony_ci 313570af302Sopenharmony_ci#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1) 314570af302Sopenharmony_ci 315570af302Sopenharmony_ci#ifdef __LITEOS_A__ 316570af302Sopenharmony_ci#define MUSL_TYPE_THREAD (-1) 317570af302Sopenharmony_ci#define MUSL_TYPE_PROCESS (0) 318570af302Sopenharmony_ci 319570af302Sopenharmony_ci#define PTHREAD_MUTEX_TYPE_MASK 3 320570af302Sopenharmony_ci#define PTHREAD_PRIORITY_LOWEST 31 321570af302Sopenharmony_cihidden int __thread_clone(int (*func)(void *), int flags, struct pthread *thread, unsigned char *sp); 322570af302Sopenharmony_ci#endif 323570af302Sopenharmony_ci 324570af302Sopenharmony_ci#endif 325