thr_private.h revision 61681
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/libkse/thread/thr_private.h 61681 2000-06-14 17:17:41Z jasone $
35 */
36
37#ifndef _PTHREAD_PRIVATE_H
38#define _PTHREAD_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 <setjmp.h>
53#include <signal.h>
54#include <sys/queue.h>
55#include <sys/types.h>
56#include <sys/time.h>
57#include <sys/cdefs.h>
58#include <sched.h>
59#include <spinlock.h>
60#include <pthread_np.h>
61
62/*
63 * Kernel fatal error handler macro.
64 */
65#define PANIC(string)   _thread_exit(__FILE__,__LINE__,string)
66
67/* Output debug messages like this: */
68#define	stdout_debug(_x)	_thread_sys_write(1,_x,strlen(_x));
69#define	stderr_debug(_x)	_thread_sys_write(2,_x,strlen(_x));
70
71
72/*
73 * Priority queue manipulation macros (using pqe link):
74 */
75#define PTHREAD_PRIOQ_INSERT_HEAD(thrd)	_pq_insert_head(&_readyq,thrd)
76#define PTHREAD_PRIOQ_INSERT_TAIL(thrd)	_pq_insert_tail(&_readyq,thrd)
77#define PTHREAD_PRIOQ_REMOVE(thrd)	_pq_remove(&_readyq,thrd)
78#define PTHREAD_PRIOQ_FIRST()		_pq_first(&_readyq)
79
80/*
81 * Waiting queue manipulation macros (using pqe link):
82 */
83#if defined(_PTHREADS_INVARIANTS)
84#define PTHREAD_WAITQ_REMOVE(thrd)	_waitq_remove(thrd)
85#define PTHREAD_WAITQ_INSERT(thrd)	_waitq_insert(thrd)
86#define PTHREAD_WAITQ_CLEARACTIVE()	_waitq_clearactive()
87#define PTHREAD_WAITQ_SETACTIVE()	_waitq_setactive()
88#else
89#define PTHREAD_WAITQ_REMOVE(thrd) do {					\
90	TAILQ_REMOVE(&_waitingq,thrd,pqe);				\
91	(thrd)->flags &= ~PTHREAD_FLAGS_IN_WAITQ;			\
92} while (0)
93
94#define PTHREAD_WAITQ_INSERT(thrd) do {					\
95	if ((thrd)->wakeup_time.tv_sec == -1)				\
96		TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe);			\
97	else {								\
98		pthread_t tid = TAILQ_FIRST(&_waitingq);		\
99		while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \
100		    ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) ||	\
101		    ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) &&	\
102		    (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \
103			tid = TAILQ_NEXT(tid, pqe);			\
104		if (tid == NULL)					\
105			TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe);		\
106		else							\
107			TAILQ_INSERT_BEFORE(tid,thrd,pqe);		\
108	}								\
109	(thrd)->flags |= PTHREAD_FLAGS_IN_WAITQ;			\
110} while (0)
111#define PTHREAD_WAITQ_CLEARACTIVE()
112#define PTHREAD_WAITQ_SETACTIVE()
113#endif
114
115/*
116 * Work queue manipulation macros (using qe link):
117 */
118#define PTHREAD_WORKQ_INSERT(thrd) do {					\
119	TAILQ_INSERT_TAIL(&_workq,thrd,qe);				\
120	(thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ;			\
121} while (0)
122#define PTHREAD_WORKQ_REMOVE(thrd) do {					\
123	TAILQ_REMOVE(&_workq,thrd,qe);					\
124	(thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ;			\
125} while (0)
126
127
128/*
129 * State change macro without scheduling queue change:
130 */
131#define PTHREAD_SET_STATE(thrd, newstate) do {				\
132	(thrd)->state = newstate;					\
133	(thrd)->fname = __FILE__;					\
134	(thrd)->lineno = __LINE__;					\
135} while (0)
136
137/*
138 * State change macro with scheduling queue change - This must be
139 * called with preemption deferred (see thread_kern_sched_[un]defer).
140 */
141#if defined(_PTHREADS_INVARIANTS)
142#define PTHREAD_NEW_STATE(thrd, newstate) do {				\
143	if (_thread_kern_new_state != 0)				\
144		PANIC("Recursive PTHREAD_NEW_STATE");			\
145	_thread_kern_new_state = 1;					\
146	if ((thrd)->state != newstate) {				\
147		if ((thrd)->state == PS_RUNNING) {			\
148			PTHREAD_PRIOQ_REMOVE(thrd);			\
149			PTHREAD_WAITQ_INSERT(thrd);			\
150		} else if (newstate == PS_RUNNING) { 			\
151			PTHREAD_WAITQ_REMOVE(thrd);			\
152			PTHREAD_PRIOQ_INSERT_TAIL(thrd);		\
153		}							\
154	}								\
155	_thread_kern_new_state = 0;					\
156	PTHREAD_SET_STATE(thrd, newstate);				\
157} while (0)
158#else
159#define PTHREAD_NEW_STATE(thrd, newstate) do {				\
160	if ((thrd)->state != newstate) {				\
161		if ((thrd)->state == PS_RUNNING) {			\
162			PTHREAD_PRIOQ_REMOVE(thrd);			\
163			PTHREAD_WAITQ_INSERT(thrd);			\
164		} else if (newstate == PS_RUNNING) { 			\
165			PTHREAD_WAITQ_REMOVE(thrd);			\
166			PTHREAD_PRIOQ_INSERT_TAIL(thrd);		\
167		}							\
168	}								\
169	PTHREAD_SET_STATE(thrd, newstate);				\
170} while (0)
171#endif
172
173/*
174 * Define the signals to be used for scheduling.
175 */
176#if defined(_PTHREADS_COMPAT_SCHED)
177#define _ITIMER_SCHED_TIMER	ITIMER_VIRTUAL
178#define _SCHED_SIGNAL		SIGVTALRM
179#else
180#define _ITIMER_SCHED_TIMER	ITIMER_PROF
181#define _SCHED_SIGNAL		SIGPROF
182#endif
183
184/*
185 * Priority queues.
186 *
187 * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
188 */
189typedef struct pq_list {
190	TAILQ_HEAD(, pthread)	pl_head; /* list of threads at this priority */
191	TAILQ_ENTRY(pq_list)	pl_link; /* link for queue of priority lists */
192	int			pl_prio; /* the priority of this list */
193	int			pl_queued; /* is this in the priority queue */
194} pq_list_t;
195
196typedef struct pq_queue {
197	TAILQ_HEAD(, pq_list)	 pq_queue; /* queue of priority lists */
198	pq_list_t		*pq_lists; /* array of all priority lists */
199	int			 pq_size;  /* number of priority lists */
200} pq_queue_t;
201
202
203/*
204 * TailQ initialization values.
205 */
206#define TAILQ_INITIALIZER	{ NULL, NULL }
207
208/*
209 * Mutex definitions.
210 */
211union pthread_mutex_data {
212	void	*m_ptr;
213	int	m_count;
214};
215
216struct pthread_mutex {
217	enum pthread_mutextype		m_type;
218	int				m_protocol;
219	TAILQ_HEAD(mutex_head, pthread)	m_queue;
220	struct pthread			*m_owner;
221	union pthread_mutex_data	m_data;
222	long				m_flags;
223	int				m_refcount;
224
225	/*
226	 * Used for priority inheritence and protection.
227	 *
228	 *   m_prio       - For priority inheritence, the highest active
229	 *                  priority (threads locking the mutex inherit
230	 *                  this priority).  For priority protection, the
231	 *                  ceiling priority of this mutex.
232	 *   m_saved_prio - mutex owners inherited priority before
233	 *                  taking the mutex, restored when the owner
234	 *                  unlocks the mutex.
235	 */
236	int				m_prio;
237	int				m_saved_prio;
238
239	/*
240	 * Link for list of all mutexes a thread currently owns.
241	 */
242	TAILQ_ENTRY(pthread_mutex)	m_qe;
243
244	/*
245	 * Lock for accesses to this structure.
246	 */
247	spinlock_t			lock;
248};
249
250/*
251 * Flags for mutexes.
252 */
253#define MUTEX_FLAGS_PRIVATE	0x01
254#define MUTEX_FLAGS_INITED	0x02
255#define MUTEX_FLAGS_BUSY	0x04
256
257/*
258 * Static mutex initialization values.
259 */
260#define PTHREAD_MUTEX_STATIC_INITIALIZER   \
261	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \
262	NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \
263	_SPINLOCK_INITIALIZER }
264
265struct pthread_mutex_attr {
266	enum pthread_mutextype	m_type;
267	int			m_protocol;
268	int			m_ceiling;
269	long			m_flags;
270};
271
272/*
273 * Condition variable definitions.
274 */
275enum pthread_cond_type {
276	COND_TYPE_FAST,
277	COND_TYPE_MAX
278};
279
280struct pthread_cond {
281	enum pthread_cond_type		c_type;
282	TAILQ_HEAD(cond_head, pthread)	c_queue;
283	pthread_mutex_t			c_mutex;
284	void				*c_data;
285	long				c_flags;
286
287	/*
288	 * Lock for accesses to this structure.
289	 */
290	spinlock_t			lock;
291};
292
293struct pthread_cond_attr {
294	enum pthread_cond_type	c_type;
295	long			c_flags;
296};
297
298/*
299 * Flags for condition variables.
300 */
301#define COND_FLAGS_PRIVATE	0x01
302#define COND_FLAGS_INITED	0x02
303#define COND_FLAGS_BUSY		0x04
304
305/*
306 * Static cond initialization values.
307 */
308#define PTHREAD_COND_STATIC_INITIALIZER    \
309	{ COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
310	0, _SPINLOCK_INITIALIZER }
311
312/*
313 * Semaphore definitions.
314 */
315struct sem {
316#define	SEM_MAGIC	((u_int32_t) 0x09fa4012)
317	u_int32_t	magic;
318	pthread_mutex_t	lock;
319	pthread_cond_t	gtzero;
320	u_int32_t	count;
321	u_int32_t	nwaiters;
322};
323
324/*
325 * Cleanup definitions.
326 */
327struct pthread_cleanup {
328	struct pthread_cleanup	*next;
329	void			(*routine) ();
330	void			*routine_arg;
331};
332
333struct pthread_attr {
334	int	sched_policy;
335	int	sched_inherit;
336	int	sched_interval;
337	int	prio;
338	int	suspend;
339	int	flags;
340	void	*arg_attr;
341	void	(*cleanup_attr) ();
342	void	*stackaddr_attr;
343	size_t	stacksize_attr;
344};
345
346/*
347 * Thread creation state attributes.
348 */
349#define PTHREAD_CREATE_RUNNING			0
350#define PTHREAD_CREATE_SUSPENDED		1
351
352/*
353 * Additional state for a thread suspended with pthread_suspend_np().
354 */
355enum pthread_susp {
356	SUSP_NO,	/* Not suspended. */
357	SUSP_YES,	/* Suspended. */
358	SUSP_NOWAIT,	/* Suspended, was in a mutex or condition queue. */
359	SUSP_MUTEX_WAIT,/* Suspended, still in a mutex queue. */
360	SUSP_COND_WAIT	/* Suspended, still in a condition queue. */
361};
362
363/*
364 * Miscellaneous definitions.
365 */
366#define PTHREAD_STACK_DEFAULT			65536
367/*
368 * Size of red zone at the end of each stack.  In actuality, this "red zone" is
369 * merely an unmapped region, except in the case of the initial stack.  Since
370 * mmap() makes it possible to specify the maximum growth of a MAP_STACK region,
371 * an unmapped gap between thread stacks achieves the same effect as explicitly
372 * mapped red zones.
373 */
374#define PTHREAD_STACK_GUARD			PAGE_SIZE
375
376/*
377 * Maximum size of initial thread's stack.  This perhaps deserves to be larger
378 * than the stacks of other threads, since many applications are likely to run
379 * almost entirely on this stack.
380 */
381#define PTHREAD_STACK_INITIAL			0x100000
382/* Address immediately beyond the beginning of the initial thread stack. */
383#define PTHREAD_DEFAULT_PRIORITY		64
384#define PTHREAD_MAX_PRIORITY			126
385#define PTHREAD_MIN_PRIORITY			0
386#define _POSIX_THREAD_ATTR_STACKSIZE
387
388/*
389 * Clock resolution in nanoseconds.
390 */
391#define CLOCK_RES_NSEC				10000000
392
393/*
394 * Time slice period in microseconds.
395 */
396#define TIMESLICE_USEC				100000
397
398struct pthread_key {
399	spinlock_t	lock;
400	volatile int	allocated;
401	volatile int	count;
402	void            (*destructor) ();
403};
404
405struct pthread_rwlockattr {
406	int		pshared;
407};
408
409struct pthread_rwlock {
410	pthread_mutex_t	lock;	/* monitor lock */
411	int		state;	/* 0 = idle  >0 = # of readers  -1 = writer */
412	pthread_cond_t	read_signal;
413	pthread_cond_t	write_signal;
414	int		blocked_writers;
415};
416
417/*
418 * Thread states.
419 */
420enum pthread_state {
421	PS_RUNNING,
422	PS_SIGTHREAD,
423	PS_MUTEX_WAIT,
424	PS_COND_WAIT,
425	PS_FDLR_WAIT,
426	PS_FDLW_WAIT,
427	PS_FDR_WAIT,
428	PS_FDW_WAIT,
429	PS_FILE_WAIT,
430	PS_POLL_WAIT,
431	PS_SELECT_WAIT,
432	PS_SLEEP_WAIT,
433	PS_WAIT_WAIT,
434	PS_SIGSUSPEND,
435	PS_SIGWAIT,
436	PS_SPINBLOCK,
437	PS_JOIN,
438	PS_SUSPENDED,
439	PS_DEAD,
440	PS_DEADLOCK,
441	PS_STATE_MAX
442};
443
444
445/*
446 * File descriptor locking definitions.
447 */
448#define FD_READ             0x1
449#define FD_WRITE            0x2
450#define FD_RDWR             (FD_READ | FD_WRITE)
451
452/*
453 * File descriptor table structure.
454 */
455struct fd_table_entry {
456	/*
457	 * Lock for accesses to this file descriptor table
458	 * entry. This is passed to _spinlock() to provide atomic
459	 * access to this structure. It does *not* represent the
460	 * state of the lock on the file descriptor.
461	 */
462	spinlock_t		lock;
463	TAILQ_HEAD(, pthread)	r_queue;	/* Read queue.                        */
464	TAILQ_HEAD(, pthread)	w_queue;	/* Write queue.                       */
465	struct pthread		*r_owner;	/* Ptr to thread owning read lock.    */
466	struct pthread		*w_owner;	/* Ptr to thread owning write lock.   */
467	char			*r_fname;	/* Ptr to read lock source file name  */
468	int			r_lineno;	/* Read lock source line number.      */
469	char			*w_fname;	/* Ptr to write lock source file name */
470	int			w_lineno;	/* Write lock source line number.     */
471	int			r_lockcount;	/* Count for FILE read locks.         */
472	int			w_lockcount;	/* Count for FILE write locks.        */
473	int			flags;		/* Flags used in open.                */
474};
475
476struct pthread_poll_data {
477	int	nfds;
478	struct pollfd *fds;
479};
480
481union pthread_wait_data {
482	pthread_mutex_t	mutex;
483	pthread_cond_t	cond;
484	const sigset_t	*sigwait;	/* Waiting on a signal in sigwait */
485	struct {
486		short	fd;		/* Used when thread waiting on fd */
487		short	branch;		/* Line number, for debugging.    */
488		char	*fname;		/* Source file name for debugging.*/
489	} fd;
490	struct pthread_poll_data * poll_data;
491	spinlock_t	*spinlock;
492};
493
494/*
495 * Define a continuation routine that can be used to perform a
496 * transfer of control:
497 */
498typedef void	(*thread_continuation_t) (void *);
499
500/*
501 * Thread structure.
502 */
503struct pthread {
504	/*
505	 * Magic value to help recognize a valid thread structure
506	 * from an invalid one:
507	 */
508#define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)
509	u_int32_t		magic;
510	char			*name;
511	u_int64_t		uniqueid; /* for gdb */
512
513	/*
514	 * Lock for accesses to this thread structure.
515	 */
516	spinlock_t		lock;
517
518	/* Queue entry for list of all threads: */
519	TAILQ_ENTRY(pthread)	tle;
520
521	/* Queue entry for list of dead threads: */
522	TAILQ_ENTRY(pthread)	dle;
523
524	/*
525	 * Thread start routine, argument, stack pointer and thread
526	 * attributes.
527	 */
528	void			*(*start_routine)(void *);
529	void			*arg;
530	void			*stack;
531	struct pthread_attr	attr;
532
533#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
534	/*
535	 * Saved floating point registers on systems where they are not
536	 * saved in the signal context.
537	 */
538	char	saved_fp[108];
539#endif
540
541	/*
542	 * Saved signal context used in call to sigreturn by
543	 * _thread_kern_sched if sig_saved is TRUE.
544	 */
545	ucontext_t saved_sigcontext;
546
547	/*
548	 * Saved jump buffer used in call to longjmp by _thread_kern_sched
549	 * if sig_saved is FALSE.
550	 */
551	jmp_buf	saved_jmp_buf;
552	jmp_buf	*sighandler_jmp_buf;
553
554	/*
555	 * Saved jump buffers for use when doing nested [sig|_]longjmp()s, as
556	 * when doing signal delivery.
557	 */
558	union {
559		jmp_buf		jmp;
560		sigjmp_buf	sigjmp;
561	}	nested_jmp;
562	int	longjmp_val;
563
564#define	JMPFLAGS_NONE		0x00
565#define	JMPFLAGS_LONGJMP	0x01
566#define	JMPFLAGS__LONGJMP	0x02
567#define	JMPFLAGS_SIGLONGJMP	0x04
568#define	JMPFLAGS_DEFERRED	0x08
569	int	jmpflags;
570
571	/*
572	 * TRUE if the last state saved was a signal context. FALSE if the
573	 * last state saved was a jump buffer.
574	 */
575	int	sig_saved;
576
577	/*
578	 * Used for tracking delivery of nested signal handlers.
579	 */
580	int	signal_nest_level;
581
582 	/*
583	 * Cancelability flags - the lower 2 bits are used by cancel
584	 * definitions in pthread.h
585	 */
586#define PTHREAD_AT_CANCEL_POINT		0x0004
587#define PTHREAD_CANCELLING		0x0008
588#define PTHREAD_CANCEL_NEEDED		0x0010
589	int	cancelflags;
590
591	enum	pthread_susp suspended;
592
593	thread_continuation_t	continuation;
594
595	/*
596	 * Current signal mask and pending signals.
597	 */
598	sigset_t	sigmask;
599	sigset_t	sigpend;
600
601	/* Thread state: */
602	enum pthread_state	state;
603	enum pthread_state	oldstate;
604
605	/* Time that this thread was last made active. */
606	struct  timeval		last_active;
607
608	/* Time that this thread was last made inactive. */
609	struct  timeval		last_inactive;
610
611	/*
612	 * Number of microseconds accumulated by this thread when
613	 * time slicing is active.
614	 */
615	long	slice_usec;
616
617	/*
618	 * Incremental priority accumulated by thread while it is ready to
619	 * run but is denied being run.
620	 */
621	int	inc_prio;
622
623	/*
624	 * Time to wake up thread. This is used for sleeping threads and
625	 * for any operation which may time out (such as select).
626	 */
627	struct timespec	wakeup_time;
628
629	/* TRUE if operation has timed out. */
630	int	timeout;
631
632	/*
633	 * Error variable used instead of errno. The function __error()
634	 * returns a pointer to this.
635	 */
636	int	error;
637
638	/* Join queue head and link for waiting threads: */
639	TAILQ_HEAD(join_head, pthread)	join_queue;
640
641	/*
642	 * The current thread can belong to only one scheduling queue at
643	 * a time (ready or waiting queue).  It can also belong to (only)
644	 * one of:
645	 *
646	 *   o A queue of threads waiting for a mutex
647	 *   o A queue of threads waiting for a condition variable
648	 *   o A queue of threads waiting for another thread to terminate
649	 *     (the join queue above)
650	 *   o A queue of threads waiting for a file descriptor lock
651	 *   o A queue of threads needing work done by the kernel thread
652	 *     (waiting for a spinlock or file I/O)
653	 *
654	 * Use pqe for the scheduling queue link (both ready and waiting),
655	 * and qe for other links.
656	 */
657
658	/* Priority queue entry for this thread: */
659	TAILQ_ENTRY(pthread)	pqe;
660
661	/* Queue entry for this thread: */
662	TAILQ_ENTRY(pthread)	qe;
663
664	/* Wait data. */
665	union pthread_wait_data data;
666
667	/*
668	 * Allocated for converting select into poll.
669	 */
670	struct pthread_poll_data poll_data;
671
672	/*
673	 * Set to TRUE if a blocking operation was
674	 * interrupted by a signal:
675	 */
676	int		interrupted;
677
678	/* Signal number when in state PS_SIGWAIT: */
679	int		signo;
680
681	/*
682	 * Set to non-zero when this thread has deferred signals.
683	 * We allow for recursive deferral.
684	 */
685	int		sig_defer_count;
686
687	/*
688	 * Set to TRUE if this thread should yield after undeferring
689	 * signals.
690	 */
691	int		yield_on_sig_undefer;
692
693	/* Miscellaneous flags; only set with signals deferred. */
694	int		flags;
695#define PTHREAD_FLAGS_PRIVATE	0x0001
696#define PTHREAD_EXITING		0x0002
697#define PTHREAD_FLAGS_IN_CONDQ	0x0004	/* in condition queue using qe link*/
698#define PTHREAD_FLAGS_IN_WORKQ	0x0008	/* in work queue using qe link */
699#define PTHREAD_FLAGS_IN_WAITQ	0x0010	/* in waiting queue using pqe link */
700#define PTHREAD_FLAGS_IN_PRIOQ	0x0020	/* in priority queue using pqe link */
701#define PTHREAD_FLAGS_IN_MUTEXQ	0x0040	/* in mutex queue using qe link */
702#define PTHREAD_FLAGS_IN_FILEQ	0x0080	/* in file lock queue using qe link */
703#define PTHREAD_FLAGS_IN_FDQ	0x0100	/* in fd lock queue using qe link */
704#define PTHREAD_FLAGS_TRACE	0x0200	/* for debugging purposes */
705
706	/*
707	 * Base priority is the user setable and retrievable priority
708	 * of the thread.  It is only affected by explicit calls to
709	 * set thread priority and upon thread creation via a thread
710	 * attribute or default priority.
711	 */
712	char		base_priority;
713
714	/*
715	 * Inherited priority is the priority a thread inherits by
716	 * taking a priority inheritence or protection mutex.  It
717	 * is not affected by base priority changes.  Inherited
718	 * priority defaults to and remains 0 until a mutex is taken
719	 * that is being waited on by any other thread whose priority
720	 * is non-zero.
721	 */
722	char		inherited_priority;
723
724	/*
725	 * Active priority is always the maximum of the threads base
726	 * priority and inherited priority.  When there is a change
727	 * in either the base or inherited priority, the active
728	 * priority must be recalculated.
729	 */
730	char		active_priority;
731
732	/* Number of priority ceiling or protection mutexes owned. */
733	int		priority_mutex_count;
734
735	/*
736	 * Queue of currently owned mutexes.
737	 */
738	TAILQ_HEAD(, pthread_mutex)	mutexq;
739
740	void		*ret;
741	const void	**specific_data;
742	int		specific_data_count;
743
744	/* Cleanup handlers Link List */
745	struct pthread_cleanup *cleanup;
746	char			*fname;	/* Ptr to source file name  */
747	int			lineno;	/* Source line number.      */
748};
749
750/* Spare thread stack. */
751struct stack {
752	SLIST_ENTRY(stack)	qe; /* Queue entry for this stack. */
753};
754
755/*
756 * Global variables for the uthread kernel.
757 */
758
759/* Kernel thread structure used when there are no running threads: */
760SCLASS struct pthread   _thread_kern_thread;
761
762/* Ptr to the thread structure for the running thread: */
763SCLASS struct pthread   * volatile _thread_run
764#ifdef GLOBAL_PTHREAD_PRIVATE
765= &_thread_kern_thread;
766#else
767;
768#endif
769
770/* Ptr to the thread structure for the last user thread to run: */
771SCLASS struct pthread   * volatile _last_user_thread
772#ifdef GLOBAL_PTHREAD_PRIVATE
773= &_thread_kern_thread;
774#else
775;
776#endif
777
778/*
779 * Ptr to the thread running in single-threaded mode or NULL if
780 * running multi-threaded (default POSIX behaviour).
781 */
782SCLASS struct pthread   * volatile _thread_single
783#ifdef GLOBAL_PTHREAD_PRIVATE
784= NULL;
785#else
786;
787#endif
788
789/* List of all threads: */
790SCLASS TAILQ_HEAD(, pthread)	_thread_list
791#ifdef GLOBAL_PTHREAD_PRIVATE
792= TAILQ_HEAD_INITIALIZER(_thread_list);
793#else
794;
795#endif
796
797/*
798 * Array of kernel pipe file descriptors that are used to ensure that
799 * no signals are missed in calls to _select.
800 */
801SCLASS int		_thread_kern_pipe[2]
802#ifdef GLOBAL_PTHREAD_PRIVATE
803= {
804	-1,
805	-1
806};
807#else
808;
809#endif
810SCLASS int		volatile _queue_signals
811#ifdef GLOBAL_PTHREAD_PRIVATE
812= 0;
813#else
814;
815#endif
816SCLASS int              _thread_kern_in_sched
817#ifdef GLOBAL_PTHREAD_PRIVATE
818= 0;
819#else
820;
821#endif
822
823/* Last time that an incremental priority update was performed: */
824SCLASS struct timeval   kern_inc_prio_time
825#ifdef GLOBAL_PTHREAD_PRIVATE
826= { 0, 0 };
827#else
828;
829#endif
830
831/* Dead threads: */
832SCLASS TAILQ_HEAD(, pthread) _dead_list
833#ifdef GLOBAL_PTHREAD_PRIVATE
834= TAILQ_HEAD_INITIALIZER(_dead_list);
835#else
836;
837#endif
838
839/* Initial thread: */
840SCLASS struct pthread *_thread_initial
841#ifdef GLOBAL_PTHREAD_PRIVATE
842= NULL;
843#else
844;
845#endif
846
847/* Default thread attributes: */
848SCLASS struct pthread_attr pthread_attr_default
849#ifdef GLOBAL_PTHREAD_PRIVATE
850= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING,
851	PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
852#else
853;
854#endif
855
856/* Default mutex attributes: */
857SCLASS struct pthread_mutex_attr pthread_mutexattr_default
858#ifdef GLOBAL_PTHREAD_PRIVATE
859= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
860#else
861;
862#endif
863
864/* Default condition variable attributes: */
865SCLASS struct pthread_cond_attr pthread_condattr_default
866#ifdef GLOBAL_PTHREAD_PRIVATE
867= { COND_TYPE_FAST, 0 };
868#else
869;
870#endif
871
872/*
873 * Standard I/O file descriptors need special flag treatment since
874 * setting one to non-blocking does all on *BSD. Sigh. This array
875 * is used to store the initial flag settings.
876 */
877SCLASS int	_pthread_stdio_flags[3];
878
879/* File table information: */
880SCLASS struct fd_table_entry **_thread_fd_table
881#ifdef GLOBAL_PTHREAD_PRIVATE
882= NULL;
883#else
884;
885#endif
886
887/* Table for polling file descriptors: */
888SCLASS struct pollfd *_thread_pfd_table
889#ifdef GLOBAL_PTHREAD_PRIVATE
890= NULL;
891#else
892;
893#endif
894
895SCLASS const int dtablecount
896#ifdef GLOBAL_PTHREAD_PRIVATE
897= 4096/sizeof(struct fd_table_entry);
898#else
899;
900#endif
901SCLASS int    _thread_dtablesize        /* Descriptor table size.           */
902#ifdef GLOBAL_PTHREAD_PRIVATE
903= 0;
904#else
905;
906#endif
907
908SCLASS int    _clock_res_nsec		/* Clock resolution in nsec.	*/
909#ifdef GLOBAL_PTHREAD_PRIVATE
910= CLOCK_RES_NSEC;
911#else
912;
913#endif
914
915/* Garbage collector mutex and condition variable. */
916SCLASS	pthread_mutex_t _gc_mutex
917#ifdef GLOBAL_PTHREAD_PRIVATE
918= NULL
919#endif
920;
921SCLASS	pthread_cond_t  _gc_cond
922#ifdef GLOBAL_PTHREAD_PRIVATE
923= NULL
924#endif
925;
926
927/*
928 * Array of signal actions for this process.
929 */
930SCLASS struct  sigaction _thread_sigact[NSIG];
931
932/*
933 * Pending signals for this process.
934 */
935SCLASS sigset_t	_process_sigpending;
936
937/*
938 * Scheduling queues:
939 */
940SCLASS pq_queue_t		_readyq;
941SCLASS TAILQ_HEAD(, pthread)	_waitingq;
942
943/*
944 * Work queue:
945 */
946SCLASS TAILQ_HEAD(, pthread)	_workq;
947
948/* Tracks the number of threads blocked while waiting for a spinlock. */
949SCLASS	volatile int	_spinblock_count
950#ifdef GLOBAL_PTHREAD_PRIVATE
951= 0
952#endif
953;
954
955/* Indicates that the signal queue needs to be checked. */
956SCLASS	volatile int	_sigq_check_reqd
957#ifdef GLOBAL_PTHREAD_PRIVATE
958= 0
959#endif
960;
961
962/* Thread switch hook. */
963SCLASS pthread_switch_routine_t _sched_switch_hook
964#ifdef GLOBAL_PTHREAD_PRIVATE
965= NULL
966#endif
967;
968
969/*
970 * Spare stack queue.  Stacks of default size are cached in order to reduce
971 * thread creation time.  Spare stacks are used in LIFO order to increase cache
972 * locality.
973 */
974SCLASS SLIST_HEAD(, stack)	_stackq;
975
976/*
977 * Base address of next unallocated default-size {stack, red zone}.  Stacks are
978 * allocated contiguously, starting below the bottom of the main stack.  When a
979 * new stack is created, a red zone is created (actually, the red zone is simply
980 * left unmapped) below the bottom of the stack, such that the stack will not be
981 * able to grow all the way to the top of the next stack.  This isn't
982 * fool-proof.  It is possible for a stack to grow by a large amount, such that
983 * it grows into the next stack, and as long as the memory within the red zone
984 * is never accessed, nothing will prevent one thread stack from trouncing all
985 * over the next.
986 */
987SCLASS void *	_next_stack
988#ifdef GLOBAL_PTHREAD_PRIVATE
989/* main stack top   - main stack size       - stack size            - (red zone + main stack red zone) */
990= (void *) USRSTACK - PTHREAD_STACK_INITIAL - PTHREAD_STACK_DEFAULT - (2 * PTHREAD_STACK_GUARD)
991#endif
992;
993
994/* Used for _PTHREADS_INVARIANTS checking. */
995SCLASS int	_thread_kern_new_state
996#ifdef GLOBAL_PTHREAD_PRIVATE
997= 0
998#endif
999;
1000
1001/* Undefine the storage class specifier: */
1002#undef  SCLASS
1003
1004#ifdef	_LOCK_DEBUG
1005#define	_FD_LOCK(_fd,_type,_ts)		_thread_fd_lock_debug(_fd, _type, \
1006						_ts, __FILE__, __LINE__)
1007#define _FD_UNLOCK(_fd,_type)		_thread_fd_unlock_debug(_fd, _type, \
1008						__FILE__, __LINE__)
1009#else
1010#define	_FD_LOCK(_fd,_type,_ts)		_thread_fd_lock(_fd, _type, _ts)
1011#define _FD_UNLOCK(_fd,_type)		_thread_fd_unlock(_fd, _type)
1012#endif
1013
1014/*
1015 * Function prototype definitions.
1016 */
1017__BEGIN_DECLS
1018char    *__ttyname_basic(int);
1019char    *__ttyname_r_basic(int, char *, size_t);
1020char    *ttyname_r(int, char *, size_t);
1021int     _find_dead_thread(pthread_t);
1022int     _find_thread(pthread_t);
1023void    _funlock_owned(pthread_t);
1024int     _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
1025int     _thread_fd_lock(int, int, struct timespec *);
1026int     _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno);
1027void    _dispatch_signals(void);
1028int	_mutex_cv_lock(pthread_mutex_t *);
1029int	_mutex_cv_unlock(pthread_mutex_t *);
1030void	_mutex_notify_priochange(pthread_t);
1031int	_mutex_reinit(pthread_mutex_t *);
1032void	_mutex_unlock_private(pthread_t);
1033int	_cond_reinit(pthread_cond_t *);
1034int	_pq_alloc(struct pq_queue *, int, int);
1035int	_pq_init(struct pq_queue *);
1036void	_pq_remove(struct pq_queue *pq, struct pthread *);
1037void	_pq_insert_head(struct pq_queue *pq, struct pthread *);
1038void	_pq_insert_tail(struct pq_queue *pq, struct pthread *);
1039struct pthread *_pq_first(struct pq_queue *pq);
1040#if defined(_PTHREADS_INVARIANTS)
1041void	_waitq_insert(pthread_t pthread);
1042void	_waitq_remove(pthread_t pthread);
1043void	_waitq_setactive(void);
1044void	_waitq_clearactive(void);
1045#endif
1046void    _thread_exit(char *, int, char *);
1047void    _thread_exit_cleanup(void);
1048void    _thread_fd_unlock(int, int);
1049void    _thread_fd_unlock_debug(int, int, char *, int);
1050void    _thread_fd_unlock_owned(pthread_t);
1051void    *_thread_cleanup(pthread_t);
1052void    _thread_cleanupspecific(void);
1053void    _thread_dump_info(void);
1054void    _thread_init(void);
1055void    _thread_kern_sched(ucontext_t *);
1056void    _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
1057void	_thread_kern_sched_state_unlock(enum pthread_state state,
1058	    spinlock_t *lock, char *fname, int lineno);
1059void    _thread_kern_set_timeout(struct timespec *);
1060void    _thread_kern_sig_defer(void);
1061void    _thread_kern_sig_undefer(void);
1062void    _thread_sig_handler(int, int, ucontext_t *);
1063pthread_t _thread_sig_handle(int, ucontext_t *);
1064void	_thread_sig_init(void);
1065void	_thread_sig_send(pthread_t pthread, int sig);
1066void	_thread_sig_deliver(pthread_t pthread, int sig);
1067void    _thread_start(void);
1068void    _thread_start_sig_handler(void);
1069void	_thread_seterrno(pthread_t,int);
1070int     _thread_fd_table_init(int fd);
1071pthread_addr_t _thread_gc(pthread_addr_t);
1072void	_thread_enter_cancellation_point(void);
1073void	_thread_leave_cancellation_point(void);
1074void	_thread_cancellation_point(void);
1075
1076/* #include <signal.h> */
1077int     _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *);
1078int     _thread_sys_sigpending(sigset_t *);
1079int     _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
1080int     _thread_sys_sigsuspend(const sigset_t *);
1081int     _thread_sys_siginterrupt(int, int);
1082int     _thread_sys_sigpause(int);
1083int     _thread_sys_sigreturn(ucontext_t *);
1084int     _thread_sys_sigstack(const struct sigstack *, struct sigstack *);
1085int     _thread_sys_sigvec(int, struct sigvec *, struct sigvec *);
1086void    _thread_sys_psignal(unsigned int, const char *);
1087void    (*_thread_sys_signal(int, void (*)(int)))(int);
1088
1089/* #include <sys/stat.h> */
1090#ifdef  _SYS_STAT_H_
1091int     _thread_sys_fchmod(int, mode_t);
1092int     _thread_sys_fstat(int, struct stat *);
1093int     _thread_sys_fchflags(int, u_long);
1094#endif
1095
1096/* #include <sys/mount.h> */
1097#ifdef  _SYS_MOUNT_H_
1098int     _thread_sys_fstatfs(int, struct statfs *);
1099#endif
1100int     _thread_sys_pipe(int *);
1101
1102/* #include <sys/socket.h> */
1103#ifdef  _SYS_SOCKET_H_
1104int     _thread_sys_accept(int, struct sockaddr *, int *);
1105int     _thread_sys_bind(int, const struct sockaddr *, int);
1106int     _thread_sys_connect(int, const struct sockaddr *, int);
1107int     _thread_sys_getpeername(int, struct sockaddr *, int *);
1108int     _thread_sys_getsockname(int, struct sockaddr *, int *);
1109int     _thread_sys_getsockopt(int, int, int, void *, int *);
1110int     _thread_sys_listen(int, int);
1111int     _thread_sys_setsockopt(int, int, int, const void *, int);
1112int     _thread_sys_shutdown(int, int);
1113int     _thread_sys_socket(int, int, int);
1114int     _thread_sys_socketpair(int, int, int, int *);
1115ssize_t _thread_sys_recv(int, void *, size_t, int);
1116ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
1117ssize_t _thread_sys_recvmsg(int, struct msghdr *, int);
1118ssize_t _thread_sys_send(int, const void *, size_t, int);
1119ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int);
1120ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, int);
1121#endif
1122
1123/* #include <stdio.h> */
1124#ifdef  _STDIO_H_
1125FILE    *_thread_sys_fdopen(int, const char *);
1126FILE    *_thread_sys_fopen(const char *, const char *);
1127FILE    *_thread_sys_freopen(const char *, const char *, FILE *);
1128FILE    *_thread_sys_popen(const char *, const char *);
1129FILE    *_thread_sys_tmpfile(void);
1130char    *_thread_sys_ctermid(char *);
1131char    *_thread_sys_cuserid(char *);
1132char    *_thread_sys_fgetln(FILE *, size_t *);
1133char    *_thread_sys_fgets(char *, int, FILE *);
1134char    *_thread_sys_gets(char *);
1135char    *_thread_sys_tempnam(const char *, const char *);
1136char    *_thread_sys_tmpnam(char *);
1137int     _thread_sys_fclose(FILE *);
1138int     _thread_sys_feof(FILE *);
1139int     _thread_sys_ferror(FILE *);
1140int     _thread_sys_fflush(FILE *);
1141int     _thread_sys_fgetc(FILE *);
1142int     _thread_sys_fgetpos(FILE *, fpos_t *);
1143int     _thread_sys_fileno(FILE *);
1144int     _thread_sys_fprintf(FILE *, const char *, ...);
1145int     _thread_sys_fpurge(FILE *);
1146int     _thread_sys_fputc(int, FILE *);
1147int     _thread_sys_fputs(const char *, FILE *);
1148int     _thread_sys_fscanf(FILE *, const char *, ...);
1149int     _thread_sys_fseek(FILE *, long, int);
1150int     _thread_sys_fsetpos(FILE *, const fpos_t *);
1151int     _thread_sys_getc(FILE *);
1152int     _thread_sys_getchar(void);
1153int     _thread_sys_getw(FILE *);
1154int     _thread_sys_pclose(FILE *);
1155int     _thread_sys_printf(const char *, ...);
1156int     _thread_sys_putc(int, FILE *);
1157int     _thread_sys_putchar(int);
1158int     _thread_sys_puts(const char *);
1159int     _thread_sys_putw(int, FILE *);
1160int     _thread_sys_remove(const char *);
1161int     _thread_sys_rename (const char *, const char *);
1162int     _thread_sys_scanf(const char *, ...);
1163int     _thread_sys_setlinebuf(FILE *);
1164int     _thread_sys_setvbuf(FILE *, char *, int, size_t);
1165int     _thread_sys_snprintf(char *, size_t, const char *, ...);
1166int     _thread_sys_sprintf(char *, const char *, ...);
1167int     _thread_sys_sscanf(const char *, const char *, ...);
1168int     _thread_sys_ungetc(int, FILE *);
1169int     _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_);
1170int     _thread_sys_vprintf(const char *, _BSD_VA_LIST_);
1171int     _thread_sys_vscanf(const char *, _BSD_VA_LIST_);
1172int     _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
1173int     _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_);
1174int     _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_);
1175long    _thread_sys_ftell(FILE *);
1176size_t  _thread_sys_fread(void *, size_t, size_t, FILE *);
1177size_t  _thread_sys_fwrite(const void *, size_t, size_t, FILE *);
1178void    _thread_sys_clearerr(FILE *);
1179void    _thread_sys_perror(const char *);
1180void    _thread_sys_rewind(FILE *);
1181void    _thread_sys_setbuf(FILE *, char *);
1182void    _thread_sys_setbuffer(FILE *, char *, int);
1183#endif
1184
1185/* #include <unistd.h> */
1186#ifdef  _UNISTD_H_
1187char    *_thread_sys_ttyname(int);
1188int     _thread_sys_close(int);
1189int     _thread_sys_dup(int);
1190int     _thread_sys_dup2(int, int);
1191int     _thread_sys_exect(const char *, char * const *, char * const *);
1192int     _thread_sys_execve(const char *, char * const *, char * const *);
1193int     _thread_sys_fchdir(int);
1194int     _thread_sys_fchown(int, uid_t, gid_t);
1195int     _thread_sys_fsync(int);
1196int     _thread_sys_ftruncate(int, off_t);
1197int     _thread_sys_pause(void);
1198int     _thread_sys_pipe(int *);
1199int     _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
1200off_t   _thread_sys_lseek(int, off_t, int);
1201pid_t   _thread_sys_fork(void);
1202pid_t   _thread_sys_tcgetpgrp(int);
1203ssize_t _thread_sys_read(int, void *, size_t);
1204ssize_t _thread_sys_write(int, const void *, size_t);
1205void	_thread_sys__exit(int);
1206#endif
1207
1208/* #include <fcntl.h> */
1209#ifdef  _SYS_FCNTL_H_
1210int     _thread_sys_creat(const char *, mode_t);
1211int     _thread_sys_fcntl(int, int, ...);
1212int     _thread_sys_flock(int, int);
1213int     _thread_sys_open(const char *, int, ...);
1214#endif
1215
1216/* #include <sys/ioctl.h> */
1217#ifdef  _SYS_IOCTL_H_
1218int     _thread_sys_ioctl(int, unsigned long, ...);
1219#endif
1220
1221/* #include <dirent.h> */
1222#ifdef  _DIRENT_H_
1223DIR     *___thread_sys_opendir2(const char *, int);
1224DIR     *_thread_sys_opendir(const char *);
1225int     _thread_sys_alphasort(const void *, const void *);
1226int     _thread_sys_scandir(const char *, struct dirent ***,
1227	int (*)(struct dirent *), int (*)(const void *, const void *));
1228int     _thread_sys_closedir(DIR *);
1229int     _thread_sys_getdirentries(int, char *, int, long *);
1230long    _thread_sys_telldir(const DIR *);
1231struct  dirent *_thread_sys_readdir(DIR *);
1232void    _thread_sys_rewinddir(DIR *);
1233void    _thread_sys_seekdir(DIR *, long);
1234#endif
1235
1236/* #include <sys/uio.h> */
1237#ifdef  _SYS_UIO_H_
1238ssize_t _thread_sys_readv(int, const struct iovec *, int);
1239ssize_t _thread_sys_writev(int, const struct iovec *, int);
1240#endif
1241
1242/* #include <sys/wait.h> */
1243#ifdef  WNOHANG
1244pid_t   _thread_sys_wait(int *);
1245pid_t   _thread_sys_waitpid(pid_t, int *, int);
1246pid_t   _thread_sys_wait3(int *, int, struct rusage *);
1247pid_t   _thread_sys_wait4(pid_t, int *, int, struct rusage *);
1248#endif
1249
1250/* #include <poll.h> */
1251#ifdef _SYS_POLL_H_
1252int 	_thread_sys_poll(struct pollfd *, unsigned, int);
1253#endif
1254
1255/* #include <sys/mman.h> */
1256#ifdef _SYS_MMAN_H_
1257int	_thread_sys_msync(void *, size_t, int);
1258#endif
1259
1260/* #include <setjmp.h> */
1261#ifdef _SETJMP_H_
1262extern void	__siglongjmp(sigjmp_buf, int) __dead2;
1263extern void	__longjmp(jmp_buf, int) __dead2;
1264extern void	___longjmp(jmp_buf, int) __dead2;
1265#endif
1266__END_DECLS
1267
1268#endif  /* !_PTHREAD_PRIVATE_H */
1269