thr_private.h revision 112958
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 112958 2003-04-01 22:39:31Z jeff $
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
64#include <machine/atomic.h>
65#include <sys/thr.h>
66#include <sys/umtx.h>
67
68/*
69 * Kernel fatal error handler macro.
70 */
71#define PANIC(string)   _thread_exit(__FILE__,__LINE__,string)
72
73
74/* Output debug messages like this: */
75#define stdout_debug(args...)	_thread_printf(STDOUT_FILENO, args)
76#define stderr_debug(args...)	_thread_printf(STDOUT_FILENO, args)
77
78/*
79 * State change macro without scheduling queue change:
80 */
81#define PTHREAD_SET_STATE(thrd, newstate) do {				\
82	(thrd)->state = newstate;					\
83	(thrd)->fname = __FILE__;					\
84	(thrd)->lineno = __LINE__;					\
85} while (0)
86
87/*
88 * State change macro with scheduling queue change - This must be
89 * called with GIANT held.
90 */
91#if defined(_PTHREADS_INVARIANTS)
92#include <assert.h>
93#define PTHREAD_ASSERT(cond, msg) do {	\
94	if (!(cond))			\
95		PANIC(msg);		\
96} while (0)
97#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
98	PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0),	\
99	    "Illegal call from signal handler");
100#define PTHREAD_NEW_STATE(thrd, newstate) do {				\
101	if ((thrd)->state != newstate) {				\
102		if ((thrd)->state == PS_RUNNING) {			\
103			PTHREAD_SET_STATE(thrd, newstate);		\
104		} else if (newstate == PS_RUNNING) { 			\
105			if (thr_kill(thrd->thr_id, SIGTHR))		\
106				abort();				\
107			PTHREAD_SET_STATE(thrd, newstate);		\
108		}							\
109	}								\
110} while (0)
111#else
112#define PTHREAD_ASSERT(cond, msg)
113#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
114#define PTHREAD_NEW_STATE(thrd, newstate) do {				\
115	if (thr_kill(thrd->thr_id, SIGTHR))				\
116		abort();						\
117	PTHREAD_SET_STATE(thrd, newstate);				\
118} while (0)
119#if 0
120#define PTHREAD_NEW_STATE(thrd, newstate) do {				\
121	if ((thrd)->state != newstate) {				\
122		if ((thrd)->state == PS_RUNNING) {			\
123		} else if (newstate == PS_RUNNING) { 			\
124			if (thr_kill(thrd->thr_id, SIGTHR))		\
125				abort();				\
126		}							\
127	}								\
128	PTHREAD_SET_STATE(thrd, newstate);				\
129} while (0)
130#endif
131#endif
132
133
134/*
135 * TailQ initialization values.
136 */
137#define TAILQ_INITIALIZER	{ NULL, NULL }
138
139#define	UMTX_INITIALIZER	{ NULL, NULL }
140
141struct pthread_mutex_attr {
142	enum pthread_mutextype	m_type;
143	int			m_protocol;
144	int			m_ceiling;
145	long			m_flags;
146};
147
148/*
149 * Static mutex initialization values.
150 */
151
152#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
153	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
154
155#define PTHREAD_MUTEX_STATIC_INITIALIZER   \
156	{ PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL,	\
157	0, 0, TAILQ_INITIALIZER }
158
159union pthread_mutex_data {
160        void    *m_ptr;
161        int     m_count;
162};
163
164struct pthread_mutex {
165        enum pthread_mutextype          m_type;
166        int                             m_protocol;
167        TAILQ_HEAD(mutex_head, pthread) m_queue;
168        struct pthread                  *m_owner;
169        union pthread_mutex_data        m_data;
170        long                            m_flags;
171        int                             m_refcount;
172
173        /*
174         * Used for priority inheritence and protection.
175         *
176         *   m_prio       - For priority inheritence, the highest active
177         *                  priority (threads locking the mutex inherit
178         *                  this priority).  For priority protection, the
179         *                  ceiling priority of this mutex.
180         *   m_saved_prio - mutex owners inherited priority before
181         *                  taking the mutex, restored when the owner
182         *                  unlocks the mutex.
183         */
184        int                             m_prio;
185        int                             m_saved_prio;
186
187        /*
188         * Link for list of all mutexes a thread currently owns.
189         */
190        TAILQ_ENTRY(pthread_mutex)      m_qe;
191
192        /*
193         * Lock for accesses to this structure.
194         */
195        spinlock_t                      lock;
196};
197
198/*
199 * Flags for mutexes.
200 */
201#define MUTEX_FLAGS_PRIVATE	0x01
202#define MUTEX_FLAGS_INITED	0x02
203#define MUTEX_FLAGS_BUSY	0x04
204
205/*
206 * Condition variable definitions.
207 */
208enum pthread_cond_type {
209	COND_TYPE_FAST,
210	COND_TYPE_MAX
211};
212
213struct pthread_cond {
214	enum pthread_cond_type		c_type;
215	TAILQ_HEAD(cond_head, pthread)	c_queue;
216	pthread_mutex_t			c_mutex;
217	void				*c_data;
218	long				c_flags;
219	int				c_seqno;
220
221	/*
222	 * Lock for accesses to this structure.
223	 */
224	struct umtx			c_lock;
225};
226
227struct pthread_cond_attr {
228	enum pthread_cond_type	c_type;
229	long			c_flags;
230};
231
232/*
233 * Flags for condition variables.
234 */
235#define COND_FLAGS_INITED	0x01
236
237/*
238 * Static cond initialization values.
239 */
240#define PTHREAD_COND_STATIC_INITIALIZER    \
241	{ COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
242	0, 0, UMTX_INITIALIZER }
243
244/*
245 * Semaphore definitions.
246 */
247struct sem {
248#define	SEM_MAGIC	((u_int32_t) 0x09fa4012)
249	u_int32_t	magic;
250	pthread_mutex_t	lock;
251	pthread_cond_t	gtzero;
252	u_int32_t	count;
253	u_int32_t	nwaiters;
254};
255
256/*
257 * Cleanup definitions.
258 */
259struct pthread_cleanup {
260	struct pthread_cleanup	*next;
261	void			(*routine) ();
262	void			*routine_arg;
263};
264
265struct pthread_attr {
266	int	sched_policy;
267	int	sched_inherit;
268	int	sched_interval;
269	int	prio;
270	int	suspend;
271	int	flags;
272	void	*arg_attr;
273	void	(*cleanup_attr) ();
274	void	*stackaddr_attr;
275	size_t	stacksize_attr;
276	size_t	guardsize_attr;
277};
278
279/*
280 * Thread creation state attributes.
281 */
282#define PTHREAD_CREATE_RUNNING			0
283#define PTHREAD_CREATE_SUSPENDED		1
284
285/*
286 * Miscellaneous definitions.
287 */
288#define PTHREAD_STACK_DEFAULT			65536
289/*
290 * Size of default red zone at the end of each stack.  In actuality, this "red
291 * zone" is merely an unmapped region, except in the case of the initial stack.
292 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK
293 * region, an unmapped gap between thread stacks achieves the same effect as
294 * explicitly mapped red zones.
295 * This is declared and initialized in uthread_init.c.
296 */
297extern int _pthread_guard_default;
298
299extern int _pthread_page_size;
300
301/*
302 * Maximum size of initial thread's stack.  This perhaps deserves to be larger
303 * than the stacks of other threads, since many applications are likely to run
304 * almost entirely on this stack.
305 */
306#define PTHREAD_STACK_INITIAL			0x100000
307
308/*
309 * Define the different priority ranges.  All applications have thread
310 * priorities constrained within 0-31.  The threads library raises the
311 * priority when delivering signals in order to ensure that signal
312 * delivery happens (from the POSIX spec) "as soon as possible".
313 * In the future, the threads library will also be able to map specific
314 * threads into real-time (cooperating) processes or kernel threads.
315 * The RT and SIGNAL priorities will be used internally and added to
316 * thread base priorities so that the scheduling queue can handle both
317 * normal and RT priority threads with and without signal handling.
318 *
319 * The approach taken is that, within each class, signal delivery
320 * always has priority over thread execution.
321 */
322#define PTHREAD_DEFAULT_PRIORITY		15
323#define PTHREAD_MIN_PRIORITY			0
324#define PTHREAD_MAX_PRIORITY			31	/* 0x1F */
325#define PTHREAD_SIGNAL_PRIORITY			32	/* 0x20 */
326#define PTHREAD_RT_PRIORITY			64	/* 0x40 */
327#define PTHREAD_FIRST_PRIORITY			PTHREAD_MIN_PRIORITY
328#define PTHREAD_LAST_PRIORITY	\
329	(PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY)
330#define PTHREAD_BASE_PRIORITY(prio)	((prio) & PTHREAD_MAX_PRIORITY)
331
332/*
333 * Clock resolution in microseconds.
334 */
335#define CLOCK_RES_USEC				10000
336#define CLOCK_RES_USEC_MIN			1000
337
338/*
339 * Time slice period in microseconds.
340 */
341#define TIMESLICE_USEC				20000
342
343/*
344 * XXX Define a thread-safe macro to get the current time of day
345 * which is updated at regular intervals by the scheduling signal
346 * handler.
347 */
348#define	GET_CURRENT_TOD(tv)	gettimeofday(&(tv), NULL)
349
350
351struct pthread_rwlockattr {
352	int		pshared;
353};
354
355struct pthread_rwlock {
356	pthread_mutex_t	lock;	/* monitor lock */
357	int		state;	/* 0 = idle  >0 = # of readers  -1 = writer */
358	pthread_cond_t	read_signal;
359	pthread_cond_t	write_signal;
360	int		blocked_writers;
361};
362
363/*
364 * Thread states.
365 */
366enum pthread_state {
367	PS_RUNNING,
368	PS_MUTEX_WAIT,
369	PS_COND_WAIT,
370	PS_SLEEP_WAIT,	/* XXX We need to wrap syscalls to set this state */
371	PS_WAIT_WAIT,
372	PS_JOIN,
373	PS_DEAD,
374	PS_DEADLOCK,
375	PS_STATE_MAX
376};
377
378
379/*
380 * File descriptor locking definitions.
381 */
382#define FD_READ             0x1
383#define FD_WRITE            0x2
384#define FD_RDWR             (FD_READ | FD_WRITE)
385
386union pthread_wait_data {
387	pthread_mutex_t	mutex;
388	pthread_cond_t	cond;
389	spinlock_t	*spinlock;
390	struct pthread	*thread;
391};
392
393struct join_status {
394	struct pthread	*thread;
395	void		*ret;
396	int		error;
397};
398
399struct pthread_state_data {
400	union pthread_wait_data psd_wait_data;
401	enum pthread_state	psd_state;
402	int			psd_flags;
403};
404
405struct pthread_specific_elem {
406	const void	*data;
407	int		seqno;
408};
409
410/*
411 * Thread structure.
412 */
413struct pthread {
414	/*
415	 * Magic value to help recognize a valid thread structure
416	 * from an invalid one:
417	 */
418#define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)
419	u_int32_t		magic;
420	char			*name;
421	u_int64_t		uniqueid; /* for gdb */
422	thr_id_t		thr_id;
423
424	/*
425	 * Lock for accesses to this thread structure.
426	 */
427	spinlock_t		lock;
428
429	/* Queue entry for list of all threads: */
430	TAILQ_ENTRY(pthread)	tle;
431
432	/* Queue entry for list of dead threads: */
433	TAILQ_ENTRY(pthread)	dle;
434
435	/*
436	 * Thread start routine, argument, stack pointer and thread
437	 * attributes.
438	 */
439	void			*(*start_routine)(void *);
440	void			*arg;
441	void			*stack;
442	struct pthread_attr	attr;
443
444	/*
445	 * Machine context, including signal state.
446	 */
447	ucontext_t		ctx;
448
449	/*
450	 * Cancelability flags - the lower 2 bits are used by cancel
451	 * definitions in pthread.h
452	 */
453#define PTHREAD_AT_CANCEL_POINT		0x0004
454#define PTHREAD_CANCELLING		0x0008
455
456	/*
457	 * Protected by Giant.
458	 */
459	int	cancelflags;
460
461	/* Thread state: */
462	enum pthread_state	state;
463
464	/*
465	 * Error variable used instead of errno. The function __error()
466	 * returns a pointer to this.
467	 */
468	int	error;
469
470	/*
471	 * The joiner is the thread that is joining to this thread.  The
472	 * join status keeps track of a join operation to another thread.
473	 */
474	struct pthread		*joiner;
475	struct join_status	join_status;
476
477	/*
478	 * A thread can belong to:
479	 *
480	 *   o A queue of threads waiting for a mutex
481	 *   o A queue of threads waiting for a condition variable
482	 *
483	 * A thread can also be joining a thread (the joiner field above).
484	 *
485	 * It must not be possible for a thread to belong to any of the
486	 * above queues while it is handling a signal.  Signal handlers
487	 * may longjmp back to previous stack frames circumventing normal
488	 * control flow.  This could corrupt queue integrity if the thread
489	 * retains membership in the queue.  Therefore, if a thread is a
490	 * member of one of these queues when a signal handler is invoked,
491	 * it must remove itself from the queue before calling the signal
492	 * handler and reinsert itself after normal return of the handler.
493	 *
494	 * Use sqe for synchronization (mutex and condition variable) queue
495	 * links.
496	 */
497	TAILQ_ENTRY(pthread)	sqe;	/* synchronization queue link */
498
499	/* Wait data. */
500	union pthread_wait_data data;
501
502	/* Miscellaneous flags; only set with signals deferred. */
503	int		flags;
504#define PTHREAD_FLAGS_PRIVATE	0x0001
505#define PTHREAD_EXITING		0x0002
506#define PTHREAD_FLAGS_IN_CONDQ	0x0080	/* in condition queue using sqe link*/
507#define PTHREAD_FLAGS_IN_MUTEXQ	0x0100	/* in mutex queue using sqe link */
508#define	PTHREAD_FLAGS_SUSPENDED	0x0200	/* thread is suspended */
509#define PTHREAD_FLAGS_TRACE	0x0400	/* for debugging purposes */
510#define PTHREAD_FLAGS_IN_SYNCQ	\
511    (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
512
513	/*
514	 * Base priority is the user setable and retrievable priority
515	 * of the thread.  It is only affected by explicit calls to
516	 * set thread priority and upon thread creation via a thread
517	 * attribute or default priority.
518	 */
519	char		base_priority;
520
521	/*
522	 * Inherited priority is the priority a thread inherits by
523	 * taking a priority inheritence or protection mutex.  It
524	 * is not affected by base priority changes.  Inherited
525	 * priority defaults to and remains 0 until a mutex is taken
526	 * that is being waited on by any other thread whose priority
527	 * is non-zero.
528	 */
529	char		inherited_priority;
530
531	/*
532	 * Active priority is always the maximum of the threads base
533	 * priority and inherited priority.  When there is a change
534	 * in either the base or inherited priority, the active
535	 * priority must be recalculated.
536	 */
537	char		active_priority;
538
539	/* Number of priority ceiling or protection mutexes owned. */
540	int		priority_mutex_count;
541
542	/*
543	 * Queue of currently owned mutexes.
544	 */
545	TAILQ_HEAD(, pthread_mutex)	mutexq;
546
547	void				*ret;
548	struct pthread_specific_elem	*specific;
549	int				specific_data_count;
550
551	/*
552	 * Architecture specific id field used for _{get, set}_curthread()
553	 * interface.
554	 */
555	void			*arch_id;
556
557	/* Cleanup handlers Link List */
558	struct pthread_cleanup *cleanup;
559	char			*fname;	/* Ptr to source file name  */
560	int			lineno;	/* Source line number.      */
561};
562
563/*
564 * Global variables for the uthread kernel.
565 */
566
567SCLASS void *_usrstack
568#ifdef GLOBAL_PTHREAD_PRIVATE
569= (void *) USRSTACK;
570#else
571;
572#endif
573
574/* List of all threads: */
575SCLASS TAILQ_HEAD(, pthread)	_thread_list
576#ifdef GLOBAL_PTHREAD_PRIVATE
577= TAILQ_HEAD_INITIALIZER(_thread_list);
578#else
579;
580#endif
581
582/* Dead threads: */
583SCLASS TAILQ_HEAD(, pthread) _dead_list
584#ifdef GLOBAL_PTHREAD_PRIVATE
585= TAILQ_HEAD_INITIALIZER(_dead_list);
586#else
587;
588#endif
589
590/* Initial thread: */
591SCLASS struct pthread *_thread_initial
592#ifdef GLOBAL_PTHREAD_PRIVATE
593= NULL;
594#else
595;
596#endif
597
598/* Default thread attributes: */
599SCLASS struct pthread_attr pthread_attr_default
600#ifdef GLOBAL_PTHREAD_PRIVATE
601= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
602	PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL,
603	PTHREAD_STACK_DEFAULT, -1 };
604#else
605;
606#endif
607
608/* Default mutex attributes: */
609SCLASS struct pthread_mutex_attr pthread_mutexattr_default
610#ifdef GLOBAL_PTHREAD_PRIVATE
611= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
612#else
613;
614#endif
615
616/* Default condition variable attributes: */
617SCLASS struct pthread_cond_attr pthread_condattr_default
618#ifdef GLOBAL_PTHREAD_PRIVATE
619= { COND_TYPE_FAST, 0 };
620#else
621;
622#endif
623
624SCLASS int    _clock_res_usec		/* Clock resolution in usec.	*/
625#ifdef GLOBAL_PTHREAD_PRIVATE
626= CLOCK_RES_USEC;
627#else
628;
629#endif
630
631/* Giant lock. */
632SCLASS struct umtx _giant_mutex
633#ifdef GLOBAL_PTHREAD_PRIVATE
634=  UMTX_INITIALIZER
635#endif
636;
637
638SCLASS int _giant_count;
639
640/* Garbage collector mutex and condition variable. */
641SCLASS	pthread_mutex_t _gc_mutex
642#ifdef GLOBAL_PTHREAD_PRIVATE
643= NULL
644#endif
645;
646SCLASS	pthread_cond_t  _gc_cond
647#ifdef GLOBAL_PTHREAD_PRIVATE
648= NULL
649#endif
650;
651
652/*
653 * Array of signal actions for this process.
654 */
655SCLASS struct  sigaction _thread_sigact[NSIG];
656
657/* Tracks the number of threads blocked while waiting for a spinlock. */
658SCLASS	volatile int	_spinblock_count
659#ifdef GLOBAL_PTHREAD_PRIVATE
660= 0
661#endif
662;
663
664/*
665 * And, should we climb the beanstalk,
666 * We'll meet his brother, Giant.
667 */
668void GIANT_LOCK(pthread_t curthread);
669void GIANT_UNLOCK(pthread_t curthread);
670
671/* Undefine the storage class specifier: */
672#undef  SCLASS
673
674/*
675 * Function prototype definitions.
676 */
677__BEGIN_DECLS
678char    *__ttyname_basic(int);
679char    *__ttyname_r_basic(int, char *, size_t);
680char    *ttyname_r(int, char *, size_t);
681void	_cond_wait_backout(pthread_t);
682int     _find_thread(pthread_t);
683struct pthread *_get_curthread_slow(void);
684struct pthread *_get_curthread(void);
685void	*_set_curthread(struct pthread *);
686void	_retire_thread(void *arch_id);
687void	*_thread_stack_alloc(size_t, size_t);
688void	_thread_stack_free(void *, size_t, size_t);
689int     _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
690int	_mutex_cv_lock(pthread_mutex_t *);
691int	_mutex_cv_unlock(pthread_mutex_t *);
692void	_mutex_lock_backout(pthread_t);
693void	_mutex_notify_priochange(pthread_t);
694int	_mutex_reinit(pthread_mutex_t *);
695void	_mutex_unlock_private(pthread_t);
696int	_cond_reinit(pthread_cond_t *);
697void	*_pthread_getspecific(pthread_key_t);
698int	_pthread_key_create(pthread_key_t *, void (*) (void *));
699int	_pthread_key_delete(pthread_key_t);
700int	_pthread_mutex_destroy(pthread_mutex_t *);
701int	_pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
702int	_pthread_mutex_lock(pthread_mutex_t *);
703int	_pthread_mutex_trylock(pthread_mutex_t *);
704int	_pthread_mutex_unlock(pthread_mutex_t *);
705int	_pthread_mutexattr_init(pthread_mutexattr_t *);
706int	_pthread_mutexattr_destroy(pthread_mutexattr_t *);
707int	_pthread_mutexattr_settype(pthread_mutexattr_t *, int);
708int	_pthread_once(pthread_once_t *, void (*) (void));
709pthread_t _pthread_self(void);
710int	_pthread_setspecific(pthread_key_t, const void *);
711void    _thread_exit(char *, int, char *);
712void    _thread_exit_cleanup(void);
713void    *_thread_cleanup(pthread_t);
714void    _thread_cleanupspecific(void);
715void    _thread_dump_info(void);
716void    _thread_init(void);
717void	_thread_sig_wrapper(int sig, siginfo_t *info, ucontext_t *context);
718void	_thread_printf(int fd, const char *, ...);
719void    _thread_start(void);
720void	_thread_seterrno(pthread_t, int);
721pthread_addr_t _thread_gc(pthread_addr_t);
722void	_thread_enter_cancellation_point(void);
723void	_thread_leave_cancellation_point(void);
724void	_thread_cancellation_point(void);
725int	_thread_suspend(pthread_t thread, struct timespec *abstime);
726
727/* #include <sys/aio.h> */
728#ifdef _SYS_AIO_H_
729int	__sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
730#endif
731
732/* #include <sys/event.h> */
733#ifdef _SYS_EVENT_H_
734int	__sys_kevent(int, const struct kevent *, int, struct kevent *,
735	    int, const struct timespec *);
736#endif
737
738/* #include <sys/ioctl.h> */
739#ifdef _SYS_IOCTL_H_
740int	__sys_ioctl(int, unsigned long, ...);
741#endif
742
743/* #include <sys/mman.h> */
744#ifdef _SYS_MMAN_H_
745int	__sys_msync(void *, size_t, int);
746#endif
747
748/* #include <sys/mount.h> */
749#ifdef _SYS_MOUNT_H_
750int	__sys_fstatfs(int, struct statfs *);
751#endif
752
753/* #include <sys/socket.h> */
754#ifdef _SYS_SOCKET_H_
755int	__sys_accept(int, struct sockaddr *, socklen_t *);
756int	__sys_bind(int, const struct sockaddr *, socklen_t);
757int	__sys_connect(int, const struct sockaddr *, socklen_t);
758int	__sys_getpeername(int, struct sockaddr *, socklen_t *);
759int	__sys_getsockname(int, struct sockaddr *, socklen_t *);
760int	__sys_getsockopt(int, int, int, void *, socklen_t *);
761int	__sys_listen(int, int);
762ssize_t	__sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
763ssize_t	__sys_recvmsg(int, struct msghdr *, int);
764int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
765ssize_t	__sys_sendmsg(int, const struct msghdr *, int);
766ssize_t	__sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
767int	__sys_setsockopt(int, int, int, const void *, socklen_t);
768int	__sys_shutdown(int, int);
769int	__sys_socket(int, int, int);
770int	__sys_socketpair(int, int, int, int *);
771#endif
772
773/* #include <sys/stat.h> */
774#ifdef _SYS_STAT_H_
775int	__sys_fchflags(int, u_long);
776int	__sys_fchmod(int, mode_t);
777int	__sys_fstat(int, struct stat *);
778#endif
779
780/* #include <sys/uio.h> */
781#ifdef _SYS_UIO_H_
782ssize_t	__sys_readv(int, const struct iovec *, int);
783ssize_t	__sys_writev(int, const struct iovec *, int);
784#endif
785
786/* #include <sys/wait.h> */
787#ifdef WNOHANG
788pid_t	__sys_wait4(pid_t, int *, int, struct rusage *);
789#endif
790
791/* #include <dirent.h> */
792#ifdef _DIRENT_H_
793int	__sys_getdirentries(int, char *, int, long *);
794#endif
795
796/* #include <fcntl.h> */
797#ifdef _SYS_FCNTL_H_
798int	__sys_fcntl(int, int, ...);
799int	__sys_flock(int, int);
800int	__sys_open(const char *, int, ...);
801#endif
802
803/* #include <poll.h> */
804#ifdef _SYS_POLL_H_
805int	__sys_poll(struct pollfd *, unsigned, int);
806#endif
807
808/* #include <signal.h> */
809#ifdef _SIGNAL_H_
810int	__sys_sigaction(int, const struct sigaction *, struct sigaction *);
811int	__sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
812int	__sys_sigprocmask(int, const sigset_t *, sigset_t *);
813int	__sys_sigreturn(ucontext_t *);
814#endif
815
816/* #include <unistd.h> */
817#ifdef _UNISTD_H_
818int	__sys_close(int);
819int	__sys_dup(int);
820int	__sys_dup2(int, int);
821int	__sys_execve(const char *, char * const *, char * const *);
822void	__sys_exit(int);
823int	__sys_fchown(int, uid_t, gid_t);
824pid_t	__sys_fork(void);
825long	__sys_fpathconf(int, int);
826int	__sys_fsync(int);
827int	__sys_pipe(int *);
828ssize_t	__sys_read(int, void *, size_t);
829ssize_t	__sys_write(int, const void *, size_t);
830#endif
831
832__END_DECLS
833
834#endif  /* !_PTHREAD_PRIVATE_H */
835