xref: /openbsd-src/lib/libc/thread/rthread.h (revision c7e8ea31cd41a963f06f0a8ba93948b06aa6b4a4)
1 /*	$OpenBSD: rthread.h,v 1.1 2017/08/15 06:13:24 guenther Exp $ */
2 /*
3  * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * Private data structures that back up the typedefs in pthread.h.
20  * Since only the thread library cares about their size or arrangement,
21  * it should be possible to switch libraries without relinking.
22  *
23  * Do not reorder _atomic_lock_t and sem_t variables in the structs.
24  * This is due to alignment requirements of certain arches like hppa.
25  * The current requirement is 16 bytes.
26  *
27  * THE MACHINE DEPENDENT CERROR CODE HAS HARD CODED OFFSETS INTO PTHREAD_T!
28  */
29 
30 #include <sys/queue.h>
31 #include <semaphore.h>
32 #include <machine/spinlock.h>
33 
34 #ifdef __LP64__
35 #define RTHREAD_STACK_SIZE_DEF (512 * 1024)
36 #else
37 #define RTHREAD_STACK_SIZE_DEF (256 * 1024)
38 #endif
39 
40 #define	_SPINLOCK_UNLOCKED _ATOMIC_LOCK_UNLOCKED
41 
42 struct stack {
43 	SLIST_ENTRY(stack)	link;	/* link for free default stacks */
44 	void	*sp;			/* machine stack pointer */
45 	void	*base;			/* bottom of allocated area */
46 	size_t	guardsize;		/* size of PROT_NONE zone or */
47 					/* ==1 if application alloced */
48 	size_t	len;			/* total size of allocated stack */
49 };
50 
51 struct __sem {
52 	_atomic_lock_t lock;
53 	volatile int waitcount;
54 	volatile int value;
55 	int shared;
56 };
57 
58 TAILQ_HEAD(pthread_queue, pthread);
59 
60 #ifdef FUTEX
61 
62 struct pthread_mutex {
63 	volatile unsigned int lock;
64 	int type;
65 	pthread_t owner;
66 	int count;
67 	int prioceiling;
68 };
69 
70 struct pthread_cond {
71 	volatile unsigned int seq;
72 	clockid_t clock;
73 	struct pthread_mutex *mutex;
74 };
75 
76 #else
77 
78 struct pthread_mutex {
79 	_atomic_lock_t lock;
80 	struct pthread_queue lockers;
81 	int type;
82 	pthread_t owner;
83 	int count;
84 	int prioceiling;
85 };
86 
87 struct pthread_cond {
88 	_atomic_lock_t lock;
89 	struct pthread_queue waiters;
90 	struct pthread_mutex *mutex;
91 	clockid_t clock;
92 };
93 #endif /* FUTEX */
94 
95 struct pthread_mutex_attr {
96 	int ma_type;
97 	int ma_protocol;
98 	int ma_prioceiling;
99 };
100 
101 struct pthread_cond_attr {
102 	clockid_t ca_clock;
103 };
104 
105 struct pthread_rwlock {
106 	_atomic_lock_t lock;
107 	pthread_t owner;
108 	struct pthread_queue writers;
109 	int readers;
110 };
111 
112 struct pthread_rwlockattr {
113 	int pshared;
114 };
115 
116 struct pthread_attr {
117 	void *stack_addr;
118 	size_t stack_size;
119 	size_t guard_size;
120 	int detach_state;
121 	int contention_scope;
122 	int sched_policy;
123 	struct sched_param sched_param;
124 	int sched_inherit;
125 };
126 
127 #define	PTHREAD_MIN_PRIORITY	0
128 #define	PTHREAD_MAX_PRIORITY	31
129 
130 struct rthread_key {
131 	int used;
132 	void (*destructor)(void *);
133 };
134 
135 struct rthread_storage {
136 	int keyid;
137 	struct rthread_storage *next;
138 	void *data;
139 };
140 
141 struct rthread_cleanup_fn {
142 	void (*fn)(void *);
143 	void *arg;
144 	struct rthread_cleanup_fn *next;
145 };
146 
147 struct pthread_barrier {
148 	pthread_mutex_t mutex;
149 	pthread_cond_t cond;
150 	int threshold;
151 	int in;
152 	int out;
153 	int generation;
154 };
155 
156 struct pthread_barrierattr {
157 	int pshared;
158 };
159 
160 struct pthread_spinlock {
161 	_atomic_lock_t lock;
162 	pthread_t owner;
163 };
164 
165 struct tib;
166 struct pthread {
167 	struct __sem donesem;
168 	unsigned int flags;
169 	_atomic_lock_t flags_lock;
170 	struct tib *tib;
171 	void *retval;
172 	void *(*fn)(void *);
173 	void *arg;
174 	char name[32];
175 	struct stack *stack;
176 	LIST_ENTRY(pthread) threads;
177 	TAILQ_ENTRY(pthread) waiting;
178 	pthread_cond_t blocking_cond;
179 	struct pthread_attr attr;
180 	struct rthread_storage *local_storage;
181 	struct rthread_cleanup_fn *cleanup_fns;
182 	int myerrno;
183 
184 	/* cancel received in a delayed cancel block? */
185 	int delayed_cancel;
186 };
187 /* flags in pthread->flags */
188 #define	THREAD_DONE		0x001
189 #define	THREAD_DETACHED		0x002
190 
191 /* flags in tib->tib_thread_flags */
192 #define	TIB_THREAD_ASYNC_CANCEL		0x001
193 #define	TIB_THREAD_INITIAL_STACK	0x002	/* has stack from exec */
194 
195 #define ENTER_DELAYED_CANCEL_POINT(tib, self)				\
196 	(self)->delayed_cancel = 0;					\
197 	ENTER_CANCEL_POINT_INNER(tib, 1, 1)
198 
199 #define	ROUND_TO_PAGE(size) \
200 	(((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1))
201 
202 __BEGIN_HIDDEN_DECLS
203 void	_spinlock(volatile _atomic_lock_t *);
204 int	_spinlocktry(volatile _atomic_lock_t *);
205 void	_spinunlock(volatile _atomic_lock_t *);
206 int	_sem_wait(sem_t, int, const struct timespec *, int *);
207 int	_sem_post(sem_t);
208 
209 void	_rthread_init(void);
210 struct stack *_rthread_alloc_stack(pthread_t);
211 void	_rthread_free_stack(struct stack *);
212 void	_rthread_tls_destructors(pthread_t);
213 void	_rthread_debug(int, const char *, ...)
214 		__attribute__((__format__ (printf, 2, 3)));
215 void	_rthread_debug_init(void);
216 #ifndef NO_PIC
217 void	_rthread_dl_lock(int what);
218 #endif
219 void	_thread_malloc_reinit(void);
220 
221 extern int _threads_ready;
222 extern size_t _thread_pagesize;
223 extern LIST_HEAD(listhead, pthread) _thread_list;
224 extern _atomic_lock_t _thread_lock;
225 extern struct pthread_attr _rthread_attr_default;
226 __END_HIDDEN_DECLS
227 
228 void	_thread_dump_info(void);
229 
230 /* syscalls not declared in system headers */
231 #define REDIRECT_SYSCALL(x)		typeof(x) x asm("_thread_sys_"#x)
232 void	__threxit(pid_t *);
233 int	__thrsleep(const volatile void *, clockid_t, const struct timespec *,
234 	    volatile void *, const int *);
235 int	__thrwakeup(const volatile void *, int n);
236 int	__thrsigdivert(sigset_t, siginfo_t *, const struct timespec *);
237