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