thr_private.h revision 129484
1227753Stheraven/*
2232498Stheraven * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
3227753Stheraven * All rights reserved.
4227753Stheraven *
5227753Stheraven * Redistribution and use in source and binary forms, with or without
6227753Stheraven * modification, are permitted provided that the following conditions
7227753Stheraven * are met:
8227753Stheraven * 1. Redistributions of source code must retain the above copyright
9227753Stheraven *    notice, this list of conditions and the following disclaimer.
10227753Stheraven * 2. Redistributions in binary form must reproduce the above copyright
11232498Stheraven *    notice, this list of conditions and the following disclaimer in the
12232498Stheraven *    documentation and/or other materials provided with the distribution.
13232498Stheraven * 3. All advertising materials mentioning features or use of this software
14232498Stheraven *    must display the following acknowledgement:
15232498Stheraven *	This product includes software developed by John Birrell.
16227753Stheraven * 4. Neither the name of the author nor the names of any co-contributors
17227753Stheraven *    may be used to endorse or promote products derived from this software
18227753Stheraven *    without specific prior written permission.
19227753Stheraven *
20232498Stheraven * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21227753Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22227753Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23227753Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24227753Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25227753Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26227753Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27227753Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28227753Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29227753Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30227753Stheraven * SUCH DAMAGE.
31227753Stheraven *
32227753Stheraven * Private thread definitions for the uthread kernel.
33227753Stheraven *
34227753Stheraven * $FreeBSD: head/lib/libthr/thread/thr_private.h 129484 2004-05-20 12:06:16Z mtm $
35227753Stheraven */
36227753Stheraven
37232498Stheraven#ifndef _THR_PRIVATE_H
38227753Stheraven#define _THR_PRIVATE_H
39227753Stheraven
40232498Stheraven/*
41227753Stheraven * Evaluate the storage class specifier.
42232498Stheraven */
43227753Stheraven#ifdef GLOBAL_PTHREAD_PRIVATE
44232498Stheraven#define SCLASS
45227753Stheraven#else
46232498Stheraven#define SCLASS extern
47227753Stheraven#endif
48232498Stheraven
49227753Stheraven/*
50227753Stheraven * Include files.
51227753Stheraven */
52232498Stheraven#include <sys/types.h>
53232498Stheraven#include <sys/cdefs.h>
54231714Sdim#include <sys/errno.h>
55227753Stheraven#include <sys/time.h>
56232498Stheraven#include <sys/queue.h>
57227753Stheraven#include <pthread_np.h>
58232498Stheraven#include <sched.h>
59227753Stheraven#include <signal.h>
60232498Stheraven#include <spinlock.h>
61227753Stheraven#include <stdio.h>
62232498Stheraven#include <ucontext.h>
63227753Stheraven#include <unistd.h>
64232498Stheraven#if defined(_PTHREADS_INVARIANTS)
65227753Stheraven#include <assert.h>
66232498Stheraven#endif
67227753Stheraven
68232498Stheraven#include <machine/atomic.h>
69232498Stheraven#include <sys/thr.h>
70227753Stheraven#include <sys/umtx.h>
71227753Stheraven
72227753Stheraven#if defined(_PTHREADS_INVARIANTS)
73232498Stheraven/*
74232498Stheraven * Kernel fatal error handler macro.
75231714Sdim */
76232498Stheraven#define PANIC(string)							     \
77232498Stheraven	do {								     \
78231673Stheraven		_thread_printf(STDOUT_FILENO, (string));		     \
79227753Stheraven		_thread_printf(STDOUT_FILENO,				     \
80227753Stheraven		    "\nAbnormal termination, file: %s, line: %d\n",	     \
81227753Stheraven		    __FILE__, __LINE__);				     \
82227753Stheraven		abort();						     \
83227753Stheraven	} while (0)
84227753Stheraven
85227753Stheraven#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#define PTHREAD_LOCK(p)		UMTX_LOCK(&(p)->lock)
132#define PTHREAD_UNLOCK(p)	UMTX_UNLOCK(&(p)->lock)
133
134#define PTHREAD_WAKE(ptd)	thr_wake((ptd)->thr_id)
135
136/*
137 * TailQ initialization values.
138 */
139#define TAILQ_INITIALIZER	{ NULL, NULL }
140
141#define	UMTX_INITIALIZER	{ NULL }
142
143struct pthread_mutex_attr {
144	enum pthread_mutextype	m_type;
145	int			m_protocol;
146	int			m_ceiling;
147	long			m_flags;
148};
149
150/*
151 * Static mutex initialization values.
152 */
153
154#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
155	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
156
157#define PTHREAD_MUTEX_STATIC_INITIALIZER   \
158	{ PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL,	\
159	0, 0, TAILQ_INITIALIZER }
160
161union pthread_mutex_data {
162        void    *m_ptr;
163        int     m_count;
164};
165
166struct pthread_mutex {
167        enum pthread_mutextype          m_type;
168        int                             m_protocol;
169        TAILQ_HEAD(mutex_head, pthread) m_queue;
170        struct pthread                  *m_owner;
171        union pthread_mutex_data        m_data;
172        long                            m_flags;
173        int                             m_refcount;
174
175        /*
176         * Used for priority inheritence and protection.
177         *
178         *   m_prio       - For priority inheritence, the highest active
179         *                  priority (threads locking the mutex inherit
180         *                  this priority).  For priority protection, the
181         *                  ceiling priority of this mutex.
182         *   m_saved_prio - mutex owners inherited priority before
183         *                  taking the mutex, restored when the owner
184         *                  unlocks the mutex.
185         */
186        int                             m_prio;
187        int                             m_saved_prio;
188
189        /*
190         * Link for list of all mutexes a thread currently owns.
191         */
192        TAILQ_ENTRY(pthread_mutex)      m_qe;
193
194        /*
195         * Lock for accesses to this structure.
196         */
197        spinlock_t                      lock;
198};
199
200struct pthread_spinlock {
201	void *s_owner;
202	unsigned int  s_magic;
203};
204
205/*
206 * Flags for mutexes.
207 */
208#define MUTEX_FLAGS_PRIVATE	0x01
209#define MUTEX_FLAGS_INITED	0x02
210#define MUTEX_FLAGS_BUSY	0x04
211
212/*
213 * Condition variable definitions.
214 */
215enum pthread_cond_type {
216	COND_TYPE_FAST,
217	COND_TYPE_MAX
218};
219
220struct pthread_cond {
221	enum pthread_cond_type		c_type;
222	TAILQ_HEAD(cond_head, pthread)	c_queue;
223	pthread_mutex_t			c_mutex;
224	void				*c_data;
225	long				c_flags;
226	int				c_seqno;
227
228	/*
229	 * Lock for accesses to this structure.
230	 */
231	struct umtx			c_lock;
232};
233
234struct pthread_cond_attr {
235	enum pthread_cond_type	c_type;
236	long			c_flags;
237};
238
239/*
240 * Flags for condition variables.
241 */
242#define COND_FLAGS_INITED	0x01
243
244/*
245 * Static cond initialization values.
246 */
247#define PTHREAD_COND_STATIC_INITIALIZER    \
248	{ COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
249	0, 0, UMTX_INITIALIZER }
250
251/*
252 * Semaphore definitions.
253 */
254struct sem {
255#define	SEM_MAGIC	((u_int32_t) 0x09fa4012)
256	u_int32_t	magic;
257	pthread_mutex_t	lock;
258	pthread_cond_t	gtzero;
259	u_int32_t	count;
260	u_int32_t	nwaiters;
261};
262
263/*
264 * Cleanup definitions.
265 */
266struct pthread_cleanup {
267	struct pthread_cleanup	*next;
268	void			(*routine) ();
269	void			*routine_arg;
270};
271
272struct pthread_attr {
273	int	sched_policy;
274	int	sched_inherit;
275	int	sched_interval;
276	int	prio;
277	int	suspend;
278	int	flags;
279	void	*arg_attr;
280	void	(*cleanup_attr) ();
281	void	*stackaddr_attr;
282	size_t	stacksize_attr;
283	size_t	guardsize_attr;
284};
285
286/*
287 * Thread creation state attributes.
288 */
289#define PTHREAD_CREATE_RUNNING			0
290#define PTHREAD_CREATE_SUSPENDED		1
291
292/*
293 * Miscellaneous definitions.
294 */
295#define PTHREAD_STACK_DEFAULT			65536
296/*
297 * Size of default red zone at the end of each stack.  In actuality, this "red
298 * zone" is merely an unmapped region, except in the case of the initial stack.
299 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK
300 * region, an unmapped gap between thread stacks achieves the same effect as
301 * explicitly mapped red zones.
302 * This is declared and initialized in uthread_init.c.
303 */
304extern int _pthread_guard_default;
305
306extern int _pthread_page_size;
307
308/*
309 * Maximum size of initial thread's stack.  This perhaps deserves to be larger
310 * than the stacks of other threads, since many applications are likely to run
311 * almost entirely on this stack.
312 */
313#define PTHREAD_STACK_INITIAL			0x100000
314
315/*
316 * Define the different priority ranges.  All applications have thread
317 * priorities constrained within 0-31.  The threads library raises the
318 * priority when delivering signals in order to ensure that signal
319 * delivery happens (from the POSIX spec) "as soon as possible".
320 * In the future, the threads library will also be able to map specific
321 * threads into real-time (cooperating) processes or kernel threads.
322 * The RT and SIGNAL priorities will be used internally and added to
323 * thread base priorities so that the scheduling queue can handle both
324 * normal and RT priority threads with and without signal handling.
325 *
326 * The approach taken is that, within each class, signal delivery
327 * always has priority over thread execution.
328 */
329#define PTHREAD_DEFAULT_PRIORITY		15
330#define PTHREAD_MIN_PRIORITY			0
331#define PTHREAD_MAX_PRIORITY			31	/* 0x1F */
332#define PTHREAD_SIGNAL_PRIORITY			32	/* 0x20 */
333#define PTHREAD_RT_PRIORITY			64	/* 0x40 */
334#define PTHREAD_FIRST_PRIORITY			PTHREAD_MIN_PRIORITY
335#define PTHREAD_LAST_PRIORITY	\
336	(PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY)
337#define PTHREAD_BASE_PRIORITY(prio)	((prio) & PTHREAD_MAX_PRIORITY)
338
339/*
340 * Clock resolution in microseconds.
341 */
342#define CLOCK_RES_USEC				10000
343#define CLOCK_RES_USEC_MIN			1000
344
345/*
346 * Time slice period in microseconds.
347 */
348#define TIMESLICE_USEC				20000
349
350/*
351 * XXX Define a thread-safe macro to get the current time of day
352 * which is updated at regular intervals by the scheduling signal
353 * handler.
354 */
355#define	GET_CURRENT_TOD(tv)	gettimeofday(&(tv), NULL)
356
357struct pthread_barrierattr {
358	int ba_pshared;
359};
360
361/*
362 * POSIX Threads barrier object.
363 * Lock order:
364 *	1. pthread_barrier
365 *	2. pthread
366 */
367struct pthread_barrier {
368	TAILQ_HEAD(barrq_head, pthread) b_barrq;
369	struct umtx b_lock;
370	int	    b_total;
371	int	    b_subtotal;
372};
373
374struct pthread_rwlockattr {
375	int		pshared;
376};
377
378struct pthread_rwlock {
379	pthread_mutex_t	lock;	/* monitor lock */
380	int		state;	/* 0 = idle  >0 = # of readers  -1 = writer */
381	pthread_cond_t	read_signal;
382	pthread_cond_t	write_signal;
383	int		blocked_writers;
384};
385
386/*
387 * Thread states.
388 */
389enum pthread_state {
390	PS_RUNNING,
391	PS_MUTEX_WAIT,
392	PS_COND_WAIT,
393	PS_BARRIER_WAIT,
394	PS_SLEEP_WAIT,	/* XXX We need to wrap syscalls to set this state */
395	PS_WAIT_WAIT,
396	PS_JOIN,
397	PS_DEAD,
398	PS_DEADLOCK,
399	PS_STATE_MAX
400};
401
402
403/*
404 * File descriptor locking definitions.
405 */
406#define FD_READ             0x1
407#define FD_WRITE            0x2
408#define FD_RDWR             (FD_READ | FD_WRITE)
409
410union pthread_wait_data {
411	pthread_mutex_t	mutex;
412	pthread_cond_t	cond;
413	spinlock_t	*spinlock;
414	struct pthread	*thread;
415};
416
417struct join_status {
418	struct pthread	*thread;
419	void		*ret;
420	int		error;
421};
422
423struct pthread_state_data {
424	union pthread_wait_data psd_wait_data;
425	enum pthread_state	psd_state;
426	int			psd_flags;
427};
428
429struct pthread_specific_elem {
430	const void	*data;
431	int		seqno;
432};
433
434struct rwlock_held {
435	LIST_ENTRY(rwlock_held)	rh_link;
436	struct pthread_rwlock	*rh_rwlock;
437	int rh_rdcount;
438	int rh_wrcount;
439};
440
441LIST_HEAD(rwlock_listhead, rwlock_held);
442
443/*
444 * The cancel mode a thread is in is determined by the
445 * the cancel type and state it is set in. The two values
446 * are combined into one mode:
447 *	Mode		State		Type
448 *	----		-----		----
449 *	off		disabled	deferred
450 *	off		disabled	async
451 *	deferred	enabled		deferred
452 *	async		enabled		async
453 */
454enum cancel_mode { M_OFF, M_DEFERRED, M_ASYNC };
455
456/*
457 * A thread's cancellation is pending until the cancel
458 * mode has been tested to determine if the thread can be
459 * cancelled immediately.
460 */
461enum cancellation_state { CS_NULL, CS_PENDING, CS_SET };
462
463/*
464 * Thread structure.
465 */
466struct pthread {
467	/*
468	 * Magic value to help recognize a valid thread structure
469	 * from an invalid one:
470	 */
471#define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)
472	u_int32_t		magic;
473	char			*name;
474	u_int64_t		uniqueid; /* for gdb */
475	thr_id_t		thr_id;
476	sigset_t		savedsig;
477	int			signest; /* blocked signal netsting level */
478	int			ptdflags; /* used by other other threads
479					     to signal this thread */
480	int			isdead;
481	int			isdeadlocked;
482	int			exiting;
483	int			cancellationpoint;
484
485	/*
486	 * Lock for accesses to this thread structure.
487	 */
488	struct umtx		lock;
489
490	/* Queue entry for list of all threads: */
491	TAILQ_ENTRY(pthread)	tle;
492
493	/* Queue entry for list of dead threads: */
494	TAILQ_ENTRY(pthread)	dle;
495
496	/*
497	 * Thread start routine, argument, stack pointer and thread
498	 * attributes.
499	 */
500	void			*(*start_routine)(void *);
501	void			*arg;
502	void			*stack;
503	struct pthread_attr	attr;
504
505	/*
506	 * Machine context, including signal state.
507	 */
508	ucontext_t		ctx;
509
510	/*
511	 * The primary method of obtaining a thread's cancel state
512	 * and type is through cancelmode. The cancelstate field is
513	 * only so we don't loose the cancel state when the mode is
514	 * turned off.
515	 */
516	enum cancel_mode	cancelmode;
517	enum cancel_mode	cancelstate;
518
519	/* Specifies if cancellation is pending, acted upon, or neither. */
520	enum cancellation_state	cancellation;
521
522	/*
523	 * Error variable used instead of errno. The function __error()
524	 * returns a pointer to this.
525	 */
526	int	error;
527
528	/*
529	 * The joiner is the thread that is joining to this thread.  The
530	 * join status keeps track of a join operation to another thread.
531	 */
532	struct pthread		*joiner;
533	struct join_status	join_status;
534
535	/*
536	 * A thread can belong to:
537	 *
538	 *   o A queue of threads waiting for a mutex
539	 *   o A queue of threads waiting for a condition variable
540	 *
541	 * A thread can also be joining a thread (the joiner field above).
542	 *
543	 * Use sqe for synchronization (mutex and condition variable) queue
544	 * links.
545	 */
546	TAILQ_ENTRY(pthread)	sqe;	/* synchronization queue link */
547
548	/* Wait data. */
549	union pthread_wait_data data;
550
551	/* Miscellaneous flags; only set with signals deferred. */
552	int		flags;
553#define PTHREAD_FLAGS_PRIVATE	0x0001
554#define PTHREAD_FLAGS_BARR_REL	0x0004	/* has been released from barrier */
555#define PTHREAD_FLAGS_IN_BARRQ	0x0008	/* in barrier queue using sqe link */
556#define PTHREAD_FLAGS_IN_CONDQ	0x0080	/* in condition queue using sqe link*/
557#define PTHREAD_FLAGS_IN_MUTEXQ	0x0100	/* in mutex queue using sqe link */
558#define	PTHREAD_FLAGS_SUSPENDED	0x0200	/* thread is suspended */
559#define PTHREAD_FLAGS_TRACE	0x0400	/* for debugging purposes */
560#define PTHREAD_FLAGS_IN_SYNCQ	\
561    (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ | PTHREAD_FLAGS_IN_BARRQ)
562#define PTHREAD_FLAGS_NOT_RUNNING \
563    (PTHREAD_FLAGS_IN_SYNCQ | PTHREAD_FLAGS_SUSPENDED)
564
565	/*
566	 * Base priority is the user setable and retrievable priority
567	 * of the thread.  It is only affected by explicit calls to
568	 * set thread priority and upon thread creation via a thread
569	 * attribute or default priority.
570	 */
571	char		base_priority;
572
573	/*
574	 * Inherited priority is the priority a thread inherits by
575	 * taking a priority inheritence or protection mutex.  It
576	 * is not affected by base priority changes.  Inherited
577	 * priority defaults to and remains 0 until a mutex is taken
578	 * that is being waited on by any other thread whose priority
579	 * is non-zero.
580	 */
581	char		inherited_priority;
582
583	/*
584	 * Active priority is always the maximum of the threads base
585	 * priority and inherited priority.  When there is a change
586	 * in either the base or inherited priority, the active
587	 * priority must be recalculated.
588	 */
589	char		active_priority;
590
591	/* Number of priority ceiling or protection mutexes owned. */
592	int		prio_inherit_count;
593	int		prio_protect_count;
594
595	/*
596	 * Queue of currently owned mutexes.
597	 */
598	TAILQ_HEAD(, pthread_mutex)	mutexq;
599
600	/*
601	 * List of read-write locks owned for reading _OR_ writing.
602	 * This is accessed only by the current thread, so there's
603	 * no need for mutual exclusion.
604	 */
605	struct rwlock_listhead		*rwlockList;
606
607	void				*ret;
608	struct pthread_specific_elem	*specific;
609	int				specific_data_count;
610
611	/*
612	 * Architecture specific id field used for _{get, set}_curthread()
613	 * interface.
614	 */
615	void			*arch_id;
616
617	/* Cleanup handlers Link List */
618	struct pthread_cleanup *cleanup;
619	char			*fname;	/* Ptr to source file name  */
620	int			lineno;	/* Source line number.      */
621};
622
623/*
624 * Global variables for the uthread kernel.
625 */
626
627SCLASS void *_usrstack
628#ifdef GLOBAL_PTHREAD_PRIVATE
629= (void *) USRSTACK;
630#else
631;
632#endif
633
634SCLASS spinlock_t stack_lock
635#ifdef GLOBAL_PTHREAD_PRIVATE
636= _SPINLOCK_INITIALIZER
637#endif
638;
639#define STACK_LOCK	_SPINLOCK(&stack_lock);
640#define STACK_UNLOCK	_SPINUNLOCK(&stack_lock);
641
642/* List of all threads: */
643SCLASS TAILQ_HEAD(, pthread)	_thread_list
644#ifdef GLOBAL_PTHREAD_PRIVATE
645= TAILQ_HEAD_INITIALIZER(_thread_list);
646#else
647;
648#endif
649
650/* Dead threads: */
651SCLASS TAILQ_HEAD(, pthread) _dead_list
652#ifdef GLOBAL_PTHREAD_PRIVATE
653= TAILQ_HEAD_INITIALIZER(_dead_list);
654#else
655;
656#endif
657
658/*
659 * These two locks protect the global active threads list and
660 * the global dead threads list, respectively. Combining these
661 * into one lock for both lists doesn't seem wise, since it
662 * would likely increase contention during busy thread creation
663 * and destruction for very little savings in space.
664 *
665 * The lock for the "dead threads list" must be a pthread mutex
666 * because it is used with condition variables to synchronize
667 * the gc thread with active threads in the process of exiting or
668 * dead threads who have just been joined.
669 */
670SCLASS spinlock_t thread_list_lock
671#ifdef GLOBAL_PTHREAD_PRIVATE
672= _SPINLOCK_INITIALIZER
673#endif
674;
675SCLASS pthread_mutex_t dead_list_lock
676#ifdef GLOBAL_PTHREAD_PRIVATE
677= NULL
678#endif
679;
680
681#define THREAD_LIST_LOCK	_SPINLOCK(&thread_list_lock)
682#define THREAD_LIST_UNLOCK	_SPINUNLOCK(&thread_list_lock)
683#define DEAD_LIST_LOCK		_pthread_mutex_lock(&dead_list_lock)
684#define DEAD_LIST_UNLOCK	_pthread_mutex_unlock(&dead_list_lock)
685
686/* Initial thread: */
687SCLASS struct pthread *_thread_initial
688#ifdef GLOBAL_PTHREAD_PRIVATE
689= NULL;
690#else
691;
692#endif
693
694/* Default thread attributes: */
695SCLASS struct pthread_attr pthread_attr_default
696#ifdef GLOBAL_PTHREAD_PRIVATE
697= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
698	PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL,
699	PTHREAD_STACK_DEFAULT, -1 };
700#else
701;
702#endif
703
704/* Default mutex attributes: */
705SCLASS struct pthread_mutex_attr pthread_mutexattr_default
706#ifdef GLOBAL_PTHREAD_PRIVATE
707= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
708#else
709;
710#endif
711
712/* Default condition variable attributes: */
713SCLASS struct pthread_cond_attr pthread_condattr_default
714#ifdef GLOBAL_PTHREAD_PRIVATE
715= { COND_TYPE_FAST, 0 };
716#else
717;
718#endif
719
720/*
721 * Array of signal actions for this process.
722 */
723SCLASS struct  sigaction _thread_sigact[NSIG];
724
725/* Precomputed signal set for _thread_suspend. */
726SCLASS sigset_t _thread_suspend_sigset;
727
728/* Tracks the number of threads blocked while waiting for a spinlock. */
729SCLASS	volatile int	_spinblock_count
730#ifdef GLOBAL_PTHREAD_PRIVATE
731= 0
732#endif
733;
734
735/* Undefine the storage class specifier: */
736#undef  SCLASS
737
738/*
739 * Function prototype definitions.
740 */
741__BEGIN_DECLS
742char    *__ttyname_basic(int);
743char    *__ttyname_r_basic(int, char *, size_t);
744char    *ttyname_r(int, char *, size_t);
745void	_cond_wait_backout(pthread_t);
746int     _find_thread(pthread_t);
747pthread_t _get_curthread(void);
748void	*_set_curthread(ucontext_t *, struct pthread *, int *);
749void	_retire_thread(void *arch_id);
750void	*_thread_stack_alloc(size_t, size_t);
751void	_thread_stack_free(void *, size_t, size_t);
752int     _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
753int	_mutex_cv_lock(pthread_mutex_t *);
754int	_mutex_cv_unlock(pthread_mutex_t *);
755void	_mutex_lock_backout(pthread_t);
756void	_mutex_notify_priochange(pthread_t);
757int	_mutex_reinit(pthread_mutex_t *);
758void	_mutex_unlock_private(pthread_t);
759int	_cond_reinit(pthread_cond_t *);
760void	*_pthread_getspecific(pthread_key_t);
761int	_pthread_key_create(pthread_key_t *, void (*) (void *));
762int	_pthread_key_delete(pthread_key_t);
763int	_pthread_mutex_destroy(pthread_mutex_t *);
764int	_pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
765int	_pthread_mutex_lock(pthread_mutex_t *);
766int	_pthread_mutex_trylock(pthread_mutex_t *);
767int	_pthread_mutex_unlock(pthread_mutex_t *);
768int	_pthread_mutexattr_init(pthread_mutexattr_t *);
769int	_pthread_mutexattr_destroy(pthread_mutexattr_t *);
770int	_pthread_mutexattr_settype(pthread_mutexattr_t *, int);
771int	_pthread_once(pthread_once_t *, void (*) (void));
772pthread_t _pthread_self(void);
773int	_pthread_setspecific(pthread_key_t, const void *);
774int	_spintrylock(spinlock_t *);
775void    _thread_exit(char *, int, char *);
776void    _thread_exit_cleanup(void);
777void    *_thread_cleanup(pthread_t);
778void    _thread_cleanupspecific(void);
779void    _thread_dump_info(void);
780void    _thread_init(void);
781void	_thread_printf(int fd, const char *, ...);
782void    _thread_start(void);
783void	_thread_seterrno(pthread_t, int);
784void	_thread_enter_cancellation_point(void);
785void	_thread_leave_cancellation_point(void);
786void	_thread_cancellation_point(void);
787int	_thread_suspend(pthread_t thread, const struct timespec *abstime);
788void	_thread_critical_enter(pthread_t);
789void	_thread_critical_exit(pthread_t);
790void	_thread_sigblock();
791void	_thread_sigunblock();
792void	adjust_prio_inheritance(struct pthread *);
793void	adjust_prio_protection(struct pthread *);
794void	deadlist_free_onethread(struct pthread *);
795void	init_td_common(struct pthread *, struct pthread_attr *, int);
796void	init_tdlist(struct pthread *, int);
797void	proc_sigact_copyin(int, const struct sigaction *);
798void	proc_sigact_copyout(int, struct sigaction *);
799void	readjust_priorities(struct pthread *, struct pthread_mutex *);
800struct sigaction *proc_sigact_sigaction(int);
801
802/* #include <sys/aio.h> */
803#ifdef _SYS_AIO_H_
804int	__sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
805#endif
806
807/* #include <sys/event.h> */
808#ifdef _SYS_EVENT_H_
809int	__sys_kevent(int, const struct kevent *, int, struct kevent *,
810	    int, const struct timespec *);
811#endif
812
813/* #include <sys/ioctl.h> */
814#ifdef _SYS_IOCTL_H_
815int	__sys_ioctl(int, unsigned long, ...);
816#endif
817
818/* #include <sys/mman.h> */
819#ifdef _SYS_MMAN_H_
820int	__sys_msync(void *, size_t, int);
821#endif
822
823/* #include <sys/mount.h> */
824#ifdef _SYS_MOUNT_H_
825int	__sys_fstatfs(int, struct statfs *);
826#endif
827
828/* #include <sys/socket.h> */
829#ifdef _SYS_SOCKET_H_
830int	__sys_accept(int, struct sockaddr *, socklen_t *);
831int	__sys_bind(int, const struct sockaddr *, socklen_t);
832int	__sys_connect(int, const struct sockaddr *, socklen_t);
833int	__sys_getpeername(int, struct sockaddr *, socklen_t *);
834int	__sys_getsockname(int, struct sockaddr *, socklen_t *);
835int	__sys_getsockopt(int, int, int, void *, socklen_t *);
836int	__sys_listen(int, int);
837ssize_t	__sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
838ssize_t	__sys_recvmsg(int, struct msghdr *, int);
839int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
840ssize_t	__sys_sendmsg(int, const struct msghdr *, int);
841ssize_t	__sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
842int	__sys_setsockopt(int, int, int, const void *, socklen_t);
843int	__sys_shutdown(int, int);
844int	__sys_socket(int, int, int);
845int	__sys_socketpair(int, int, int, int *);
846#endif
847
848/* #include <sys/stat.h> */
849#ifdef _SYS_STAT_H_
850int	__sys_fchflags(int, u_long);
851int	__sys_fchmod(int, mode_t);
852int	__sys_fstat(int, struct stat *);
853#endif
854
855/* #include <sys/uio.h> */
856#ifdef _SYS_UIO_H_
857ssize_t	__sys_readv(int, const struct iovec *, int);
858ssize_t	__sys_writev(int, const struct iovec *, int);
859#endif
860
861/* #include <sys/wait.h> */
862#ifdef WNOHANG
863pid_t	__sys_wait4(pid_t, int *, int, struct rusage *);
864#endif
865
866/* #include <dirent.h> */
867#ifdef _DIRENT_H_
868int	__sys_getdirentries(int, char *, int, long *);
869#endif
870
871/* #include <fcntl.h> */
872#ifdef _SYS_FCNTL_H_
873int	__sys_fcntl(int, int, ...);
874int	__sys_flock(int, int);
875int	__sys_open(const char *, int, ...);
876#endif
877
878/* #include <poll.h> */
879#ifdef _SYS_POLL_H_
880int	__sys_poll(struct pollfd *, unsigned, int);
881#endif
882
883/* #include <signal.h> */
884#ifdef _SIGNAL_H_
885int	__sys_sigaction(int, const struct sigaction *, struct sigaction *);
886int	__sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
887int	__sys_sigprocmask(int, const sigset_t *, sigset_t *);
888int	__sys_sigreturn(ucontext_t *);
889#endif
890
891/* #include <unistd.h> */
892#ifdef _UNISTD_H_
893int	__sys_close(int);
894int	__sys_dup(int);
895int	__sys_dup2(int, int);
896int	__sys_execve(const char *, char * const *, char * const *);
897void	__sys_exit(int);
898int	__sys_fchown(int, uid_t, gid_t);
899pid_t	__sys_fork(void);
900long	__sys_fpathconf(int, int);
901int	__sys_fsync(int);
902int	__sys_pipe(int *);
903ssize_t	__sys_read(int, void *, size_t);
904ssize_t	__sys_write(int, const void *, size_t);
905#endif
906
907__END_DECLS
908
909#endif  /* !_PTHREAD_PRIVATE_H */
910