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