Deleted Added
full compact
thr_private.h (125966) thr_private.h (126000)
1/*
2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by John Birrell.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * Private thread definitions for the uthread kernel.
33 *
1/*
2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by John Birrell.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * Private thread definitions for the uthread kernel.
33 *
34 * $FreeBSD: head/lib/libthr/thread/thr_private.h 125966 2004-02-18 15:16:31Z mtm $
34 * $FreeBSD: head/lib/libthr/thread/thr_private.h 126000 2004-02-19 13:51:52Z mtm $
35 */
36
37#ifndef _THR_PRIVATE_H
38#define _THR_PRIVATE_H
39
40/*
41 * Evaluate the storage class specifier.
42 */
43#ifdef GLOBAL_PTHREAD_PRIVATE
44#define SCLASS
45#else
46#define SCLASS extern
47#endif
48
49/*
50 * Include files.
51 */
52#include <sys/types.h>
53#include <sys/cdefs.h>
54#include <sys/errno.h>
55#include <sys/time.h>
56#include <sys/queue.h>
57#include <pthread_np.h>
58#include <sched.h>
59#include <signal.h>
60#include <spinlock.h>
61#include <stdio.h>
62#include <ucontext.h>
63#include <unistd.h>
64#if defined(_PTHREADS_INVARIANTS)
65#include <assert.h>
66#endif
67
68#include <machine/atomic.h>
69#include <sys/thr.h>
70#include <sys/umtx.h>
71
72#if defined(_PTHREADS_INVARIANTS)
73/*
74 * Kernel fatal error handler macro.
75 */
76#define PANIC(string) \
77 do { \
78 _thread_printf(STDOUT_FILENO, (string)); \
79 _thread_printf(STDOUT_FILENO, \
80 "\nAbnormal termination, file: %s, line: %d\n", \
81 __FILE__, __LINE__); \
82 abort(); \
83 } while (0)
84
85#define PTHREAD_ASSERT(cond, msg) do { \
86 if (!(cond)) \
87 PANIC(msg); \
88} while (0)
89
90#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
91 PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \
92 "Illegal call from signal handler");
93
94#else /* !_PTHREADS_INVARIANTS */
95#define PANIC(string) _thread_exit(__FILE__, __LINE__, (string))
96#define PTHREAD_ASSERT(cond, msg)
97#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
98#endif /* _PTHREADS_INVARIANTS */
99
100/* Output debug messages like this: */
101#define stdout_debug(args...) _thread_printf(STDOUT_FILENO, args)
102#define stderr_debug(args...) _thread_printf(STDOUT_FILENO, args)
103
104/*
105 * Currently executing thread.
106 */
107#define curthread _get_curthread()
108
109/*
110 * Locking macros
111 */
112#define UMTX_LOCK(m) \
113 do { \
114 if (umtx_lock((m), curthread->thr_id) != 0) \
115 abort(); \
116 } while (0)
117
118#define UMTX_TRYLOCK(m, r) \
119 do { \
120 (r) = umtx_trylock((m), curthread->thr_id); \
121 if ((r) != 0 && (r) != EBUSY) \
122 abort(); \
123 } while (0)
124
125#define UMTX_UNLOCK(m) \
126 do { \
127 if (umtx_unlock((m), curthread->thr_id) != 0) \
128 abort(); \
129 } while (0)
130
131
132/*
133 * State change macro:
134 */
135#define PTHREAD_SET_STATE(thrd, newstate) do { \
136 (thrd)->state = newstate; \
137 (thrd)->fname = __FILE__; \
138 (thrd)->lineno = __LINE__; \
139} while (0)
140
141#define PTHREAD_NEW_STATE(thrd, newstate) do { \
142 if (newstate == PS_RUNNING) { \
143 if (thr_kill(thrd->thr_id, SIGTHR)) \
144 abort(); \
145 } \
146 PTHREAD_SET_STATE(thrd, newstate); \
147} while (0)
148
35 */
36
37#ifndef _THR_PRIVATE_H
38#define _THR_PRIVATE_H
39
40/*
41 * Evaluate the storage class specifier.
42 */
43#ifdef GLOBAL_PTHREAD_PRIVATE
44#define SCLASS
45#else
46#define SCLASS extern
47#endif
48
49/*
50 * Include files.
51 */
52#include <sys/types.h>
53#include <sys/cdefs.h>
54#include <sys/errno.h>
55#include <sys/time.h>
56#include <sys/queue.h>
57#include <pthread_np.h>
58#include <sched.h>
59#include <signal.h>
60#include <spinlock.h>
61#include <stdio.h>
62#include <ucontext.h>
63#include <unistd.h>
64#if defined(_PTHREADS_INVARIANTS)
65#include <assert.h>
66#endif
67
68#include <machine/atomic.h>
69#include <sys/thr.h>
70#include <sys/umtx.h>
71
72#if defined(_PTHREADS_INVARIANTS)
73/*
74 * Kernel fatal error handler macro.
75 */
76#define PANIC(string) \
77 do { \
78 _thread_printf(STDOUT_FILENO, (string)); \
79 _thread_printf(STDOUT_FILENO, \
80 "\nAbnormal termination, file: %s, line: %d\n", \
81 __FILE__, __LINE__); \
82 abort(); \
83 } while (0)
84
85#define PTHREAD_ASSERT(cond, msg) do { \
86 if (!(cond)) \
87 PANIC(msg); \
88} while (0)
89
90#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
91 PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \
92 "Illegal call from signal handler");
93
94#else /* !_PTHREADS_INVARIANTS */
95#define PANIC(string) _thread_exit(__FILE__, __LINE__, (string))
96#define PTHREAD_ASSERT(cond, msg)
97#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
98#endif /* _PTHREADS_INVARIANTS */
99
100/* Output debug messages like this: */
101#define stdout_debug(args...) _thread_printf(STDOUT_FILENO, args)
102#define stderr_debug(args...) _thread_printf(STDOUT_FILENO, args)
103
104/*
105 * Currently executing thread.
106 */
107#define curthread _get_curthread()
108
109/*
110 * Locking macros
111 */
112#define UMTX_LOCK(m) \
113 do { \
114 if (umtx_lock((m), curthread->thr_id) != 0) \
115 abort(); \
116 } while (0)
117
118#define UMTX_TRYLOCK(m, r) \
119 do { \
120 (r) = umtx_trylock((m), curthread->thr_id); \
121 if ((r) != 0 && (r) != EBUSY) \
122 abort(); \
123 } while (0)
124
125#define UMTX_UNLOCK(m) \
126 do { \
127 if (umtx_unlock((m), curthread->thr_id) != 0) \
128 abort(); \
129 } while (0)
130
131
132/*
133 * State change macro:
134 */
135#define PTHREAD_SET_STATE(thrd, newstate) do { \
136 (thrd)->state = newstate; \
137 (thrd)->fname = __FILE__; \
138 (thrd)->lineno = __LINE__; \
139} while (0)
140
141#define PTHREAD_NEW_STATE(thrd, newstate) do { \
142 if (newstate == PS_RUNNING) { \
143 if (thr_kill(thrd->thr_id, SIGTHR)) \
144 abort(); \
145 } \
146 PTHREAD_SET_STATE(thrd, newstate); \
147} while (0)
148
149
150/*
151 * TailQ initialization values.
152 */
153#define TAILQ_INITIALIZER { NULL, NULL }
154
155#define UMTX_INITIALIZER { NULL }
156
157struct pthread_mutex_attr {
158 enum pthread_mutextype m_type;
159 int m_protocol;
160 int m_ceiling;
161 long m_flags;
162};
163
164/*
165 * Static mutex initialization values.
166 */
167
168#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
169 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
170
171#define PTHREAD_MUTEX_STATIC_INITIALIZER \
172 { PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL, \
173 0, 0, TAILQ_INITIALIZER }
174
175union pthread_mutex_data {
176 void *m_ptr;
177 int m_count;
178};
179
180struct pthread_mutex {
181 enum pthread_mutextype m_type;
182 int m_protocol;
183 TAILQ_HEAD(mutex_head, pthread) m_queue;
184 struct pthread *m_owner;
185 union pthread_mutex_data m_data;
186 long m_flags;
187 int m_refcount;
188
189 /*
190 * Used for priority inheritence and protection.
191 *
192 * m_prio - For priority inheritence, the highest active
193 * priority (threads locking the mutex inherit
194 * this priority). For priority protection, the
195 * ceiling priority of this mutex.
196 * m_saved_prio - mutex owners inherited priority before
197 * taking the mutex, restored when the owner
198 * unlocks the mutex.
199 */
200 int m_prio;
201 int m_saved_prio;
202
203 /*
204 * Link for list of all mutexes a thread currently owns.
205 */
206 TAILQ_ENTRY(pthread_mutex) m_qe;
207
208 /*
209 * Lock for accesses to this structure.
210 */
211 spinlock_t lock;
212};
213
214struct pthread_spinlock {
215 void *s_owner;
216 unsigned int s_magic;
217};
218
219/*
220 * Flags for mutexes.
221 */
222#define MUTEX_FLAGS_PRIVATE 0x01
223#define MUTEX_FLAGS_INITED 0x02
224#define MUTEX_FLAGS_BUSY 0x04
225
226/*
227 * Condition variable definitions.
228 */
229enum pthread_cond_type {
230 COND_TYPE_FAST,
231 COND_TYPE_MAX
232};
233
234struct pthread_cond {
235 enum pthread_cond_type c_type;
236 TAILQ_HEAD(cond_head, pthread) c_queue;
237 pthread_mutex_t c_mutex;
238 void *c_data;
239 long c_flags;
240 int c_seqno;
241
242 /*
243 * Lock for accesses to this structure.
244 */
245 struct umtx c_lock;
246};
247
248struct pthread_cond_attr {
249 enum pthread_cond_type c_type;
250 long c_flags;
251};
252
253/*
254 * Flags for condition variables.
255 */
256#define COND_FLAGS_INITED 0x01
257
258/*
259 * Static cond initialization values.
260 */
261#define PTHREAD_COND_STATIC_INITIALIZER \
262 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
263 0, 0, UMTX_INITIALIZER }
264
265/*
266 * Semaphore definitions.
267 */
268struct sem {
269#define SEM_MAGIC ((u_int32_t) 0x09fa4012)
270 u_int32_t magic;
271 pthread_mutex_t lock;
272 pthread_cond_t gtzero;
273 u_int32_t count;
274 u_int32_t nwaiters;
275};
276
277/*
278 * Cleanup definitions.
279 */
280struct pthread_cleanup {
281 struct pthread_cleanup *next;
282 void (*routine) ();
283 void *routine_arg;
284};
285
286struct pthread_attr {
287 int sched_policy;
288 int sched_inherit;
289 int sched_interval;
290 int prio;
291 int suspend;
292 int flags;
293 void *arg_attr;
294 void (*cleanup_attr) ();
295 void *stackaddr_attr;
296 size_t stacksize_attr;
297 size_t guardsize_attr;
298};
299
300/*
301 * Thread creation state attributes.
302 */
303#define PTHREAD_CREATE_RUNNING 0
304#define PTHREAD_CREATE_SUSPENDED 1
305
306/*
307 * Miscellaneous definitions.
308 */
309#define PTHREAD_STACK_DEFAULT 65536
310/*
311 * Size of default red zone at the end of each stack. In actuality, this "red
312 * zone" is merely an unmapped region, except in the case of the initial stack.
313 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK
314 * region, an unmapped gap between thread stacks achieves the same effect as
315 * explicitly mapped red zones.
316 * This is declared and initialized in uthread_init.c.
317 */
318extern int _pthread_guard_default;
319
320extern int _pthread_page_size;
321
322/*
323 * Maximum size of initial thread's stack. This perhaps deserves to be larger
324 * than the stacks of other threads, since many applications are likely to run
325 * almost entirely on this stack.
326 */
327#define PTHREAD_STACK_INITIAL 0x100000
328
329/*
330 * Define the different priority ranges. All applications have thread
331 * priorities constrained within 0-31. The threads library raises the
332 * priority when delivering signals in order to ensure that signal
333 * delivery happens (from the POSIX spec) "as soon as possible".
334 * In the future, the threads library will also be able to map specific
335 * threads into real-time (cooperating) processes or kernel threads.
336 * The RT and SIGNAL priorities will be used internally and added to
337 * thread base priorities so that the scheduling queue can handle both
338 * normal and RT priority threads with and without signal handling.
339 *
340 * The approach taken is that, within each class, signal delivery
341 * always has priority over thread execution.
342 */
343#define PTHREAD_DEFAULT_PRIORITY 15
344#define PTHREAD_MIN_PRIORITY 0
345#define PTHREAD_MAX_PRIORITY 31 /* 0x1F */
346#define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */
347#define PTHREAD_RT_PRIORITY 64 /* 0x40 */
348#define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY
349#define PTHREAD_LAST_PRIORITY \
350 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY)
351#define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY)
352
353/*
354 * Clock resolution in microseconds.
355 */
356#define CLOCK_RES_USEC 10000
357#define CLOCK_RES_USEC_MIN 1000
358
359/*
360 * Time slice period in microseconds.
361 */
362#define TIMESLICE_USEC 20000
363
364/*
365 * XXX Define a thread-safe macro to get the current time of day
366 * which is updated at regular intervals by the scheduling signal
367 * handler.
368 */
369#define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL)
370
149/*
150 * TailQ initialization values.
151 */
152#define TAILQ_INITIALIZER { NULL, NULL }
153
154#define UMTX_INITIALIZER { NULL }
155
156struct pthread_mutex_attr {
157 enum pthread_mutextype m_type;
158 int m_protocol;
159 int m_ceiling;
160 long m_flags;
161};
162
163/*
164 * Static mutex initialization values.
165 */
166
167#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
168 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
169
170#define PTHREAD_MUTEX_STATIC_INITIALIZER \
171 { PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL, \
172 0, 0, TAILQ_INITIALIZER }
173
174union pthread_mutex_data {
175 void *m_ptr;
176 int m_count;
177};
178
179struct pthread_mutex {
180 enum pthread_mutextype m_type;
181 int m_protocol;
182 TAILQ_HEAD(mutex_head, pthread) m_queue;
183 struct pthread *m_owner;
184 union pthread_mutex_data m_data;
185 long m_flags;
186 int m_refcount;
187
188 /*
189 * Used for priority inheritence and protection.
190 *
191 * m_prio - For priority inheritence, the highest active
192 * priority (threads locking the mutex inherit
193 * this priority). For priority protection, the
194 * ceiling priority of this mutex.
195 * m_saved_prio - mutex owners inherited priority before
196 * taking the mutex, restored when the owner
197 * unlocks the mutex.
198 */
199 int m_prio;
200 int m_saved_prio;
201
202 /*
203 * Link for list of all mutexes a thread currently owns.
204 */
205 TAILQ_ENTRY(pthread_mutex) m_qe;
206
207 /*
208 * Lock for accesses to this structure.
209 */
210 spinlock_t lock;
211};
212
213struct pthread_spinlock {
214 void *s_owner;
215 unsigned int s_magic;
216};
217
218/*
219 * Flags for mutexes.
220 */
221#define MUTEX_FLAGS_PRIVATE 0x01
222#define MUTEX_FLAGS_INITED 0x02
223#define MUTEX_FLAGS_BUSY 0x04
224
225/*
226 * Condition variable definitions.
227 */
228enum pthread_cond_type {
229 COND_TYPE_FAST,
230 COND_TYPE_MAX
231};
232
233struct pthread_cond {
234 enum pthread_cond_type c_type;
235 TAILQ_HEAD(cond_head, pthread) c_queue;
236 pthread_mutex_t c_mutex;
237 void *c_data;
238 long c_flags;
239 int c_seqno;
240
241 /*
242 * Lock for accesses to this structure.
243 */
244 struct umtx c_lock;
245};
246
247struct pthread_cond_attr {
248 enum pthread_cond_type c_type;
249 long c_flags;
250};
251
252/*
253 * Flags for condition variables.
254 */
255#define COND_FLAGS_INITED 0x01
256
257/*
258 * Static cond initialization values.
259 */
260#define PTHREAD_COND_STATIC_INITIALIZER \
261 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
262 0, 0, UMTX_INITIALIZER }
263
264/*
265 * Semaphore definitions.
266 */
267struct sem {
268#define SEM_MAGIC ((u_int32_t) 0x09fa4012)
269 u_int32_t magic;
270 pthread_mutex_t lock;
271 pthread_cond_t gtzero;
272 u_int32_t count;
273 u_int32_t nwaiters;
274};
275
276/*
277 * Cleanup definitions.
278 */
279struct pthread_cleanup {
280 struct pthread_cleanup *next;
281 void (*routine) ();
282 void *routine_arg;
283};
284
285struct pthread_attr {
286 int sched_policy;
287 int sched_inherit;
288 int sched_interval;
289 int prio;
290 int suspend;
291 int flags;
292 void *arg_attr;
293 void (*cleanup_attr) ();
294 void *stackaddr_attr;
295 size_t stacksize_attr;
296 size_t guardsize_attr;
297};
298
299/*
300 * Thread creation state attributes.
301 */
302#define PTHREAD_CREATE_RUNNING 0
303#define PTHREAD_CREATE_SUSPENDED 1
304
305/*
306 * Miscellaneous definitions.
307 */
308#define PTHREAD_STACK_DEFAULT 65536
309/*
310 * Size of default red zone at the end of each stack. In actuality, this "red
311 * zone" is merely an unmapped region, except in the case of the initial stack.
312 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK
313 * region, an unmapped gap between thread stacks achieves the same effect as
314 * explicitly mapped red zones.
315 * This is declared and initialized in uthread_init.c.
316 */
317extern int _pthread_guard_default;
318
319extern int _pthread_page_size;
320
321/*
322 * Maximum size of initial thread's stack. This perhaps deserves to be larger
323 * than the stacks of other threads, since many applications are likely to run
324 * almost entirely on this stack.
325 */
326#define PTHREAD_STACK_INITIAL 0x100000
327
328/*
329 * Define the different priority ranges. All applications have thread
330 * priorities constrained within 0-31. The threads library raises the
331 * priority when delivering signals in order to ensure that signal
332 * delivery happens (from the POSIX spec) "as soon as possible".
333 * In the future, the threads library will also be able to map specific
334 * threads into real-time (cooperating) processes or kernel threads.
335 * The RT and SIGNAL priorities will be used internally and added to
336 * thread base priorities so that the scheduling queue can handle both
337 * normal and RT priority threads with and without signal handling.
338 *
339 * The approach taken is that, within each class, signal delivery
340 * always has priority over thread execution.
341 */
342#define PTHREAD_DEFAULT_PRIORITY 15
343#define PTHREAD_MIN_PRIORITY 0
344#define PTHREAD_MAX_PRIORITY 31 /* 0x1F */
345#define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */
346#define PTHREAD_RT_PRIORITY 64 /* 0x40 */
347#define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY
348#define PTHREAD_LAST_PRIORITY \
349 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY)
350#define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY)
351
352/*
353 * Clock resolution in microseconds.
354 */
355#define CLOCK_RES_USEC 10000
356#define CLOCK_RES_USEC_MIN 1000
357
358/*
359 * Time slice period in microseconds.
360 */
361#define TIMESLICE_USEC 20000
362
363/*
364 * XXX Define a thread-safe macro to get the current time of day
365 * which is updated at regular intervals by the scheduling signal
366 * handler.
367 */
368#define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL)
369
370struct pthread_barrierattr {
371 int ba_pshared;
372};
371
373
374/*
375 * POSIX Threads barrier object.
376 * Lock order:
377 * 1. pthread_barrier
378 * 2. pthread
379 */
380struct pthread_barrier {
381 TAILQ_HEAD(barrq_head, pthread) b_barrq;
382 struct umtx b_lock;
383 int b_total;
384 int b_subtotal;
385};
386
372struct pthread_rwlockattr {
373 int pshared;
374};
375
376struct pthread_rwlock {
377 pthread_mutex_t lock; /* monitor lock */
378 int state; /* 0 = idle >0 = # of readers -1 = writer */
379 pthread_cond_t read_signal;
380 pthread_cond_t write_signal;
381 int blocked_writers;
382};
383
384/*
385 * Thread states.
386 */
387enum pthread_state {
388 PS_RUNNING,
389 PS_MUTEX_WAIT,
390 PS_COND_WAIT,
387struct pthread_rwlockattr {
388 int pshared;
389};
390
391struct pthread_rwlock {
392 pthread_mutex_t lock; /* monitor lock */
393 int state; /* 0 = idle >0 = # of readers -1 = writer */
394 pthread_cond_t read_signal;
395 pthread_cond_t write_signal;
396 int blocked_writers;
397};
398
399/*
400 * Thread states.
401 */
402enum pthread_state {
403 PS_RUNNING,
404 PS_MUTEX_WAIT,
405 PS_COND_WAIT,
406 PS_BARRIER_WAIT,
391 PS_SLEEP_WAIT, /* XXX We need to wrap syscalls to set this state */
392 PS_WAIT_WAIT,
393 PS_JOIN,
394 PS_DEAD,
395 PS_DEADLOCK,
396 PS_STATE_MAX
397};
398
399
400/*
401 * File descriptor locking definitions.
402 */
403#define FD_READ 0x1
404#define FD_WRITE 0x2
405#define FD_RDWR (FD_READ | FD_WRITE)
406
407union pthread_wait_data {
408 pthread_mutex_t mutex;
409 pthread_cond_t cond;
410 spinlock_t *spinlock;
411 struct pthread *thread;
412};
413
414struct join_status {
415 struct pthread *thread;
416 void *ret;
417 int error;
418};
419
420struct pthread_state_data {
421 union pthread_wait_data psd_wait_data;
422 enum pthread_state psd_state;
423 int psd_flags;
424};
425
426struct pthread_specific_elem {
427 const void *data;
428 int seqno;
429};
430
431struct rwlock_held {
432 LIST_ENTRY(rwlock_held) rh_link;
433 struct pthread_rwlock *rh_rwlock;
434 int rh_rdcount;
435 int rh_wrcount;
436};
437
438LIST_HEAD(rwlock_listhead, rwlock_held);
439
440/*
441 * Thread structure.
442 */
443struct pthread {
444 /*
445 * Magic value to help recognize a valid thread structure
446 * from an invalid one:
447 */
448#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115)
449 u_int32_t magic;
450 char *name;
451 u_int64_t uniqueid; /* for gdb */
452 thr_id_t thr_id;
453 sigset_t savedsig;
454 int signest; /* blocked signal netsting level */
455
456 /*
457 * Lock for accesses to this thread structure.
458 */
459 struct umtx lock;
460
461 /* Queue entry for list of all threads: */
462 TAILQ_ENTRY(pthread) tle;
463
464 /* Queue entry for list of dead threads: */
465 TAILQ_ENTRY(pthread) dle;
466
467 /*
468 * Thread start routine, argument, stack pointer and thread
469 * attributes.
470 */
471 void *(*start_routine)(void *);
472 void *arg;
473 void *stack;
474 struct pthread_attr attr;
475
476 /*
477 * Machine context, including signal state.
478 */
479 ucontext_t ctx;
480
481 /*
482 * Cancelability flags - the lower 2 bits are used by cancel
483 * definitions in pthread.h
484 */
485#define PTHREAD_AT_CANCEL_POINT 0x0004
486#define PTHREAD_CANCELLING 0x0008
487
488 /*
489 * Protected by Giant.
490 */
491 int cancelflags;
492
493 /* Thread state: */
494 enum pthread_state state;
495
496 /*
497 * Error variable used instead of errno. The function __error()
498 * returns a pointer to this.
499 */
500 int error;
501
502 /*
503 * The joiner is the thread that is joining to this thread. The
504 * join status keeps track of a join operation to another thread.
505 */
506 struct pthread *joiner;
507 struct join_status join_status;
508
509 /*
510 * A thread can belong to:
511 *
512 * o A queue of threads waiting for a mutex
513 * o A queue of threads waiting for a condition variable
514 *
515 * A thread can also be joining a thread (the joiner field above).
516 *
517 * It must not be possible for a thread to belong to any of the
518 * above queues while it is handling a signal. Signal handlers
519 * may longjmp back to previous stack frames circumventing normal
520 * control flow. This could corrupt queue integrity if the thread
521 * retains membership in the queue. Therefore, if a thread is a
522 * member of one of these queues when a signal handler is invoked,
523 * it must remove itself from the queue before calling the signal
524 * handler and reinsert itself after normal return of the handler.
525 *
526 * Use sqe for synchronization (mutex and condition variable) queue
527 * links.
528 */
529 TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */
530
531 /* Wait data. */
532 union pthread_wait_data data;
533
534 /* Miscellaneous flags; only set with signals deferred. */
535 int flags;
536#define PTHREAD_FLAGS_PRIVATE 0x0001
537#define PTHREAD_EXITING 0x0002
407 PS_SLEEP_WAIT, /* XXX We need to wrap syscalls to set this state */
408 PS_WAIT_WAIT,
409 PS_JOIN,
410 PS_DEAD,
411 PS_DEADLOCK,
412 PS_STATE_MAX
413};
414
415
416/*
417 * File descriptor locking definitions.
418 */
419#define FD_READ 0x1
420#define FD_WRITE 0x2
421#define FD_RDWR (FD_READ | FD_WRITE)
422
423union pthread_wait_data {
424 pthread_mutex_t mutex;
425 pthread_cond_t cond;
426 spinlock_t *spinlock;
427 struct pthread *thread;
428};
429
430struct join_status {
431 struct pthread *thread;
432 void *ret;
433 int error;
434};
435
436struct pthread_state_data {
437 union pthread_wait_data psd_wait_data;
438 enum pthread_state psd_state;
439 int psd_flags;
440};
441
442struct pthread_specific_elem {
443 const void *data;
444 int seqno;
445};
446
447struct rwlock_held {
448 LIST_ENTRY(rwlock_held) rh_link;
449 struct pthread_rwlock *rh_rwlock;
450 int rh_rdcount;
451 int rh_wrcount;
452};
453
454LIST_HEAD(rwlock_listhead, rwlock_held);
455
456/*
457 * Thread structure.
458 */
459struct pthread {
460 /*
461 * Magic value to help recognize a valid thread structure
462 * from an invalid one:
463 */
464#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115)
465 u_int32_t magic;
466 char *name;
467 u_int64_t uniqueid; /* for gdb */
468 thr_id_t thr_id;
469 sigset_t savedsig;
470 int signest; /* blocked signal netsting level */
471
472 /*
473 * Lock for accesses to this thread structure.
474 */
475 struct umtx lock;
476
477 /* Queue entry for list of all threads: */
478 TAILQ_ENTRY(pthread) tle;
479
480 /* Queue entry for list of dead threads: */
481 TAILQ_ENTRY(pthread) dle;
482
483 /*
484 * Thread start routine, argument, stack pointer and thread
485 * attributes.
486 */
487 void *(*start_routine)(void *);
488 void *arg;
489 void *stack;
490 struct pthread_attr attr;
491
492 /*
493 * Machine context, including signal state.
494 */
495 ucontext_t ctx;
496
497 /*
498 * Cancelability flags - the lower 2 bits are used by cancel
499 * definitions in pthread.h
500 */
501#define PTHREAD_AT_CANCEL_POINT 0x0004
502#define PTHREAD_CANCELLING 0x0008
503
504 /*
505 * Protected by Giant.
506 */
507 int cancelflags;
508
509 /* Thread state: */
510 enum pthread_state state;
511
512 /*
513 * Error variable used instead of errno. The function __error()
514 * returns a pointer to this.
515 */
516 int error;
517
518 /*
519 * The joiner is the thread that is joining to this thread. The
520 * join status keeps track of a join operation to another thread.
521 */
522 struct pthread *joiner;
523 struct join_status join_status;
524
525 /*
526 * A thread can belong to:
527 *
528 * o A queue of threads waiting for a mutex
529 * o A queue of threads waiting for a condition variable
530 *
531 * A thread can also be joining a thread (the joiner field above).
532 *
533 * It must not be possible for a thread to belong to any of the
534 * above queues while it is handling a signal. Signal handlers
535 * may longjmp back to previous stack frames circumventing normal
536 * control flow. This could corrupt queue integrity if the thread
537 * retains membership in the queue. Therefore, if a thread is a
538 * member of one of these queues when a signal handler is invoked,
539 * it must remove itself from the queue before calling the signal
540 * handler and reinsert itself after normal return of the handler.
541 *
542 * Use sqe for synchronization (mutex and condition variable) queue
543 * links.
544 */
545 TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */
546
547 /* Wait data. */
548 union pthread_wait_data data;
549
550 /* Miscellaneous flags; only set with signals deferred. */
551 int flags;
552#define PTHREAD_FLAGS_PRIVATE 0x0001
553#define PTHREAD_EXITING 0x0002
554#define PTHREAD_FLAGS_BARR_REL 0x0004 /* has been released from barrier */
538#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/
539#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */
540#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */
541#define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */
542#define PTHREAD_FLAGS_IN_SYNCQ \
543 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
544
545 /*
546 * Base priority is the user setable and retrievable priority
547 * of the thread. It is only affected by explicit calls to
548 * set thread priority and upon thread creation via a thread
549 * attribute or default priority.
550 */
551 char base_priority;
552
553 /*
554 * Inherited priority is the priority a thread inherits by
555 * taking a priority inheritence or protection mutex. It
556 * is not affected by base priority changes. Inherited
557 * priority defaults to and remains 0 until a mutex is taken
558 * that is being waited on by any other thread whose priority
559 * is non-zero.
560 */
561 char inherited_priority;
562
563 /*
564 * Active priority is always the maximum of the threads base
565 * priority and inherited priority. When there is a change
566 * in either the base or inherited priority, the active
567 * priority must be recalculated.
568 */
569 char active_priority;
570
571 /* Number of priority ceiling or protection mutexes owned. */
572 int prio_inherit_count;
573 int prio_protect_count;
574
575 /*
576 * Queue of currently owned mutexes.
577 */
578 TAILQ_HEAD(, pthread_mutex) mutexq;
579
580 /*
581 * List of read-write locks owned for reading _OR_ writing.
582 * This is accessed only by the current thread, so there's
583 * no need for mutual exclusion.
584 */
585 struct rwlock_listhead *rwlockList;
586
587 void *ret;
588 struct pthread_specific_elem *specific;
589 int specific_data_count;
590
591 /*
592 * Architecture specific id field used for _{get, set}_curthread()
593 * interface.
594 */
595 void *arch_id;
596
597 /* Cleanup handlers Link List */
598 struct pthread_cleanup *cleanup;
599 char *fname; /* Ptr to source file name */
600 int lineno; /* Source line number. */
601};
602
603/*
604 * Global variables for the uthread kernel.
605 */
606
607SCLASS void *_usrstack
608#ifdef GLOBAL_PTHREAD_PRIVATE
609= (void *) USRSTACK;
610#else
611;
612#endif
613
614SCLASS spinlock_t stack_lock
615#ifdef GLOBAL_PTHREAD_PRIVATE
616= _SPINLOCK_INITIALIZER
617#endif
618;
619#define STACK_LOCK _SPINLOCK(&stack_lock);
620#define STACK_UNLOCK _SPINUNLOCK(&stack_lock);
621
622/* List of all threads: */
623SCLASS TAILQ_HEAD(, pthread) _thread_list
624#ifdef GLOBAL_PTHREAD_PRIVATE
625= TAILQ_HEAD_INITIALIZER(_thread_list);
626#else
627;
628#endif
629
630/* Dead threads: */
631SCLASS TAILQ_HEAD(, pthread) _dead_list
632#ifdef GLOBAL_PTHREAD_PRIVATE
633= TAILQ_HEAD_INITIALIZER(_dead_list);
634#else
635;
636#endif
637
638/*
639 * These two locks protect the global active threads list and
640 * the global dead threads list, respectively. Combining these
641 * into one lock for both lists doesn't seem wise, since it
642 * would likely increase contention during busy thread creation
643 * and destruction for very little savings in space.
644 *
645 * The lock for the "dead threads list" must be a pthread mutex
646 * because it is used with condition variables to synchronize
647 * the gc thread with active threads in the process of exiting or
648 * dead threads who have just been joined.
649 */
650SCLASS spinlock_t thread_list_lock
651#ifdef GLOBAL_PTHREAD_PRIVATE
652= _SPINLOCK_INITIALIZER
653#endif
654;
655SCLASS pthread_mutex_t dead_list_lock
656#ifdef GLOBAL_PTHREAD_PRIVATE
657= NULL
658#endif
659;
660
661#define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock)
662#define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock)
663#define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock)
664#define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock)
665
666/* Initial thread: */
667SCLASS struct pthread *_thread_initial
668#ifdef GLOBAL_PTHREAD_PRIVATE
669= NULL;
670#else
671;
672#endif
673
674/* Default thread attributes: */
675SCLASS struct pthread_attr pthread_attr_default
676#ifdef GLOBAL_PTHREAD_PRIVATE
677= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
678 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL,
679 PTHREAD_STACK_DEFAULT, -1 };
680#else
681;
682#endif
683
684/* Default mutex attributes: */
685SCLASS struct pthread_mutex_attr pthread_mutexattr_default
686#ifdef GLOBAL_PTHREAD_PRIVATE
687= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
688#else
689;
690#endif
691
692/* Default condition variable attributes: */
693SCLASS struct pthread_cond_attr pthread_condattr_default
694#ifdef GLOBAL_PTHREAD_PRIVATE
695= { COND_TYPE_FAST, 0 };
696#else
697;
698#endif
699
700SCLASS int _clock_res_usec /* Clock resolution in usec. */
701#ifdef GLOBAL_PTHREAD_PRIVATE
702= CLOCK_RES_USEC;
703#else
704;
705#endif
706
707/* Garbage collector condition variable. */
708SCLASS pthread_cond_t _gc_cond
709#ifdef GLOBAL_PTHREAD_PRIVATE
710= NULL
711#endif
712;
713
714/*
715 * Array of signal actions for this process.
716 */
717SCLASS struct sigaction _thread_sigact[NSIG];
718
719/* Precomputed signal set for _thread_suspend. */
720SCLASS sigset_t _thread_suspend_sigset;
721
722/* Tracks the number of threads blocked while waiting for a spinlock. */
723SCLASS volatile int _spinblock_count
724#ifdef GLOBAL_PTHREAD_PRIVATE
725= 0
726#endif
727;
728
729/* Undefine the storage class specifier: */
730#undef SCLASS
731
732/*
733 * Function prototype definitions.
734 */
735__BEGIN_DECLS
736char *__ttyname_basic(int);
737char *__ttyname_r_basic(int, char *, size_t);
738char *ttyname_r(int, char *, size_t);
739void _cond_wait_backout(pthread_t);
740int _find_thread(pthread_t);
741pthread_t _get_curthread(void);
742void *_set_curthread(ucontext_t *, struct pthread *, int *);
743void _retire_thread(void *arch_id);
744void *_thread_stack_alloc(size_t, size_t);
745void _thread_stack_free(void *, size_t, size_t);
746int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
747int _mutex_cv_lock(pthread_mutex_t *);
748int _mutex_cv_unlock(pthread_mutex_t *);
749void _mutex_lock_backout(pthread_t);
750void _mutex_notify_priochange(pthread_t);
751int _mutex_reinit(pthread_mutex_t *);
752void _mutex_unlock_private(pthread_t);
753int _cond_reinit(pthread_cond_t *);
754void *_pthread_getspecific(pthread_key_t);
755int _pthread_key_create(pthread_key_t *, void (*) (void *));
756int _pthread_key_delete(pthread_key_t);
757int _pthread_mutex_destroy(pthread_mutex_t *);
758int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
759int _pthread_mutex_lock(pthread_mutex_t *);
760int _pthread_mutex_trylock(pthread_mutex_t *);
761int _pthread_mutex_unlock(pthread_mutex_t *);
762int _pthread_mutexattr_init(pthread_mutexattr_t *);
763int _pthread_mutexattr_destroy(pthread_mutexattr_t *);
764int _pthread_mutexattr_settype(pthread_mutexattr_t *, int);
765int _pthread_once(pthread_once_t *, void (*) (void));
766pthread_t _pthread_self(void);
767int _pthread_setspecific(pthread_key_t, const void *);
768int _spintrylock(spinlock_t *);
769void _thread_exit(char *, int, char *);
770void _thread_exit_cleanup(void);
771void *_thread_cleanup(pthread_t);
772void _thread_cleanupspecific(void);
773void _thread_dump_info(void);
774void _thread_init(void);
775void _thread_sig_wrapper(int sig, siginfo_t *info, void *context);
776void _thread_printf(int fd, const char *, ...);
777void _thread_start(void);
778void _thread_seterrno(pthread_t, int);
779pthread_addr_t _thread_gc(pthread_addr_t);
780void _thread_enter_cancellation_point(void);
781void _thread_leave_cancellation_point(void);
782void _thread_cancellation_point(void);
783int _thread_suspend(pthread_t thread, const struct timespec *abstime);
784void _thread_critical_enter(pthread_t);
785void _thread_critical_exit(pthread_t);
786void _thread_sigblock();
787void _thread_sigunblock();
788void adjust_prio_inheritance(struct pthread *);
789void adjust_prio_protection(struct pthread *);
790void init_td_common(struct pthread *, struct pthread_attr *, int);
791void init_tdlist(struct pthread *, int);
792void proc_sigact_copyin(int, const struct sigaction *);
793void proc_sigact_copyout(int, struct sigaction *);
794void readjust_priorities(struct pthread *, struct pthread_mutex *);
795struct sigaction *proc_sigact_sigaction(int);
796
797/* #include <sys/aio.h> */
798#ifdef _SYS_AIO_H_
799int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
800#endif
801
802/* #include <sys/event.h> */
803#ifdef _SYS_EVENT_H_
804int __sys_kevent(int, const struct kevent *, int, struct kevent *,
805 int, const struct timespec *);
806#endif
807
808/* #include <sys/ioctl.h> */
809#ifdef _SYS_IOCTL_H_
810int __sys_ioctl(int, unsigned long, ...);
811#endif
812
813/* #include <sys/mman.h> */
814#ifdef _SYS_MMAN_H_
815int __sys_msync(void *, size_t, int);
816#endif
817
818/* #include <sys/mount.h> */
819#ifdef _SYS_MOUNT_H_
820int __sys_fstatfs(int, struct statfs *);
821#endif
822
823/* #include <sys/socket.h> */
824#ifdef _SYS_SOCKET_H_
825int __sys_accept(int, struct sockaddr *, socklen_t *);
826int __sys_bind(int, const struct sockaddr *, socklen_t);
827int __sys_connect(int, const struct sockaddr *, socklen_t);
828int __sys_getpeername(int, struct sockaddr *, socklen_t *);
829int __sys_getsockname(int, struct sockaddr *, socklen_t *);
830int __sys_getsockopt(int, int, int, void *, socklen_t *);
831int __sys_listen(int, int);
832ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
833ssize_t __sys_recvmsg(int, struct msghdr *, int);
834int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
835ssize_t __sys_sendmsg(int, const struct msghdr *, int);
836ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
837int __sys_setsockopt(int, int, int, const void *, socklen_t);
838int __sys_shutdown(int, int);
839int __sys_socket(int, int, int);
840int __sys_socketpair(int, int, int, int *);
841#endif
842
843/* #include <sys/stat.h> */
844#ifdef _SYS_STAT_H_
845int __sys_fchflags(int, u_long);
846int __sys_fchmod(int, mode_t);
847int __sys_fstat(int, struct stat *);
848#endif
849
850/* #include <sys/uio.h> */
851#ifdef _SYS_UIO_H_
852ssize_t __sys_readv(int, const struct iovec *, int);
853ssize_t __sys_writev(int, const struct iovec *, int);
854#endif
855
856/* #include <sys/wait.h> */
857#ifdef WNOHANG
858pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
859#endif
860
861/* #include <dirent.h> */
862#ifdef _DIRENT_H_
863int __sys_getdirentries(int, char *, int, long *);
864#endif
865
866/* #include <fcntl.h> */
867#ifdef _SYS_FCNTL_H_
868int __sys_fcntl(int, int, ...);
869int __sys_flock(int, int);
870int __sys_open(const char *, int, ...);
871#endif
872
873/* #include <poll.h> */
874#ifdef _SYS_POLL_H_
875int __sys_poll(struct pollfd *, unsigned, int);
876#endif
877
878/* #include <signal.h> */
879#ifdef _SIGNAL_H_
880int __sys_sigaction(int, const struct sigaction *, struct sigaction *);
881int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
882int __sys_sigprocmask(int, const sigset_t *, sigset_t *);
883int __sys_sigreturn(ucontext_t *);
884#endif
885
886/* #include <unistd.h> */
887#ifdef _UNISTD_H_
888int __sys_close(int);
889int __sys_dup(int);
890int __sys_dup2(int, int);
891int __sys_execve(const char *, char * const *, char * const *);
892void __sys_exit(int);
893int __sys_fchown(int, uid_t, gid_t);
894pid_t __sys_fork(void);
895long __sys_fpathconf(int, int);
896int __sys_fsync(int);
897int __sys_pipe(int *);
898ssize_t __sys_read(int, void *, size_t);
899ssize_t __sys_write(int, const void *, size_t);
900#endif
901
902__END_DECLS
903
904#endif /* !_PTHREAD_PRIVATE_H */
555#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/
556#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */
557#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */
558#define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */
559#define PTHREAD_FLAGS_IN_SYNCQ \
560 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
561
562 /*
563 * Base priority is the user setable and retrievable priority
564 * of the thread. It is only affected by explicit calls to
565 * set thread priority and upon thread creation via a thread
566 * attribute or default priority.
567 */
568 char base_priority;
569
570 /*
571 * Inherited priority is the priority a thread inherits by
572 * taking a priority inheritence or protection mutex. It
573 * is not affected by base priority changes. Inherited
574 * priority defaults to and remains 0 until a mutex is taken
575 * that is being waited on by any other thread whose priority
576 * is non-zero.
577 */
578 char inherited_priority;
579
580 /*
581 * Active priority is always the maximum of the threads base
582 * priority and inherited priority. When there is a change
583 * in either the base or inherited priority, the active
584 * priority must be recalculated.
585 */
586 char active_priority;
587
588 /* Number of priority ceiling or protection mutexes owned. */
589 int prio_inherit_count;
590 int prio_protect_count;
591
592 /*
593 * Queue of currently owned mutexes.
594 */
595 TAILQ_HEAD(, pthread_mutex) mutexq;
596
597 /*
598 * List of read-write locks owned for reading _OR_ writing.
599 * This is accessed only by the current thread, so there's
600 * no need for mutual exclusion.
601 */
602 struct rwlock_listhead *rwlockList;
603
604 void *ret;
605 struct pthread_specific_elem *specific;
606 int specific_data_count;
607
608 /*
609 * Architecture specific id field used for _{get, set}_curthread()
610 * interface.
611 */
612 void *arch_id;
613
614 /* Cleanup handlers Link List */
615 struct pthread_cleanup *cleanup;
616 char *fname; /* Ptr to source file name */
617 int lineno; /* Source line number. */
618};
619
620/*
621 * Global variables for the uthread kernel.
622 */
623
624SCLASS void *_usrstack
625#ifdef GLOBAL_PTHREAD_PRIVATE
626= (void *) USRSTACK;
627#else
628;
629#endif
630
631SCLASS spinlock_t stack_lock
632#ifdef GLOBAL_PTHREAD_PRIVATE
633= _SPINLOCK_INITIALIZER
634#endif
635;
636#define STACK_LOCK _SPINLOCK(&stack_lock);
637#define STACK_UNLOCK _SPINUNLOCK(&stack_lock);
638
639/* List of all threads: */
640SCLASS TAILQ_HEAD(, pthread) _thread_list
641#ifdef GLOBAL_PTHREAD_PRIVATE
642= TAILQ_HEAD_INITIALIZER(_thread_list);
643#else
644;
645#endif
646
647/* Dead threads: */
648SCLASS TAILQ_HEAD(, pthread) _dead_list
649#ifdef GLOBAL_PTHREAD_PRIVATE
650= TAILQ_HEAD_INITIALIZER(_dead_list);
651#else
652;
653#endif
654
655/*
656 * These two locks protect the global active threads list and
657 * the global dead threads list, respectively. Combining these
658 * into one lock for both lists doesn't seem wise, since it
659 * would likely increase contention during busy thread creation
660 * and destruction for very little savings in space.
661 *
662 * The lock for the "dead threads list" must be a pthread mutex
663 * because it is used with condition variables to synchronize
664 * the gc thread with active threads in the process of exiting or
665 * dead threads who have just been joined.
666 */
667SCLASS spinlock_t thread_list_lock
668#ifdef GLOBAL_PTHREAD_PRIVATE
669= _SPINLOCK_INITIALIZER
670#endif
671;
672SCLASS pthread_mutex_t dead_list_lock
673#ifdef GLOBAL_PTHREAD_PRIVATE
674= NULL
675#endif
676;
677
678#define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock)
679#define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock)
680#define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock)
681#define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock)
682
683/* Initial thread: */
684SCLASS struct pthread *_thread_initial
685#ifdef GLOBAL_PTHREAD_PRIVATE
686= NULL;
687#else
688;
689#endif
690
691/* Default thread attributes: */
692SCLASS struct pthread_attr pthread_attr_default
693#ifdef GLOBAL_PTHREAD_PRIVATE
694= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
695 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL,
696 PTHREAD_STACK_DEFAULT, -1 };
697#else
698;
699#endif
700
701/* Default mutex attributes: */
702SCLASS struct pthread_mutex_attr pthread_mutexattr_default
703#ifdef GLOBAL_PTHREAD_PRIVATE
704= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
705#else
706;
707#endif
708
709/* Default condition variable attributes: */
710SCLASS struct pthread_cond_attr pthread_condattr_default
711#ifdef GLOBAL_PTHREAD_PRIVATE
712= { COND_TYPE_FAST, 0 };
713#else
714;
715#endif
716
717SCLASS int _clock_res_usec /* Clock resolution in usec. */
718#ifdef GLOBAL_PTHREAD_PRIVATE
719= CLOCK_RES_USEC;
720#else
721;
722#endif
723
724/* Garbage collector condition variable. */
725SCLASS pthread_cond_t _gc_cond
726#ifdef GLOBAL_PTHREAD_PRIVATE
727= NULL
728#endif
729;
730
731/*
732 * Array of signal actions for this process.
733 */
734SCLASS struct sigaction _thread_sigact[NSIG];
735
736/* Precomputed signal set for _thread_suspend. */
737SCLASS sigset_t _thread_suspend_sigset;
738
739/* Tracks the number of threads blocked while waiting for a spinlock. */
740SCLASS volatile int _spinblock_count
741#ifdef GLOBAL_PTHREAD_PRIVATE
742= 0
743#endif
744;
745
746/* Undefine the storage class specifier: */
747#undef SCLASS
748
749/*
750 * Function prototype definitions.
751 */
752__BEGIN_DECLS
753char *__ttyname_basic(int);
754char *__ttyname_r_basic(int, char *, size_t);
755char *ttyname_r(int, char *, size_t);
756void _cond_wait_backout(pthread_t);
757int _find_thread(pthread_t);
758pthread_t _get_curthread(void);
759void *_set_curthread(ucontext_t *, struct pthread *, int *);
760void _retire_thread(void *arch_id);
761void *_thread_stack_alloc(size_t, size_t);
762void _thread_stack_free(void *, size_t, size_t);
763int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
764int _mutex_cv_lock(pthread_mutex_t *);
765int _mutex_cv_unlock(pthread_mutex_t *);
766void _mutex_lock_backout(pthread_t);
767void _mutex_notify_priochange(pthread_t);
768int _mutex_reinit(pthread_mutex_t *);
769void _mutex_unlock_private(pthread_t);
770int _cond_reinit(pthread_cond_t *);
771void *_pthread_getspecific(pthread_key_t);
772int _pthread_key_create(pthread_key_t *, void (*) (void *));
773int _pthread_key_delete(pthread_key_t);
774int _pthread_mutex_destroy(pthread_mutex_t *);
775int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
776int _pthread_mutex_lock(pthread_mutex_t *);
777int _pthread_mutex_trylock(pthread_mutex_t *);
778int _pthread_mutex_unlock(pthread_mutex_t *);
779int _pthread_mutexattr_init(pthread_mutexattr_t *);
780int _pthread_mutexattr_destroy(pthread_mutexattr_t *);
781int _pthread_mutexattr_settype(pthread_mutexattr_t *, int);
782int _pthread_once(pthread_once_t *, void (*) (void));
783pthread_t _pthread_self(void);
784int _pthread_setspecific(pthread_key_t, const void *);
785int _spintrylock(spinlock_t *);
786void _thread_exit(char *, int, char *);
787void _thread_exit_cleanup(void);
788void *_thread_cleanup(pthread_t);
789void _thread_cleanupspecific(void);
790void _thread_dump_info(void);
791void _thread_init(void);
792void _thread_sig_wrapper(int sig, siginfo_t *info, void *context);
793void _thread_printf(int fd, const char *, ...);
794void _thread_start(void);
795void _thread_seterrno(pthread_t, int);
796pthread_addr_t _thread_gc(pthread_addr_t);
797void _thread_enter_cancellation_point(void);
798void _thread_leave_cancellation_point(void);
799void _thread_cancellation_point(void);
800int _thread_suspend(pthread_t thread, const struct timespec *abstime);
801void _thread_critical_enter(pthread_t);
802void _thread_critical_exit(pthread_t);
803void _thread_sigblock();
804void _thread_sigunblock();
805void adjust_prio_inheritance(struct pthread *);
806void adjust_prio_protection(struct pthread *);
807void init_td_common(struct pthread *, struct pthread_attr *, int);
808void init_tdlist(struct pthread *, int);
809void proc_sigact_copyin(int, const struct sigaction *);
810void proc_sigact_copyout(int, struct sigaction *);
811void readjust_priorities(struct pthread *, struct pthread_mutex *);
812struct sigaction *proc_sigact_sigaction(int);
813
814/* #include <sys/aio.h> */
815#ifdef _SYS_AIO_H_
816int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
817#endif
818
819/* #include <sys/event.h> */
820#ifdef _SYS_EVENT_H_
821int __sys_kevent(int, const struct kevent *, int, struct kevent *,
822 int, const struct timespec *);
823#endif
824
825/* #include <sys/ioctl.h> */
826#ifdef _SYS_IOCTL_H_
827int __sys_ioctl(int, unsigned long, ...);
828#endif
829
830/* #include <sys/mman.h> */
831#ifdef _SYS_MMAN_H_
832int __sys_msync(void *, size_t, int);
833#endif
834
835/* #include <sys/mount.h> */
836#ifdef _SYS_MOUNT_H_
837int __sys_fstatfs(int, struct statfs *);
838#endif
839
840/* #include <sys/socket.h> */
841#ifdef _SYS_SOCKET_H_
842int __sys_accept(int, struct sockaddr *, socklen_t *);
843int __sys_bind(int, const struct sockaddr *, socklen_t);
844int __sys_connect(int, const struct sockaddr *, socklen_t);
845int __sys_getpeername(int, struct sockaddr *, socklen_t *);
846int __sys_getsockname(int, struct sockaddr *, socklen_t *);
847int __sys_getsockopt(int, int, int, void *, socklen_t *);
848int __sys_listen(int, int);
849ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
850ssize_t __sys_recvmsg(int, struct msghdr *, int);
851int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
852ssize_t __sys_sendmsg(int, const struct msghdr *, int);
853ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
854int __sys_setsockopt(int, int, int, const void *, socklen_t);
855int __sys_shutdown(int, int);
856int __sys_socket(int, int, int);
857int __sys_socketpair(int, int, int, int *);
858#endif
859
860/* #include <sys/stat.h> */
861#ifdef _SYS_STAT_H_
862int __sys_fchflags(int, u_long);
863int __sys_fchmod(int, mode_t);
864int __sys_fstat(int, struct stat *);
865#endif
866
867/* #include <sys/uio.h> */
868#ifdef _SYS_UIO_H_
869ssize_t __sys_readv(int, const struct iovec *, int);
870ssize_t __sys_writev(int, const struct iovec *, int);
871#endif
872
873/* #include <sys/wait.h> */
874#ifdef WNOHANG
875pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
876#endif
877
878/* #include <dirent.h> */
879#ifdef _DIRENT_H_
880int __sys_getdirentries(int, char *, int, long *);
881#endif
882
883/* #include <fcntl.h> */
884#ifdef _SYS_FCNTL_H_
885int __sys_fcntl(int, int, ...);
886int __sys_flock(int, int);
887int __sys_open(const char *, int, ...);
888#endif
889
890/* #include <poll.h> */
891#ifdef _SYS_POLL_H_
892int __sys_poll(struct pollfd *, unsigned, int);
893#endif
894
895/* #include <signal.h> */
896#ifdef _SIGNAL_H_
897int __sys_sigaction(int, const struct sigaction *, struct sigaction *);
898int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
899int __sys_sigprocmask(int, const sigset_t *, sigset_t *);
900int __sys_sigreturn(ucontext_t *);
901#endif
902
903/* #include <unistd.h> */
904#ifdef _UNISTD_H_
905int __sys_close(int);
906int __sys_dup(int);
907int __sys_dup2(int, int);
908int __sys_execve(const char *, char * const *, char * const *);
909void __sys_exit(int);
910int __sys_fchown(int, uid_t, gid_t);
911pid_t __sys_fork(void);
912long __sys_fpathconf(int, int);
913int __sys_fsync(int);
914int __sys_pipe(int *);
915ssize_t __sys_read(int, void *, size_t);
916ssize_t __sys_write(int, const void *, size_t);
917#endif
918
919__END_DECLS
920
921#endif /* !_PTHREAD_PRIVATE_H */