xref: /openbsd-src/lib/librthread/rthread.h (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: rthread.h,v 1.39 2012/05/03 09:07:17 pirofti 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 _spinlock_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 
28 #include <sys/queue.h>
29 #include <semaphore.h>
30 #include <machine/spinlock.h>
31 #include <machine/tcb.h>		/* for TLS_VARIANT */
32 
33 #ifdef __LP64__
34 #define RTHREAD_STACK_SIZE_DEF (512 * 1024)
35 #else
36 #define RTHREAD_STACK_SIZE_DEF (256 * 1024)
37 #endif
38 
39 struct stack {
40 	SLIST_ENTRY(stack)	link;	/* link for free default stacks */
41 	void	*sp;			/* machine stack pointer */
42 	void	*base;			/* bottom of allocated area */
43 	size_t	guardsize;		/* size of PROT_NONE zone or */
44 					/* ==1 if application alloced */
45 	size_t	len;			/* total size of allocated stack */
46 };
47 
48 struct sem {
49 	_spinlock_lock_t lock;
50 	volatile int waitcount;
51 	volatile int value;
52 	int pad;
53 };
54 
55 TAILQ_HEAD(pthread_queue, pthread);
56 
57 struct pthread_mutex {
58 	_spinlock_lock_t lock;
59 	struct pthread_queue lockers;
60 	int type;
61 	pthread_t owner;
62 	int count;
63 	int prioceiling;
64 };
65 
66 struct pthread_mutex_attr {
67 	int ma_type;
68 	int ma_protocol;
69 	int ma_prioceiling;
70 };
71 
72 struct pthread_cond {
73 	_spinlock_lock_t lock;
74 	struct pthread_queue waiters;
75 	struct pthread_mutex *mutex;
76 	clockid_t clock;
77 };
78 
79 struct pthread_cond_attr {
80 	clockid_t ca_clock;
81 };
82 
83 struct pthread_rwlock {
84 	_spinlock_lock_t lock;
85 	pthread_t owner;
86 	struct pthread_queue writers;
87 	int readers;
88 };
89 
90 struct pthread_rwlockattr {
91 	int pshared;
92 };
93 
94 struct pthread_attr {
95 	void *stack_addr;
96 	size_t stack_size;
97 	size_t guard_size;
98 	int detach_state;
99 	int contention_scope;
100 	int sched_policy;
101 	struct sched_param sched_param;
102 	int sched_inherit;
103 };
104 
105 #define	PTHREAD_MIN_PRIORITY	0
106 #define	PTHREAD_MAX_PRIORITY	31
107 
108 struct rthread_key {
109 	int used;
110 	void (*destructor)(void *);
111 };
112 
113 struct rthread_storage {
114 	int keyid;
115 	struct rthread_storage *next;
116 	void *data;
117 };
118 
119 struct rthread_cleanup_fn {
120 	void (*fn)(void *);
121 	void *arg;
122 	struct rthread_cleanup_fn *next;
123 };
124 
125 struct pthread_barrier {
126 	pthread_mutex_t mutex;
127 	pthread_cond_t cond;
128 	int threshold;
129 	int sofar;
130 	int generation;
131 };
132 
133 struct pthread_barrierattr {
134 	int pshared;
135 };
136 
137 struct pthread_spinlock {
138 	_spinlock_lock_t lock;
139 	pthread_t owner;
140 };
141 
142 struct pthread {
143 	struct sem donesem;
144 #if TLS_VARIANT == 1
145 	int *errno_ptr;
146 #endif
147 	pid_t tid;
148 	unsigned int flags;
149 	_spinlock_lock_t flags_lock;
150 	void *retval;
151 	void *(*fn)(void *);
152 	void *arg;
153 	char name[32];
154 	struct stack *stack;
155 	LIST_ENTRY(pthread) threads;
156 	TAILQ_ENTRY(pthread) waiting;
157 	pthread_cond_t blocking_cond;
158 	int sched_policy;
159 	struct pthread_attr attr;
160 	struct sched_param sched_param;
161 	struct rthread_storage *local_storage;
162 	struct rthread_cleanup_fn *cleanup_fns;
163 	int myerrno;
164 
165 	/* currently in a cancel point? */
166 	int cancel_point;
167 
168 	/* cancel received in a delayed cancel block? */
169 	int delayed_cancel;
170 };
171 #define	THREAD_DONE		0x001
172 #define	THREAD_DETACHED		0x002
173 #define THREAD_CANCELED		0x004
174 #define THREAD_CANCEL_ENABLE	0x008
175 #define THREAD_CANCEL_DEFERRED	0x010
176 #define THREAD_CANCEL_DELAY	0x020
177 #define THREAD_DYING            0x040
178 
179 #define	IS_CANCELED(thread) \
180 	(((thread)->flags & (THREAD_CANCELED|THREAD_DYING)) == THREAD_CANCELED)
181 
182 
183 extern int _threads_ready;
184 extern size_t _thread_pagesize;
185 extern LIST_HEAD(listhead, pthread) _thread_list;
186 extern struct pthread _initial_thread;
187 extern _spinlock_lock_t _thread_lock;
188 extern struct pthread_attr _rthread_attr_default;
189 
190 #define	ROUND_TO_PAGE(size) \
191 	(((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1))
192 
193 void	_spinlock(_spinlock_lock_t *);
194 void	_spinunlock(_spinlock_lock_t *);
195 int	_sem_wait(sem_t, int, const struct timespec *, int *);
196 int	_sem_post(sem_t);
197 
198 int	_rthread_init(void);
199 void	_rthread_setflag(pthread_t, int);
200 void	_rthread_clearflag(pthread_t, int);
201 struct stack *_rthread_alloc_stack(pthread_t);
202 void	_rthread_free_stack(struct stack *);
203 void	_rthread_tls_destructors(pthread_t);
204 void	_rthread_debug(int, const char *, ...)
205 		__attribute__((__format__ (printf, 2, 3)));
206 void	_rthread_debug_init(void);
207 #if defined(__ELF__) && defined(PIC)
208 void	_rthread_dl_lock(int what);
209 void	_rthread_bind_lock(int);
210 #endif
211 
212 /* rthread_cancel.c */
213 void	_enter_cancel(pthread_t);
214 void	_leave_cancel(pthread_t);
215 void	_enter_delayed_cancel(pthread_t);
216 void	_leave_delayed_cancel(pthread_t, int);
217 
218 void	_thread_dump_info(void);
219 
220 int	_atomic_lock(register volatile _spinlock_lock_t *);
221 
222 /* syscalls */
223 int	getthrid(void);
224 void	__threxit(pid_t *);
225 int	__thrsleep(const volatile void *, clockid_t, const struct timespec *,
226 	    void *, const int *);
227 int	__thrwakeup(const volatile void *, int n);
228 int	__thrsigdivert(sigset_t, siginfo_t *, const struct timespec *);
229 int	sched_yield(void);
230 int	_thread_sys_sigaction(int, const struct sigaction *,
231 	    struct sigaction *);
232