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