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