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