1 /*	$OpenBSD: pthread_private.h,v 1.53 2004/06/07 21:11:23 marc Exp $	*/
2 /*
3  * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by John Birrell.
17  * 4. Neither the name of the author nor the names of any co-contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Private thread definitions for the uthread kernel.
34  *
35  * $FreeBSD: pthread_private.h,v 1.27 1999/09/29 15:18:38 marcel Exp $
36  */
37 
38 #ifndef _PTHREAD_PRIVATE_H
39 #define _PTHREAD_PRIVATE_H
40 
41 /*
42  * Evaluate the storage class specifier.
43  */
44 #ifdef GLOBAL_PTHREAD_PRIVATE
45 #define SCLASS
46 #else
47 #define SCLASS extern
48 #endif
49 
50 /*
51  * Include files.
52  */
53 #include <signal.h>
54 #include <stdio.h>
55 #include <sys/queue.h>
56 #include <sys/types.h>
57 #include <sys/time.h>
58 #include <sched.h>
59 #include <spinlock.h>
60 #include <pthread_np.h>
61 #include "thread_private.h"
62 #include "uthread_machdep.h"
63 
64 /*
65  * Workaround until we have ENOTSUP in errno.h
66  */
67 #define ENOTSUP			EOPNOTSUPP
68 
69 /*
70  * Kernel fatal error handler macro.
71  */
72 #define PANIC(string)   _thread_exit(__FILE__,__LINE__,string)
73 
74 /* Output debug messages like this: */
75 #define	stdout_debug(_x)	_thread_sys_write(1,_x,strlen(_x));
76 #define	stderr_debug(_x)	_thread_sys_write(2,_x,strlen(_x));
77 
78 
79 /*
80  * Priority queue manipulation macros (using pqe link):
81  */
82 #define PTHREAD_PRIOQ_INSERT_HEAD(thrd)	_pq_insert_head(&_readyq,thrd)
83 #define PTHREAD_PRIOQ_INSERT_TAIL(thrd)	_pq_insert_tail(&_readyq,thrd)
84 #define PTHREAD_PRIOQ_REMOVE(thrd)	_pq_remove(&_readyq,thrd)
85 #define PTHREAD_PRIOQ_FIRST()		_pq_first(&_readyq)
86 
87 /*
88  * Waiting queue manipulation macros (using pqe link):
89  */
90 #define PTHREAD_WAITQ_REMOVE(thrd)	_waitq_remove(thrd)
91 #define PTHREAD_WAITQ_INSERT(thrd)	_waitq_insert(thrd)
92 
93 #if defined(_PTHREADS_INVARIANTS)
94 #define PTHREAD_WAITQ_CLEARACTIVE()	_waitq_clearactive()
95 #define PTHREAD_WAITQ_SETACTIVE()	_waitq_setactive()
96 #else
97 #define PTHREAD_WAITQ_CLEARACTIVE()
98 #define PTHREAD_WAITQ_SETACTIVE()
99 #endif
100 
101 /*
102  * Work queue manipulation macros (using qe link):
103  */
104 #define PTHREAD_WORKQ_INSERT(thrd) do {					\
105 	TAILQ_INSERT_TAIL(&_workq,thrd,qe);				\
106 	(thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ;			\
107 } while (0)
108 #define PTHREAD_WORKQ_REMOVE(thrd) do {					\
109 	TAILQ_REMOVE(&_workq,thrd,qe);					\
110 	(thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ;			\
111 } while (0)
112 
113 
114 /*
115  * State change macro without scheduling queue change:
116  */
117 #define PTHREAD_SET_STATE(thrd, newstate) do {				\
118 	(thrd)->state = newstate;					\
119 	(thrd)->fname = __FILE__;					\
120 	(thrd)->lineno = __LINE__;					\
121 } while (0)
122 
123 /*
124  * State change macro with scheduling queue change - This must be
125  * called with preemption deferred (see thread_kern_sched_[un]defer).
126  */
127 #if defined(_PTHREADS_INVARIANTS)
128 #include <assert.h>
129 #define PTHREAD_ASSERT(cond, msg) do {	\
130 	if (!(cond))			\
131 		PANIC(msg);		\
132 } while (0)
133 #define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
134 	PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0),	\
135 	    "Illegal call from signal handler");
136 #define PTHREAD_NEW_STATE(thrd, newstate) do {				\
137 	if (_thread_kern_new_state != 0)				\
138 		PANIC("Recursive PTHREAD_NEW_STATE");			\
139 	_thread_kern_new_state = 1;					\
140 	if ((thrd)->state != newstate) {				\
141 		if ((thrd)->state == PS_RUNNING) {			\
142 			PTHREAD_PRIOQ_REMOVE(thrd);			\
143 			PTHREAD_WAITQ_INSERT(thrd);			\
144 		} else if (newstate == PS_RUNNING) { 			\
145 			PTHREAD_WAITQ_REMOVE(thrd);			\
146 			PTHREAD_PRIOQ_INSERT_TAIL(thrd);		\
147 		}							\
148 	}								\
149 	_thread_kern_new_state = 0;					\
150 	PTHREAD_SET_STATE(thrd, newstate);				\
151 } while (0)
152 #else
153 #define PTHREAD_ASSERT(cond, msg)
154 #define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
155 #define PTHREAD_NEW_STATE(thrd, newstate) do {				\
156 	if ((thrd)->state != newstate) {				\
157 		if ((thrd)->state == PS_RUNNING) {			\
158 			PTHREAD_PRIOQ_REMOVE(thrd);			\
159 			PTHREAD_WAITQ_INSERT(thrd);			\
160 		} else if (newstate == PS_RUNNING) { 			\
161 			PTHREAD_WAITQ_REMOVE(thrd);			\
162 			PTHREAD_PRIOQ_INSERT_TAIL(thrd);		\
163 		}							\
164 	}								\
165 	PTHREAD_SET_STATE(thrd, newstate);				\
166 } while (0)
167 #endif
168 
169 /*
170  * Define the signals to be used for scheduling.
171  */
172 #if defined(_PTHREADS_COMPAT_SCHED) || defined(PROF)
173 #define _ITIMER_SCHED_TIMER	ITIMER_VIRTUAL
174 #define _SCHED_SIGNAL		SIGVTALRM
175 #else
176 #define _ITIMER_SCHED_TIMER	ITIMER_PROF
177 #define _SCHED_SIGNAL		SIGPROF
178 #endif
179 
180 /* Lists with volatile elements */
181 #define V_TAILQ_HEAD(name, type)				\
182 volatile struct name {						\
183 	struct type * tqh_first;				\
184 	struct type * volatile * tqh_last; 			\
185 }
186 
187 #define V_TAILQ_ENTRY(type)					\
188 volatile struct {						\
189 	struct type * tqe_next;					\
190 	struct type * volatile * tqe_prev; 			\
191 }
192 
193 /* List of all threads: */
194 typedef V_TAILQ_HEAD(, pthread)	_thread_list_t;
195 
196 /*
197  * Priority queues.
198  *
199  * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
200  */
201 typedef struct pq_list {
202 	_thread_list_t		pl_head; /* list of threads at this priority */
203 	TAILQ_ENTRY(pq_list)	pl_link; /* link for queue of priority lists */
204 	int			pl_prio; /* the priority of this list */
205 	int			pl_queued; /* is this in the priority queue */
206 } pq_list_t;
207 
208 typedef struct pq_queue {
209 	TAILQ_HEAD(, pq_list)	 pq_queue; /* queue of priority lists */
210 	pq_list_t		*pq_lists; /* array of all priority lists */
211 	int			 pq_size;  /* number of priority lists */
212 } pq_queue_t;
213 
214 
215 /*
216  * TailQ initialization values.
217  */
218 #define TAILQ_INITIALIZER	{ NULL, NULL }
219 
220 /*
221  * Mutex definitions.
222  */
223 union pthread_mutex_data {
224 	void	*m_ptr;
225 	int	m_count;
226 };
227 
228 struct pthread_mutex {
229 	enum pthread_mutextype		m_type;
230 	int				m_protocol;
231 	V_TAILQ_HEAD(mutex_head, pthread)	m_queue;
232 	struct pthread			*m_owner;
233 	union pthread_mutex_data	m_data;
234 	long				m_flags;
235 	int				m_refcount;
236 
237 	/*
238 	 * Used for priority inheritence and protection.
239 	 *
240 	 *   m_prio       - For priority inheritence, the highest active
241 	 *                  priority (threads locking the mutex inherit
242 	 *                  this priority).  For priority protection, the
243 	 *                  ceiling priority of this mutex.
244 	 *   m_saved_prio - mutex owners inherited priority before
245 	 *                  taking the mutex, restored when the owner
246 	 *                  unlocks the mutex.
247 	 */
248 	int				m_prio;
249 	int				m_saved_prio;
250 
251 	/*
252 	 * Link for list of all mutexes a thread currently owns.
253 	 */
254 	V_TAILQ_ENTRY(pthread_mutex volatile)	m_qe;
255 
256 	/*
257 	 * Lock for accesses to this structure.
258 	 */
259 	spinlock_t			lock;
260 };
261 
262 /*
263  * Flags for mutexes.
264  */
265 #define MUTEX_FLAGS_PRIVATE	0x01
266 #define MUTEX_FLAGS_INITED	0x02
267 #define MUTEX_FLAGS_BUSY	0x04
268 
269 /*
270  * Static mutex initialization values.
271  */
272 #define PTHREAD_MUTEX_STATIC_INITIALIZER   \
273 	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \
274 	NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \
275 	_SPINLOCK_INITIALIZER }
276 
277 struct pthread_mutex_attr {
278 	enum pthread_mutextype	m_type;
279 	int			m_protocol;
280 	int			m_ceiling;
281 	long			m_flags;
282 };
283 
284 #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
285 	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
286 
287 /*
288  * Condition variable definitions.
289  */
290 enum pthread_cond_type {
291 	COND_TYPE_FAST,
292 	COND_TYPE_MAX
293 };
294 
295 struct pthread_cond {
296 	enum pthread_cond_type		c_type;
297 	V_TAILQ_HEAD(cond_head, pthread) c_queue;
298 	pthread_mutex_t			c_mutex;
299 	long				c_flags;
300 	int				c_seqno;
301 
302 	/*
303 	 * Lock for accesses to this structure.
304 	 */
305 	spinlock_t			lock;
306 };
307 
308 struct pthread_cond_attr {
309 	enum pthread_cond_type	c_type;
310 	long			c_flags;
311 };
312 
313 /*
314  * Flags for condition variables.
315  */
316 #define COND_FLAGS_PRIVATE	0x01
317 #define COND_FLAGS_INITED	0x02
318 #define COND_FLAGS_BUSY		0x04
319 
320 /*
321  * Static cond initialization values.
322  */
323 #define PTHREAD_COND_STATIC_INITIALIZER    \
324 	{ COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
325 	0, 0, _SPINLOCK_INITIALIZER }
326 
327 /*
328  * Semaphore definitions.
329  */
330 struct sem {
331 #define	SEM_MAGIC	((u_int32_t) 0x09fa4012)
332 	u_int32_t	magic;
333 	pthread_mutex_t	lock;
334 	pthread_cond_t	gtzero;
335 	u_int32_t	count;
336 	u_int32_t	nwaiters;
337 };
338 
339 /*
340  * Cleanup definitions.
341  */
342 struct pthread_cleanup {
343 	struct pthread_cleanup	*next;
344 	void			(*routine)(void*);
345 	void			*routine_arg;
346 };
347 
348 struct pthread_attr {
349 	int	sched_policy;
350 	int	sched_inherit;
351 	int	sched_interval;
352 	int	prio;
353 	int	suspend;
354 	int	flags;
355 	void	*arg_attr;
356 	void	(*cleanup_attr)(void*);
357 	void	*stackaddr_attr;
358 	size_t	stacksize_attr;
359 	size_t	guardsize_attr;
360 };
361 
362 /*
363  * Thread creation state attributes.
364  */
365 #define PTHREAD_CREATE_RUNNING			0
366 #define PTHREAD_CREATE_SUSPENDED		1
367 
368 /*
369  * Additional state for a thread suspended with pthread_suspend_np().
370  */
371 enum pthread_susp {
372 	SUSP_NO,	/* Not suspended. */
373 	SUSP_YES,	/* Suspended. */
374 	SUSP_JOIN,	/* Suspended, joining. */
375 	SUSP_NOWAIT,	/* Suspended, was in a mutex or condition queue. */
376 	SUSP_MUTEX_WAIT,/* Suspended, still in a mutex queue. */
377 	SUSP_COND_WAIT	/* Suspended, still in a condition queue. */
378 };
379 
380 /*
381  * Miscellaneous definitions.
382  */
383 #define PTHREAD_STACK_DEFAULT			65536
384 /*
385  * Maximum size of initial thread's stack.  This perhaps deserves to be larger
386  * than the stacks of other threads, since many applications are likely to run
387  * almost entirely on this stack.
388  */
389 #define PTHREAD_STACK_INITIAL			0x100000
390 
391 /* Address immediately beyond the beginning of the initial thread stack. */
392 #define _POSIX_THREAD_ATTR_STACKSIZE
393 
394 /*
395  * Define the different priority ranges.  All applications have thread
396  * priorities constrained within 0-31.  The threads library raises the
397  * priority when delivering signals in order to ensure that signal
398  * delivery happens (from the POSIX spec) "as soon as possible".
399  * In the future, the threads library will also be able to map specific
400  * threads into real-time (cooperating) processes or kernel threads.
401  * The RT and SIGNAL priorities will be used internally and added to
402  * thread base priorities so that the scheduling queue can handle both
403  * normal and RT priority threads with and without signal handling.
404  *
405  * The approach taken is that, within each class, signal delivery
406  * always has priority over thread execution.
407  */
408 #define PTHREAD_DEFAULT_PRIORITY		15
409 #define PTHREAD_MIN_PRIORITY			0
410 #define PTHREAD_MAX_PRIORITY			31	/* 0x1F */
411 #define PTHREAD_SIGNAL_PRIORITY			32	/* 0x20 */
412 #define PTHREAD_RT_PRIORITY			64	/* 0x40 */
413 #define PTHREAD_FIRST_PRIORITY			PTHREAD_MIN_PRIORITY
414 #define PTHREAD_LAST_PRIORITY	\
415 	(PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY)
416 #define PTHREAD_BASE_PRIORITY(prio)	((prio) & PTHREAD_MAX_PRIORITY)
417 
418 /*
419  * Clock resolution in microseconds.
420  */
421 #define CLOCK_RES_USEC				10000
422 #define CLOCK_RES_USEC_MIN			1000
423 
424 /*
425  * Time slice period in microseconds.
426  */
427 #define TIMESLICE_USEC				20000
428 
429 /*
430  * Define a thread-safe macro to get the current time of day
431  * which is updated at regular intervals by the scheduling signal
432  * handler.
433  */
434 #define	GET_CURRENT_TOD(tv)				\
435 	do {						\
436 		tv.tv_sec = _sched_tod.tv_sec;		\
437 		tv.tv_usec = _sched_tod.tv_usec;	\
438 	} while (tv.tv_sec != _sched_tod.tv_sec)
439 
440 
441 struct pthread_key {
442 	spinlock_t	lock;
443 	volatile int	allocated;
444 	volatile int	count;
445 	void            (*destructor)(void*);
446 };
447 
448 struct pthread_rwlockattr {
449 	int		pshared;
450 };
451 
452 struct pthread_rwlock {
453 	pthread_mutex_t	lock;	/* monitor lock */
454 	int		state;	/* 0 = idle  >0 = # of readers  -1 = writer */
455 	pthread_cond_t	read_signal;
456 	pthread_cond_t	write_signal;
457 	int		blocked_writers;
458 };
459 
460 /*
461  * Thread states.
462  */
463 enum pthread_state {
464 	PS_RUNNING,
465 	PS_SIGTHREAD,
466 	PS_MUTEX_WAIT,
467 	PS_COND_WAIT,
468 	PS_FDLR_WAIT,
469 	PS_FDLW_WAIT,
470 	PS_FDR_WAIT,
471 	PS_FDW_WAIT,
472 	PS_FILE_WAIT,
473 	PS_POLL_WAIT,
474 	PS_SELECT_WAIT,
475 	PS_SLEEP_WAIT,
476 	PS_WAIT_WAIT,
477 	PS_SIGSUSPEND,
478 	PS_SIGWAIT,
479 	PS_SPINBLOCK,
480 	PS_JOIN,
481 	PS_SUSPENDED,
482 	PS_DEAD,
483 	PS_DEADLOCK,
484 	PS_STATE_MAX
485 };
486 
487 
488 /*
489  * File descriptor locking definitions are defined in "thread_private.h"
490  */
491 
492 /*
493  * File descriptor table structure.
494  */
495 struct fd_table_entry {
496 	/*
497 	 * Lock for accesses to this file descriptor table
498 	 * entry. This is passed to _spinlock() to provide atomic
499 	 * access to this structure. It does *not* represent the
500 	 * state of the lock on the file descriptor.
501 	 */
502 	spinlock_t		lock;
503 	_thread_list_t		r_queue;	/* Read queue.                */
504 	_thread_list_t		w_queue;	/* Write queue.               */
505 	struct pthread		*r_owner;	/* thread owning read lock.   */
506 	struct pthread		*w_owner;	/* thread owning write lock.  */
507 	const char		*r_fname;	/* read lock source file name */
508 	int			r_lineno;	/* Read lock source line no.  */
509 	const char		*w_fname;	/* write lock src file name   */
510 	int			w_lineno;	/* Write lock src line no.    */
511 	int			r_lockcount;	/* Count for FILE read locks. */
512 	int			w_lockcount;	/* Count for FILE write locks.*/
513 	int			flags;		/* Flags used in open.        */
514 	int			refcnt;		/* how many fds use this entry*/
515 };
516 
517 struct pthread_poll_data {
518 	int	nfds;
519 	struct pollfd *fds;
520 };
521 
522 union pthread_wait_data {
523 	pthread_mutex_t	mutex;
524 	pthread_cond_t	cond;
525 	const sigset_t	*sigwait;	/* Waiting on a signal in sigwait */
526 	struct {
527 		short		fd;	/* Used when thread waiting on fd */
528 		short		branch;	/* Line number, for debugging.    */
529 		const char	*fname;	/* Source file name for debugging.*/
530 	} fd;
531 	FILE		*fp;
532 	struct pthread_poll_data *poll_data;
533 	spinlock_t	*spinlock;
534 	struct pthread	*thread;
535 };
536 
537 /* Spare thread stack. */
538 struct stack {
539 	SLIST_ENTRY(stack)	qe; /* Queue entry for this stack. */
540 	void 			*base;		/* Bottom of useful stack */
541 	size_t			size;		/* Size of useful stack */
542 	void			*redzone;	/* Red zone location */
543 	void 			*storage;	/* allocated storage */
544 };
545 
546 /*
547  * Define a continuation routine that can be used to perform a
548  * transfer of control:
549  */
550 typedef void	(*thread_continuation_t) (void *);
551 
552 typedef V_TAILQ_ENTRY(pthread) pthread_entry_t;
553 
554 struct join_status {
555 	struct pthread	*thread;
556 	void		*ret;
557 	int		error;
558 };
559 
560 /*
561  * Thread structure.
562  */
563 struct pthread {
564 	/*
565 	 * Magic value to help recognize a valid thread structure
566 	 * from an invalid one:
567 	 */
568 #define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)
569 	u_int32_t		magic;
570 	char			*name;
571 
572 	/*
573 	 * Lock for accesses to this thread structure.
574 	 */
575 	spinlock_t		lock;
576 
577 	/* Queue entry for list of all threads: */
578 	pthread_entry_t		tle;
579 
580 	/* Queue entry for list of dead threads: */
581 	pthread_entry_t		dle;
582 
583 	/*
584 	 * Thread start routine, argument, stack pointer and thread
585 	 * attributes.
586 	 */
587 	void			*(*start_routine)(void *);
588 	void			*arg;
589 	struct stack		*stack;
590 	struct pthread_attr	attr;
591 
592 	/*
593 	 * Saved signal context used in call to sigreturn by
594 	 * _thread_kern_sched if sig_saved is TRUE.
595 	 */
596 	struct  sigcontext saved_sigcontext;
597 
598 	/*
599 	 * Machine-dependent context, valid if sig_saved is FALSE.
600 	 */
601 	struct _machdep_state	_machdep;
602 
603 	/*
604 	 * TRUE if the last state saved was a signal context. FALSE if the
605 	 * last state saved was a jump buffer.
606 	 */
607 	int	sig_saved;
608 
609 	/*
610 	 * Cancelability flags - the lower 2 bits are used by cancel
611 	 * definitions in pthread.h
612 	 */
613 #define PTHREAD_AT_CANCEL_POINT		0x0004
614 #define PTHREAD_CANCELLING		0x0008
615 #define PTHREAD_CANCEL_NEEDED		0x0010
616 	int	cancelflags;
617 
618 	enum pthread_susp	suspended;
619 
620 	thread_continuation_t	continuation;
621 
622 	/*
623 	 * Current signal mask and pending signals.
624 	 */
625 	sigset_t	sigmask;
626 	sigset_t	sigpend;
627 
628 	/* Thread state: */
629 	enum pthread_state	state;
630 
631 	/* Scheduling clock when this thread was last made active. */
632 	long	last_active;
633 
634 	/* Scheduling clock when this thread was last made inactive. */
635 	long	last_inactive;
636 
637 	/*
638 	 * Number of microseconds accumulated by this thread when
639 	 * time slicing is active.
640 	 */
641 	long	slice_usec;
642 
643 	/*
644 	 * Time to wake up thread. This is used for sleeping threads and
645 	 * for any operation which may time out (such as select).
646 	 */
647 	struct timespec	wakeup_time;
648 
649 	/* TRUE if operation has timed out. */
650 	int	timeout;
651 
652 	/*
653 	 * Error variable used instead of errno. The function __error()
654 	 * returns a pointer to this.
655 	 */
656 	int	error;
657 
658 	/*
659 	 * The joiner is the thread that is joining to this thread.  The
660 	 * join status keeps track of a join operation to another thread.
661 	 */
662 	struct pthread		*joiner;
663 	struct join_status	join_status;
664 
665 	/*
666 	 * The current thread can belong to only one scheduling queue at
667 	 * a time (ready or waiting queue).  It can also belong to:
668 	 *
669 	 *   o A queue of threads waiting for a mutex
670 	 *   o A queue of threads waiting for a condition variable
671 	 *   o A queue of threads waiting for a file descriptor lock
672 	 *   o A queue of threads needing work done by the kernel thread
673 	 *     (waiting for a spinlock or file I/O)
674 	 *
675 	 * A thread can also be joining a thread (the joiner field above).
676 	 *
677 	 * It must not be possible for a thread to belong to any of the
678 	 * above queues while it is handling a signal.  Signal handlers
679 	 * may longjmp back to previous stack frames circumventing normal
680 	 * control flow.  This could corrupt queue integrity if the thread
681 	 * retains membership in the queue.  Therefore, if a thread is a
682 	 * member of one of these queues when a signal handler is invoked,
683 	 * it must remove itself from the queue before calling the signal
684 	 * handler and reinsert itself after normal return of the handler.
685 	 *
686 	 * Use pqe for the scheduling queue link (both ready and waiting),
687 	 * sqe for synchronization (mutex and condition variable) queue
688 	 * links, and qe for all other links.
689 	 */
690 
691 	pthread_entry_t		pqe;	/* priority queue link */
692 	pthread_entry_t		sqe;	/* synchronization queue link */
693 	pthread_entry_t		qe;	/* all other queues link */
694 
695 	/* Wait data. */
696 	union pthread_wait_data data;
697 
698 	/*
699 	 * Allocated for converting select into poll.
700 	 */
701 	struct pthread_poll_data poll_data;
702 
703 	/*
704 	 * Set to TRUE if a blocking operation was
705 	 * interrupted by a signal:
706 	 */
707 	int		interrupted;
708 
709 	/* Signal number when in state PS_SIGWAIT: */
710 	int		signo;
711 
712 	/*
713 	 * Set to non-zero when this thread has deferred signals.
714 	 * We allow for recursive deferral.
715 	 */
716 	int		sig_defer_count;
717 
718 	/*
719 	 * Set to TRUE if this thread should yield after undeferring
720 	 * signals.
721 	 */
722 	int		yield_on_sig_undefer;
723 
724 	/* Miscellaneous flags; only set with signals deferred. */
725 	int		flags;
726 #define PTHREAD_FLAGS_PRIVATE	0x0001
727 #define PTHREAD_EXITING		0x0002
728 #define PTHREAD_FLAGS_IN_WAITQ	0x0004	/* in waiting queue using pqe link */
729 #define PTHREAD_FLAGS_IN_PRIOQ	0x0008	/* in priority queue using pqe link */
730 #define PTHREAD_FLAGS_IN_WORKQ	0x0010	/* in work queue using qe link */
731 #define PTHREAD_FLAGS_IN_FILEQ	0x0020	/* in file lock queue using qe link */
732 #define PTHREAD_FLAGS_IN_FDQ	0x0040	/* in fd lock queue using qe link */
733 #define PTHREAD_FLAGS_IN_CONDQ	0x0080	/* in condition queue using sqe link */
734 #define PTHREAD_FLAGS_IN_MUTEXQ	0x0100	/* in mutex queue using sqe link */
735 #define PTHREAD_FLAGS_TRACE	0x0200	/* for debugging purposes */
736 #define PTHREAD_FLAGS_IN_SYNCQ	\
737     (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
738 
739 	/*
740 	 * Base priority is the user setable and retrievable priority
741 	 * of the thread.  It is only affected by explicit calls to
742 	 * set thread priority and upon thread creation via a thread
743 	 * attribute or default priority.
744 	 */
745 	char		base_priority;
746 
747 	/*
748 	 * Inherited priority is the priority a thread inherits by
749 	 * taking a priority inheritence or protection mutex.  It
750 	 * is not affected by base priority changes.  Inherited
751 	 * priority defaults to and remains 0 until a mutex is taken
752 	 * that is being waited on by any other thread whose priority
753 	 * is non-zero.
754 	 */
755 	char		inherited_priority;
756 
757 	/*
758 	 * Active priority is always the maximum of the threads base
759 	 * priority and inherited priority.  When there is a change
760 	 * in either the base or inherited priority, the active
761 	 * priority must be recalculated.
762 	 */
763 	char		active_priority;
764 
765 	/* Number of priority ceiling or protection mutexes owned. */
766 	int		priority_mutex_count;
767 
768 	/* Number rwlocks rdlocks held. */
769 	int			rdlock_count;
770 
771 	/*
772 	 * Queue of currently owned mutexes.
773 	 */
774 	V_TAILQ_HEAD(, pthread_mutex volatile)	mutexq;
775 
776 	void		*ret;
777 	const void	**specific_data;
778 	int		specific_data_count;
779 
780 	/* Cleanup handlers Link List */
781 	struct pthread_cleanup *cleanup;
782 	const char		*fname;	/* Ptr to source file name  */
783 	int			lineno;	/* Source line number.      */
784 };
785 
786 /*
787  * Flags and prototypes for the machine dependent layer
788  */
789 void _thread_machdep_switch(struct _machdep_state *newstate,
790         struct _machdep_state *savestate);
791 void _thread_machdep_init(struct _machdep_state *state, void *stackbase,
792         int stacksize, void (*entry)(void));
793 void _thread_machdep_save_float_state(struct _machdep_state* statep);
794 void _thread_machdep_restore_float_state(struct _machdep_state* statep);
795 
796 /*
797  * Global variables for the uthread kernel.
798  */
799 
800 /* Kernel thread structure used when there are no running threads: */
801 SCLASS struct pthread	_thread_kern_thread;
802 
803 /* Ptr to the thread structure for the running thread: */
804 SCLASS struct pthread	* volatile _thread_run
805 #ifdef GLOBAL_PTHREAD_PRIVATE
806 = &_thread_kern_thread;
807 #else
808 ;
809 #endif
810 
811 /* Ptr to the thread structure for the last user thread to run: */
812 SCLASS struct pthread	* volatile _last_user_thread
813 #ifdef GLOBAL_PTHREAD_PRIVATE
814 = &_thread_kern_thread;
815 #else
816 ;
817 #endif
818 
819 /*
820  * Ptr to the thread running in single-threaded mode or NULL if
821  * running multi-threaded (default POSIX behaviour).
822  */
823 SCLASS struct pthread	* volatile _thread_single
824 #ifdef GLOBAL_PTHREAD_PRIVATE
825 = NULL;
826 #else
827 ;
828 #endif
829 
830 SCLASS _thread_list_t		_thread_list
831 #ifdef GLOBAL_PTHREAD_PRIVATE
832 = TAILQ_HEAD_INITIALIZER(_thread_list);
833 #else
834 ;
835 #endif
836 
837 /*
838  * Array of kernel pipe file descriptors that are used to ensure that
839  * no signals are missed in calls to _select.
840  */
841 SCLASS int		_thread_kern_pipe[2]
842 #ifdef GLOBAL_PTHREAD_PRIVATE
843 = {
844 	-1,
845 	-1
846 };
847 #else
848 ;
849 #endif
850 SCLASS int		volatile _queue_signals
851 #ifdef GLOBAL_PTHREAD_PRIVATE
852 = 0;
853 #else
854 ;
855 #endif
856 SCLASS int		volatile _thread_kern_in_sched
857 #ifdef GLOBAL_PTHREAD_PRIVATE
858 = 0;
859 #else
860 ;
861 #endif
862 
863 SCLASS int		_sig_in_handler
864 #ifdef GLOBAL_PTHREAD_PRIVATE
865 = 0;
866 #else
867 ;
868 #endif
869 
870 /* Time of day at last scheduling timer signal: */
871 SCLASS struct timeval volatile	_sched_tod
872 #ifdef GLOBAL_PTHREAD_PRIVATE
873 = { 0, 0 };
874 #else
875 ;
876 #endif
877 
878 /*
879  * Current scheduling timer ticks; used as resource usage.
880  */
881 SCLASS unsigned int volatile	_sched_ticks
882 #ifdef GLOBAL_PTHREAD_PRIVATE
883 = 0;
884 #else
885 ;
886 #endif
887 
888 /* Dead threads: */
889 SCLASS _thread_list_t		_dead_list
890 #ifdef GLOBAL_PTHREAD_PRIVATE
891 = TAILQ_HEAD_INITIALIZER(_dead_list);
892 #else
893 ;
894 #endif
895 
896 /* Initial thread: */
897 SCLASS struct pthread *_thread_initial
898 #ifdef GLOBAL_PTHREAD_PRIVATE
899 = NULL;
900 #else
901 ;
902 #endif
903 
904 /* Default thread attributes: */
905 SCLASS struct pthread_attr pthread_attr_default
906 #ifdef GLOBAL_PTHREAD_PRIVATE
907 = { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
908 	PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL,
909 	PTHREAD_STACK_DEFAULT };
910 #else
911 ;
912 #endif
913 
914 /* Default mutex attributes: */
915 SCLASS struct pthread_mutex_attr pthread_mutexattr_default
916 #ifdef GLOBAL_PTHREAD_PRIVATE
917 = { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
918 #else
919 ;
920 #endif
921 
922 /* Default condition variable attributes: */
923 SCLASS struct pthread_cond_attr pthread_condattr_default
924 #ifdef GLOBAL_PTHREAD_PRIVATE
925 = { COND_TYPE_FAST, 0 };
926 #else
927 ;
928 #endif
929 
930 /* File table information: */
931 SCLASS struct fd_table_entry **_thread_fd_table
932 #ifdef GLOBAL_PTHREAD_PRIVATE
933 = NULL;
934 #else
935 ;
936 #endif
937 
938 /* Table for polling file descriptors: */
939 SCLASS struct pollfd *_thread_pfd_table
940 #ifdef GLOBAL_PTHREAD_PRIVATE
941 = NULL;
942 #else
943 ;
944 #endif
945 
946 SCLASS const int dtablecount
947 #ifdef GLOBAL_PTHREAD_PRIVATE
948 = 4096/sizeof(struct fd_table_entry);
949 #else
950 ;
951 #endif
952 SCLASS int    _thread_dtablesize	/* Descriptor table size.	*/
953 #ifdef GLOBAL_PTHREAD_PRIVATE
954 = 0;
955 #else
956 ;
957 #endif
958 
959 SCLASS int    _clock_res_usec		/* Clock resolution in usec.	*/
960 #ifdef GLOBAL_PTHREAD_PRIVATE
961 = CLOCK_RES_USEC;
962 #else
963 ;
964 #endif
965 
966 /* Garbage collector mutex and condition variable. */
967 SCLASS	pthread_mutex_t _gc_mutex
968 #ifdef GLOBAL_PTHREAD_PRIVATE
969 = NULL
970 #endif
971 ;
972 SCLASS	pthread_cond_t  _gc_cond
973 #ifdef GLOBAL_PTHREAD_PRIVATE
974 = NULL
975 #endif
976 ;
977 
978 /*
979  * Array of signal actions for this process.
980  */
981 SCLASS struct  sigaction _thread_sigact[NSIG];
982 
983 /*
984  * Array of counts of dummy handlers for SIG_DFL signals.  This is used to
985  * assure that there is always a dummy signal handler installed while there is a
986  * thread sigwait()ing on the corresponding signal.
987  */
988 SCLASS int	_thread_dfl_count[NSIG];
989 
990 /*
991  * Pending signals and mask for this process:
992  */
993 SCLASS sigset_t		_process_sigpending;
994 SCLASS sigset_t		_process_sigmask
995 #ifdef GLOBAL_PTHREAD_PRIVATE
996 = 0
997 #endif
998 ;
999 
1000 /*
1001  * Scheduling queues:
1002  */
1003 SCLASS pq_queue_t		_readyq;
1004 SCLASS _thread_list_t		_waitingq;
1005 
1006 /*
1007  * Work queue:
1008  */
1009 SCLASS _thread_list_t		_workq;
1010 
1011 /* Tracks the number of threads blocked while waiting for a spinlock. */
1012 SCLASS volatile int	_spinblock_count
1013 #ifdef GLOBAL_PTHREAD_PRIVATE
1014 = 0
1015 #endif
1016 ;
1017 
1018 /* Used to maintain pending and active signals: */
1019 struct sigstatus {
1020 	spinlock_t	lock;		/* structure access lock */
1021 	int		pending;	/* Is this a pending signal? */
1022 	siginfo_t	siginfo;	/* arg 2 to signal handler */
1023 };
1024 
1025 SCLASS struct sigstatus	_thread_sigq[NSIG];
1026 
1027 /* Indicates that the signal queue needs to be checked. */
1028 SCLASS volatile int	_sigq_check_reqd
1029 #ifdef GLOBAL_PTHREAD_PRIVATE
1030 = 0
1031 #endif
1032 ;
1033 
1034 /* The signal stack. */
1035 SCLASS struct sigaltstack _thread_sigstack;
1036 
1037 /* Thread switch hook. */
1038 SCLASS pthread_switch_routine_t _sched_switch_hook
1039 #ifdef GLOBAL_PTHREAD_PRIVATE
1040 = NULL
1041 #endif
1042 ;
1043 
1044 /*
1045  * Spare stack queue.  Stacks of default size are cached in order to reduce
1046  * thread creation time.  Spare stacks are used in LIFO order to increase cache
1047  * locality.
1048  */
1049 typedef SLIST_HEAD(, stack)	_stack_list_t;
1050 extern _stack_list_t		_stackq;
1051 
1052 /* Used for _PTHREADS_INVARIANTS checking. */
1053 SCLASS int	_thread_kern_new_state
1054 #ifdef GLOBAL_PTHREAD_PRIVATE
1055 = 0;
1056 #else
1057 ;
1058 #endif
1059 
1060 /* Undefine the storage class specifier: */
1061 #undef SCLASS
1062 
1063 /*
1064  * Function prototype definitions.
1065  */
1066 __BEGIN_DECLS
1067 int	*__error(void);
1068 int     _find_thread(pthread_t);
1069 struct pthread *_get_curthread(void);
1070 void	_set_curthread(struct pthread *);
1071 int     _thread_create(pthread_t *, const pthread_attr_t *,
1072 		       void *(*start_routine)(void *), void *,pthread_t);
1073 void    _dispatch_signal(int, struct sigcontext *);
1074 void    _dispatch_signals(struct sigcontext *);
1075 void    _thread_signal(pthread_t, int);
1076 int	_mutex_cv_lock(pthread_mutex_t *);
1077 int	_mutex_cv_unlock(pthread_mutex_t *);
1078 int	_mutex_reinit(pthread_mutex_t *);
1079 void	_mutex_notify_priochange(struct pthread *);
1080 int	_cond_reinit(pthread_cond_t *);
1081 int	_pq_alloc(struct pq_queue *, int, int);
1082 int	_pq_init(struct pq_queue *);
1083 void	_pq_remove(struct pq_queue *pq, struct pthread *);
1084 void	_pq_insert_head(struct pq_queue *pq, struct pthread *);
1085 void	_pq_insert_tail(struct pq_queue *pq, struct pthread *);
1086 struct pthread *_pq_first(struct pq_queue *pq);
1087 void	_waitq_insert(pthread_t pthread);
1088 void	_waitq_remove(pthread_t pthread);
1089 #if defined(_PTHREADS_INVARIANTS)
1090 void	_waitq_setactive(void);
1091 void	_waitq_clearactive(void);
1092 #endif
1093 __dead void _thread_exit(const char *, int, const char *) __attribute__((__noreturn__));
1094 void    *_thread_cleanup(pthread_t);
1095 void    _thread_cleanupspecific(void);
1096 void	_thread_clear_pending(int, pthread_t);
1097 void	_thread_dump_data(const void *, int);
1098 void    _thread_dump_info(void);
1099 void    _thread_init(void);
1100 void	_thread_kern_lock(int);
1101 void    _thread_kern_sched(struct sigcontext *);
1102 void    _thread_kern_sched_state(enum pthread_state, const char *, int);
1103 void	_thread_kern_sched_state_unlock(enum pthread_state, spinlock_t *,
1104 					const char *, int);
1105 void    _thread_kern_set_timeout(const struct timespec *);
1106 void    _thread_kern_sig_defer(void);
1107 void    _thread_kern_sig_undefer(void);
1108 void	_thread_kill_siginfo(int);
1109 void    _thread_sig_handler(int, siginfo_t *, struct sigcontext *);
1110 int	_thread_sig_handle(int, struct sigcontext *);
1111 void	_thread_sig_init(void);
1112 void    _thread_start(void);
1113 void    _thread_start_sig_handler(void);
1114 void	_thread_seterrno(pthread_t,int);
1115 void	_thread_fd_init(void);
1116 int     _thread_fd_table_init(int);
1117 int     _thread_fd_table_dup(int, int);
1118 void	_thread_fd_table_remove(int);
1119 void	_thread_fd_unlock_owned(pthread_t);
1120 void	_thread_fd_unlock_thread(struct pthread	*, int, int);
1121 pthread_addr_t _thread_gc(pthread_addr_t);
1122 void	_thread_enter_cancellation_point(void);
1123 void	_thread_leave_cancellation_point(void);
1124 void	_thread_cancellation_point(void);
1125 int	_thread_slow_atomic_lock(volatile _spinlock_lock_t *);
1126 int	_thread_slow_atomic_is_locked(volatile _spinlock_lock_t *);
1127 struct stack * _thread_stack_alloc(void *, size_t);
1128 void	_thread_stack_free(struct stack *);
1129 
1130 
1131 /* #include <signal.h> */
1132 #ifdef _USER_SIGNAL_H
1133 int	_thread_sys_kill(pid_t, int);
1134 int     _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *);
1135 int	_thread_sys_sigblock(int);
1136 int	_thread_sys_sigsetmask(int);
1137 int     _thread_sys_sigpending(sigset_t *);
1138 int     _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
1139 int     _thread_sys_sigsuspend(const sigset_t *);
1140 int     _thread_sys_siginterrupt(int, int);
1141 int     _thread_sys_sigpause(int);
1142 int     _thread_sys_sigreturn(struct sigcontext *);
1143 int     _thread_sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
1144 int     _thread_sys_sigvec(int, struct sigvec *, struct sigvec *);
1145 void    _thread_sys_psignal(unsigned int, const char *);
1146 void    (*_thread_sys_signal(int, void (*)(int)))(int);
1147 #endif
1148 
1149 /* #include <sys/stat.h> */
1150 #ifdef  _SYS_STAT_H_
1151 int     _thread_sys_fchmod(int, mode_t);
1152 int     _thread_sys_fstat(int, struct stat *);
1153 int     _thread_sys_fchflags(int, unsigned int);
1154 #endif
1155 
1156 /* #include <sys/mount.h> */
1157 #ifdef  _SYS_MOUNT_H_
1158 int     _thread_sys_fstatfs(int, struct statfs *);
1159 #endif
1160 int     _thread_sys_pipe(int *);
1161 
1162 /* #include <sys/socket.h> */
1163 #ifdef  _SYS_SOCKET_H_
1164 int     _thread_sys_accept(int, struct sockaddr *, socklen_t *);
1165 int     _thread_sys_bind(int, const struct sockaddr *, socklen_t);
1166 int     _thread_sys_connect(int, const struct sockaddr *, socklen_t);
1167 int     _thread_sys_getpeername(int, struct sockaddr *, socklen_t *);
1168 int     _thread_sys_getsockname(int, struct sockaddr *, socklen_t *);
1169 int     _thread_sys_getsockopt(int, int, int, void *, socklen_t *);
1170 int     _thread_sys_listen(int, int);
1171 int     _thread_sys_setsockopt(int, int, int, const void *, socklen_t);
1172 int     _thread_sys_shutdown(int, int);
1173 int     _thread_sys_socket(int, int, int);
1174 int     _thread_sys_socketpair(int, int, int, int *);
1175 ssize_t _thread_sys_recv(int, void *, size_t, int);
1176 ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
1177 ssize_t _thread_sys_recvmsg(int, struct msghdr *, int);
1178 ssize_t _thread_sys_send(int, const void *, size_t, int);
1179 ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int);
1180 ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
1181 #endif
1182 
1183 /* #include <stdio.h> */
1184 #ifdef  _STDIO_H_
1185 FILE    *_thread_sys_fdopen(int, const char *);
1186 FILE    *_thread_sys_fopen(const char *, const char *);
1187 FILE    *_thread_sys_freopen(const char *, const char *, FILE *);
1188 FILE    *_thread_sys_popen(const char *, const char *);
1189 FILE    *_thread_sys_tmpfile(void);
1190 char    *_thread_sys_ctermid(char *);
1191 char    *_thread_sys_cuserid(char *);
1192 char    *_thread_sys_fgetln(FILE *, size_t *);
1193 char    *_thread_sys_fgets(char *, int, FILE *);
1194 char    *_thread_sys_gets(char *);
1195 char    *_thread_sys_tempnam(const char *, const char *);
1196 char    *_thread_sys_tmpnam(char *);
1197 int     _thread_sys_fclose(FILE *);
1198 int     _thread_sys_feof(FILE *);
1199 int     _thread_sys_ferror(FILE *);
1200 int     _thread_sys_fflush(FILE *);
1201 int     _thread_sys_fgetc(FILE *);
1202 int     _thread_sys_fgetpos(FILE *, fpos_t *);
1203 int     _thread_sys_fileno(FILE *);
1204 int     _thread_sys_fprintf(FILE *, const char *, ...);
1205 int     _thread_sys_fpurge(FILE *);
1206 int     _thread_sys_fputc(int, FILE *);
1207 int     _thread_sys_fputs(const char *, FILE *);
1208 int     _thread_sys_fscanf(FILE *, const char *, ...);
1209 int     _thread_sys_fseek(FILE *, long, int);
1210 int     _thread_sys_fsetpos(FILE *, const fpos_t *);
1211 int     _thread_sys_getc(FILE *);
1212 int     _thread_sys_getchar(void);
1213 int     _thread_sys_getw(FILE *);
1214 int     _thread_sys_pclose(FILE *);
1215 int     _thread_sys_printf(const char *, ...);
1216 int     _thread_sys_putc(int, FILE *);
1217 int     _thread_sys_putchar(int);
1218 int     _thread_sys_puts(const char *);
1219 int     _thread_sys_putw(int, FILE *);
1220 int     _thread_sys_remove(const char *);
1221 int     _thread_sys_rename (const char *, const char *);
1222 int     _thread_sys_scanf(const char *, ...);
1223 int     _thread_sys_setlinebuf(FILE *);
1224 int     _thread_sys_setvbuf(FILE *, char *, int, size_t);
1225 int     _thread_sys_snprintf(char *, size_t, const char *, ...);
1226 int     _thread_sys_sprintf(char *, const char *, ...);
1227 int     _thread_sys_sscanf(const char *, const char *, ...);
1228 int     _thread_sys_ungetc(int, FILE *);
1229 int     _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_);
1230 int     _thread_sys_vprintf(const char *, _BSD_VA_LIST_);
1231 int     _thread_sys_vscanf(const char *, _BSD_VA_LIST_);
1232 int     _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
1233 int     _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_);
1234 int     _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_);
1235 long    _thread_sys_ftell(FILE *);
1236 size_t  _thread_sys_fread(void *, size_t, size_t, FILE *);
1237 size_t  _thread_sys_fwrite(const void *, size_t, size_t, FILE *);
1238 void    _thread_sys_clearerr(FILE *);
1239 void    _thread_sys_perror(const char *);
1240 void    _thread_sys_rewind(FILE *);
1241 void    _thread_sys_setbuf(FILE *, char *);
1242 void    _thread_sys_setbuffer(FILE *, char *, int);
1243 #endif
1244 
1245 /* #include <unistd.h> */
1246 #ifdef  _UNISTD_H_
1247 char    *_thread_sys_ttyname(int);
1248 int     _thread_sys_close(int);
1249 int     _thread_sys_closefrom(int);
1250 int     _thread_sys_dup(int);
1251 int     _thread_sys_dup2(int, int);
1252 int     _thread_sys_exect(const char *, char * const *, char * const *);
1253 int     _thread_sys_execve(const char *, char * const *, char * const *);
1254 int     _thread_sys_fchdir(int);
1255 int     _thread_sys_fchown(int, uid_t, gid_t);
1256 int     _thread_sys_fsync(int);
1257 int     _thread_sys_ftruncate(int, off_t);
1258 long	_thread_sys_fpathconf(int, int);
1259 pid_t	_thread_sys_getpid(void);
1260 int     _thread_sys_pipe(int *);
1261 int     _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
1262 off_t   _thread_sys_lseek(int, off_t, int);
1263 pid_t   _thread_sys_fork(void);
1264 pid_t   _thread_sys_tcgetpgrp(int);
1265 ssize_t _thread_sys_read(int, void *, size_t);
1266 ssize_t _thread_sys_write(int, const void *, size_t);
1267 __dead void	_thread_sys__exit(int) __attribute__((__noreturn__));
1268 #endif
1269 
1270 /* #include <fcntl.h> */
1271 #ifdef  _SYS_FCNTL_H_
1272 int     _thread_sys_creat(const char *, mode_t);
1273 int     _thread_sys_fcntl(int, int, ...);
1274 int     _thread_sys_flock(int, int);
1275 int     _thread_sys_open(const char *, int, ...);
1276 #endif
1277 
1278 /* #include <sys/ioctl.h> */
1279 #ifdef  _SYS_IOCTL_H_
1280 int     _thread_sys_ioctl(int, unsigned long, ...);
1281 #endif
1282 
1283 /* #include <dirent.h> */
1284 #ifdef  _DIRENT_H_
1285 DIR     *___thread_sys_opendir2(const char *, int);
1286 DIR     *_thread_sys_opendir(const char *);
1287 int     _thread_sys_alphasort(const void *, const void *);
1288 int     _thread_sys_scandir(const char *, struct dirent ***,
1289 	int (*)(struct dirent *), int (*)(const void *, const void *));
1290 int     _thread_sys_closedir(DIR *);
1291 int     _thread_sys_getdirentries(int, char *, int, long *);
1292 long    _thread_sys_telldir(const DIR *);
1293 struct  dirent *_thread_sys_readdir(DIR *);
1294 void    _thread_sys_rewinddir(DIR *);
1295 void    _thread_sys_seekdir(DIR *, long);
1296 #endif
1297 
1298 /* #include <sys/uio.h> */
1299 #ifdef  _SYS_UIO_H_
1300 ssize_t _thread_sys_readv(int, const struct iovec *, int);
1301 ssize_t _thread_sys_writev(int, const struct iovec *, int);
1302 #endif
1303 
1304 /* #include <sys/wait.h> */
1305 #ifdef  _SYS_WAIT_H_
1306 pid_t   _thread_sys_wait(int *);
1307 pid_t   _thread_sys_waitpid(pid_t, int *, int);
1308 pid_t   _thread_sys_wait3(int *, int, struct rusage *);
1309 pid_t   _thread_sys_wait4(pid_t, int *, int, struct rusage *);
1310 #endif
1311 
1312 /* #include <poll.h> */
1313 #ifdef _SYS_POLL_H_
1314 int 	_thread_sys_poll(struct pollfd *, unsigned, int);
1315 #endif
1316 
1317 /* #include <sys/event.h> */
1318 #ifdef _SYS_EVENT_H_
1319 int	_thread_sys_kqueue(void);
1320 int     _thread_sys_kevent(int, const struct kevent *, int, struct kevent *,
1321 	int, const struct timespec *);
1322 #endif
1323 
1324 /* #include <sys/mman.h> */
1325 int	_thread_sys_msync(void *, size_t, int);
1326 
1327 __END_DECLS
1328 
1329 #endif  /* !_PTHREAD_PRIVATE_H */
1330