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