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