xref: /openbsd/lib/librthread/rthread.h (revision 9b7c3dbb)
1 /*	$OpenBSD: rthread.h,v 1.58 2016/05/07 19:05:22 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 struct _spinlock 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 _USING_TICKETS 0
41 /*
42  * tickets don't work yet? (or seem much slower, with lots of system time)
43  * until then, keep the struct around to avoid excessive changes going
44  * back and forth.
45  */
46 struct _spinlock {
47 	_atomic_lock_t ticket;
48 };
49 
50 #define	_SPINLOCK_UNLOCKED { _ATOMIC_LOCK_UNLOCKED }
51 extern struct _spinlock _SPINLOCK_UNLOCKED_ASSIGN;
52 
53 struct stack {
54 	SLIST_ENTRY(stack)	link;	/* link for free default stacks */
55 	void	*sp;			/* machine stack pointer */
56 	void	*base;			/* bottom of allocated area */
57 	size_t	guardsize;		/* size of PROT_NONE zone or */
58 					/* ==1 if application alloced */
59 	size_t	len;			/* total size of allocated stack */
60 };
61 
62 struct __sem {
63 	struct _spinlock lock;
64 	volatile int waitcount;
65 	volatile int value;
66 	int shared;
67 };
68 
69 TAILQ_HEAD(pthread_queue, pthread);
70 
71 struct pthread_mutex {
72 	struct _spinlock lock;
73 	struct pthread_queue lockers;
74 	int type;
75 	pthread_t owner;
76 	int count;
77 	int prioceiling;
78 };
79 
80 struct pthread_mutex_attr {
81 	int ma_type;
82 	int ma_protocol;
83 	int ma_prioceiling;
84 };
85 
86 struct pthread_cond {
87 	struct _spinlock lock;
88 	struct pthread_queue waiters;
89 	struct pthread_mutex *mutex;
90 	clockid_t clock;
91 };
92 
93 struct pthread_cond_attr {
94 	clockid_t ca_clock;
95 };
96 
97 struct pthread_rwlock {
98 	struct _spinlock lock;
99 	pthread_t owner;
100 	struct pthread_queue writers;
101 	int readers;
102 };
103 
104 struct pthread_rwlockattr {
105 	int pshared;
106 };
107 
108 struct pthread_attr {
109 	void *stack_addr;
110 	size_t stack_size;
111 	size_t guard_size;
112 	int detach_state;
113 	int contention_scope;
114 	int sched_policy;
115 	struct sched_param sched_param;
116 	int sched_inherit;
117 };
118 
119 #define	PTHREAD_MIN_PRIORITY	0
120 #define	PTHREAD_MAX_PRIORITY	31
121 
122 struct rthread_key {
123 	int used;
124 	void (*destructor)(void *);
125 };
126 
127 struct rthread_storage {
128 	int keyid;
129 	struct rthread_storage *next;
130 	void *data;
131 };
132 
133 struct rthread_cleanup_fn {
134 	void (*fn)(void *);
135 	void *arg;
136 	struct rthread_cleanup_fn *next;
137 };
138 
139 struct pthread_barrier {
140 	pthread_mutex_t mutex;
141 	pthread_cond_t cond;
142 	int threshold;
143 	int in;
144 	int out;
145 	int generation;
146 };
147 
148 struct pthread_barrierattr {
149 	int pshared;
150 };
151 
152 struct pthread_spinlock {
153 	struct _spinlock lock;
154 	pthread_t owner;
155 };
156 
157 struct tib;
158 struct pthread {
159 	struct __sem donesem;
160 	unsigned int flags;
161 	struct _spinlock flags_lock;
162 	struct tib *tib;
163 	void *retval;
164 	void *(*fn)(void *);
165 	void *arg;
166 	char name[32];
167 	struct stack *stack;
168 	LIST_ENTRY(pthread) threads;
169 	TAILQ_ENTRY(pthread) waiting;
170 	pthread_cond_t blocking_cond;
171 	struct pthread_attr attr;
172 	struct rthread_storage *local_storage;
173 	struct rthread_cleanup_fn *cleanup_fns;
174 	int myerrno;
175 
176 	/* cancel received in a delayed cancel block? */
177 	int delayed_cancel;
178 };
179 /* flags in pthread->flags */
180 #define	THREAD_DONE		0x001
181 #define	THREAD_DETACHED		0x002
182 
183 /* flags in tib->tib_thread_flags */
184 #define	TIB_THREAD_ASYNC_CANCEL		0x001
185 #define	TIB_THREAD_INITIAL_STACK	0x002	/* has stack from exec */
186 
187 #define ENTER_DELAYED_CANCEL_POINT(tib, self)				\
188 	(self)->delayed_cancel = 0;					\
189 	ENTER_CANCEL_POINT_INNER(tib, 1, 1)
190 
191 #define	ROUND_TO_PAGE(size) \
192 	(((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1))
193 
194 __BEGIN_HIDDEN_DECLS
195 void	_spinlock(volatile struct _spinlock *);
196 int	_spinlocktry(volatile struct _spinlock *);
197 void	_spinunlock(volatile struct _spinlock *);
198 int	_sem_wait(sem_t, int, const struct timespec *, int *);
199 int	_sem_post(sem_t);
200 
201 void	_rthread_init(void);
202 struct stack *_rthread_alloc_stack(pthread_t);
203 void	_rthread_free_stack(struct stack *);
204 void	_rthread_tls_destructors(pthread_t);
205 void	_rthread_debug(int, const char *, ...)
206 		__attribute__((__format__ (printf, 2, 3)));
207 void	_rthread_debug_init(void);
208 #ifndef NO_PIC
209 void	_rthread_dl_lock(int what);
210 #endif
211 void	_thread_malloc_reinit(void);
212 
213 extern int _threads_ready;
214 extern size_t _thread_pagesize;
215 extern LIST_HEAD(listhead, pthread) _thread_list;
216 extern struct _spinlock _thread_lock;
217 extern struct pthread_attr _rthread_attr_default;
218 __END_HIDDEN_DECLS
219 
220 void	_thread_dump_info(void);
221 
222 /* syscalls not declared in system headers */
223 #define REDIRECT_SYSCALL(x)		typeof(x) x asm("_thread_sys_"#x)
224 void	__threxit(pid_t *);
225 int	__thrsleep(const volatile void *, clockid_t, const struct timespec *,
226 	    volatile void *, const int *);
227 int	__thrwakeup(const volatile void *, int n);
228 int	__thrsigdivert(sigset_t, siginfo_t *, const struct timespec *);
229