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. Neither the name of the author nor the names of any co-contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Private thread definitions for the uthread kernel.
30  *
31  * $FreeBSD: stable/9/lib/libkse/thread/thr_private.h 174689 2007-12-16 23:29:57Z deischen $
32  */
33 
34 #ifndef _THR_PRIVATE_H
35 #define _THR_PRIVATE_H
36 
37 /*
38  * Include files.
39  */
40 #include <setjmp.h>
41 #include <signal.h>
42 #include <stdio.h>
43 #include <sys/queue.h>
44 #include <sys/types.h>
45 #include <sys/time.h>
46 #include <sys/cdefs.h>
47 #include <sys/kse.h>
48 #include <sched.h>
49 #include <ucontext.h>
50 #include <unistd.h>
51 #include <pthread.h>
52 #include <pthread_np.h>
53 
54 #ifndef LIBTHREAD_DB
55 #include "lock.h"
56 #include "pthread_md.h"
57 #endif
58 
59 
60 /*
61  * Evaluate the storage class specifier.
62  */
63 #ifdef GLOBAL_PTHREAD_PRIVATE
64 #define SCLASS
65 #define SCLASS_PRESET(x...)	= x
66 #else
67 #define SCLASS			extern
68 #define SCLASS_PRESET(x...)
69 #endif
70 
71 /*
72  * Kernel fatal error handler macro.
73  */
74 #define PANIC(string)   _thr_exit(__FILE__, __LINE__, string)
75 
76 
77 /* Output debug messages like this: */
78 #ifdef STDOUT_FILENO
79 #define stdout_debug(...)	_thread_printf(STDOUT_FILENO, __VA_ARGS__)
80 #endif
81 #ifdef STDERR_FILENO
82 #define stderr_debug(...)	_thread_printf(STDERR_FILENO, __VA_ARGS__)
83 #endif
84 
85 #define	DBG_MUTEX	0x0001
86 #define	DBG_SIG		0x0002
87 #define	DBG_INFO_DUMP	0x0004
88 
89 #ifdef _PTHREADS_INVARIANTS
90 #define THR_ASSERT(cond, msg) do {	\
91 	if (!(cond))			\
92 		PANIC(msg);		\
93 } while (0)
94 #else
95 #define THR_ASSERT(cond, msg)
96 #endif
97 
98 /*
99  * State change macro without scheduling queue change:
100  */
101 #define THR_SET_STATE(thrd, newstate) do {				\
102 	(thrd)->state = newstate;					\
103 	(thrd)->fname = __FILE__;					\
104 	(thrd)->lineno = __LINE__;					\
105 } while (0)
106 
107 
108 #define	TIMESPEC_ADD(dst, src, val)				\
109 	do { 							\
110 		(dst)->tv_sec = (src)->tv_sec + (val)->tv_sec;	\
111 		(dst)->tv_nsec = (src)->tv_nsec + (val)->tv_nsec; \
112 		if ((dst)->tv_nsec >= 1000000000) {		\
113 			(dst)->tv_sec++;			\
114 			(dst)->tv_nsec -= 1000000000;		\
115 		}						\
116 	} while (0)
117 
118 #define	TIMESPEC_SUB(dst, src, val)				\
119 	do { 							\
120 		(dst)->tv_sec = (src)->tv_sec - (val)->tv_sec;	\
121 		(dst)->tv_nsec = (src)->tv_nsec - (val)->tv_nsec; \
122 		if ((dst)->tv_nsec < 0) {			\
123 			(dst)->tv_sec--;			\
124 			(dst)->tv_nsec += 1000000000;		\
125 		}						\
126 	} while (0)
127 
128 /*
129  * Priority queues.
130  *
131  * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
132  */
133 typedef struct pq_list {
134 	TAILQ_HEAD(, pthread)	pl_head; /* list of threads at this priority */
135 	TAILQ_ENTRY(pq_list)	pl_link; /* link for queue of priority lists */
136 	int			pl_prio; /* the priority of this list */
137 	int			pl_queued; /* is this in the priority queue */
138 } pq_list_t;
139 
140 typedef struct pq_queue {
141 	TAILQ_HEAD(, pq_list)	 pq_queue; /* queue of priority lists */
142 	pq_list_t		*pq_lists; /* array of all priority lists */
143 	int			 pq_size;  /* number of priority lists */
144 #define	PQF_ACTIVE	0x0001
145 	int			 pq_flags;
146 	int			 pq_threads;
147 } pq_queue_t;
148 
149 /*
150  * Each KSEG has a scheduling queue.  For now, threads that exist in their
151  * own KSEG (system scope) will get a full priority queue.  In the future
152  * this can be optimized for the single thread per KSEG case.
153  */
154 struct sched_queue {
155 	pq_queue_t		sq_runq;
156 	TAILQ_HEAD(, pthread)	sq_waitq;	/* waiting in userland */
157 };
158 
159 typedef struct kse_thr_mailbox *kse_critical_t;
160 
161 struct kse_group;
162 
163 #define	MAX_KSE_LOCKLEVEL	5
164 struct kse {
165 	/* -- location and order specific items for gdb -- */
166 	struct kcb		*k_kcb;
167 	struct pthread		*k_curthread;	/* current thread */
168 	struct kse_group	*k_kseg;	/* parent KSEG */
169 	struct sched_queue	*k_schedq;	/* scheduling queue */
170 	/* -- end of location and order specific items -- */
171 	TAILQ_ENTRY(kse)	k_qe;		/* KSE list link entry */
172 	TAILQ_ENTRY(kse)	k_kgqe;		/* KSEG's KSE list entry */
173 	/*
174 	 * Items that are only modified by the kse, or that otherwise
175 	 * don't need to be locked when accessed
176 	 */
177 	struct lock		k_lock;
178 	struct lockuser		k_lockusers[MAX_KSE_LOCKLEVEL];
179 	int			k_locklevel;
180 	stack_t			k_stack;
181 	int			k_flags;
182 #define	KF_STARTED			0x0001	/* kernel kse created */
183 #define	KF_INITIALIZED			0x0002	/* initialized on 1st upcall */
184 #define	KF_TERMINATED			0x0004	/* kse is terminated */
185 #define	KF_IDLE				0x0008	/* kse is idle */
186 #define	KF_SWITCH			0x0010	/* thread switch in UTS */
187 	int			k_error;	/* syscall errno in critical */
188 	int			k_cpu;		/* CPU ID when bound */
189 	int			k_sigseqno;	/* signal buffered count */
190 };
191 
192 #define	KSE_SET_IDLE(kse)	((kse)->k_flags |= KF_IDLE)
193 #define	KSE_CLEAR_IDLE(kse)	((kse)->k_flags &= ~KF_IDLE)
194 #define	KSE_IS_IDLE(kse)	(((kse)->k_flags & KF_IDLE) != 0)
195 #define	KSE_SET_SWITCH(kse)	((kse)->k_flags |= KF_SWITCH)
196 #define	KSE_CLEAR_SWITCH(kse)	((kse)->k_flags &= ~KF_SWITCH)
197 #define	KSE_IS_SWITCH(kse)	(((kse)->k_flags & KF_SWITCH) != 0)
198 
199 /*
200  * Each KSE group contains one or more KSEs in which threads can run.
201  * At least for now, there is one scheduling queue per KSE group; KSEs
202  * within the same KSE group compete for threads from the same scheduling
203  * queue.  A scope system thread has one KSE in one KSE group; the group
204  * does not use its scheduling queue.
205  */
206 struct kse_group {
207 	TAILQ_HEAD(, kse)	kg_kseq;	/* list of KSEs in group */
208 	TAILQ_HEAD(, pthread)	kg_threadq;	/* list of threads in group */
209 	TAILQ_ENTRY(kse_group)  kg_qe;		/* link entry */
210 	struct sched_queue	kg_schedq;	/* scheduling queue */
211 	struct lock		kg_lock;
212 	int			kg_threadcount;	/* # of assigned threads */
213 	int			kg_ksecount;	/* # of assigned KSEs */
214 	int			kg_idle_kses;
215 	int			kg_flags;
216 #define	KGF_SINGLE_THREAD		0x0001	/* scope system kse group */
217 #define	KGF_SCHEDQ_INITED		0x0002	/* has an initialized schedq */
218 };
219 
220 /*
221  * Add/remove threads from a KSE's scheduling queue.
222  * For now the scheduling queue is hung off the KSEG.
223  */
224 #define	KSEG_THRQ_ADD(kseg, thr)			\
225 do {							\
226 	TAILQ_INSERT_TAIL(&(kseg)->kg_threadq, thr, kle);\
227 	(kseg)->kg_threadcount++;			\
228 } while (0)
229 
230 #define	KSEG_THRQ_REMOVE(kseg, thr)			\
231 do {							\
232 	TAILQ_REMOVE(&(kseg)->kg_threadq, thr, kle);	\
233 	(kseg)->kg_threadcount--;			\
234 } while (0)
235 
236 
237 /*
238  * Lock acquire and release for KSEs.
239  */
240 #define	KSE_LOCK_ACQUIRE(kse, lck)					\
241 do {									\
242 	if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) {			\
243 		(kse)->k_locklevel++;					\
244 		_lock_acquire((lck),					\
245 		    &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0);	\
246 	}								\
247 	else 								\
248 		PANIC("Exceeded maximum lock level");			\
249 } while (0)
250 
251 #define	KSE_LOCK_RELEASE(kse, lck)					\
252 do {									\
253 	if ((kse)->k_locklevel > 0) {					\
254 		_lock_release((lck),					\
255 		    &(kse)->k_lockusers[(kse)->k_locklevel - 1]);	\
256 		(kse)->k_locklevel--;					\
257 	}								\
258 } while (0)
259 
260 /*
261  * Lock our own KSEG.
262  */
263 #define	KSE_LOCK(curkse)		\
264 	KSE_LOCK_ACQUIRE(curkse, &(curkse)->k_kseg->kg_lock)
265 #define	KSE_UNLOCK(curkse)		\
266 	KSE_LOCK_RELEASE(curkse, &(curkse)->k_kseg->kg_lock)
267 
268 /*
269  * Lock a potentially different KSEG.
270  */
271 #define	KSE_SCHED_LOCK(curkse, kseg)	\
272 	KSE_LOCK_ACQUIRE(curkse, &(kseg)->kg_lock)
273 #define	KSE_SCHED_UNLOCK(curkse, kseg)	\
274 	KSE_LOCK_RELEASE(curkse, &(kseg)->kg_lock)
275 
276 /*
277  * Waiting queue manipulation macros (using pqe link):
278  */
279 #define KSE_WAITQ_REMOVE(kse, thrd) \
280 do { \
281 	if (((thrd)->flags & THR_FLAGS_IN_WAITQ) != 0) { \
282 		TAILQ_REMOVE(&(kse)->k_schedq->sq_waitq, thrd, pqe); \
283 		(thrd)->flags &= ~THR_FLAGS_IN_WAITQ; \
284 	} \
285 } while (0)
286 #define KSE_WAITQ_INSERT(kse, thrd)	kse_waitq_insert(thrd)
287 #define	KSE_WAITQ_FIRST(kse)		TAILQ_FIRST(&(kse)->k_schedq->sq_waitq)
288 
289 #define	KSE_WAKEUP(kse)		kse_wakeup(&(kse)->k_kcb->kcb_kmbx)
290 
291 /*
292  * TailQ initialization values.
293  */
294 #define TAILQ_INITIALIZER	{ NULL, NULL }
295 
296 /*
297  * lock initialization values.
298  */
299 #define	LCK_INITIALIZER		{ NULL, NULL, LCK_DEFAULT }
300 
301 struct pthread_mutex {
302 	/*
303 	 * Lock for accesses to this structure.
304 	 */
305 	struct lock			m_lock;
306 	enum pthread_mutextype		m_type;
307 	int				m_protocol;
308 	TAILQ_HEAD(mutex_head, pthread)	m_queue;
309 	struct pthread			*m_owner;
310 	long				m_flags;
311 	int				m_count;
312 	int				m_refcount;
313 
314 	/*
315 	 * Used for priority inheritence and protection.
316 	 *
317 	 *   m_prio       - For priority inheritence, the highest active
318 	 *                  priority (threads locking the mutex inherit
319 	 *                  this priority).  For priority protection, the
320 	 *                  ceiling priority of this mutex.
321 	 *   m_saved_prio - mutex owners inherited priority before
322 	 *                  taking the mutex, restored when the owner
323 	 *                  unlocks the mutex.
324 	 */
325 	int				m_prio;
326 	int				m_saved_prio;
327 
328 	/*
329 	 * Link for list of all mutexes a thread currently owns.
330 	 */
331 	TAILQ_ENTRY(pthread_mutex)	m_qe;
332 };
333 
334 /*
335  * Flags for mutexes.
336  */
337 #define MUTEX_FLAGS_PRIVATE	0x01
338 #define MUTEX_FLAGS_INITED	0x02
339 #define MUTEX_FLAGS_BUSY	0x04
340 
341 /*
342  * Static mutex initialization values.
343  */
344 #define PTHREAD_MUTEX_STATIC_INITIALIZER				\
345 	{ LCK_INITIALIZER, PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE,	\
346 	TAILQ_INITIALIZER, NULL, MUTEX_FLAGS_PRIVATE, 0, 0, 0, 0,	\
347 	TAILQ_INITIALIZER }
348 
349 struct pthread_mutex_attr {
350 	enum pthread_mutextype	m_type;
351 	int			m_protocol;
352 	int			m_ceiling;
353 	long			m_flags;
354 };
355 
356 #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
357 	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
358 
359 /*
360  * Condition variable definitions.
361  */
362 enum pthread_cond_type {
363 	COND_TYPE_FAST,
364 	COND_TYPE_MAX
365 };
366 
367 struct pthread_cond {
368 	/*
369 	 * Lock for accesses to this structure.
370 	 */
371 	struct lock			c_lock;
372 	enum pthread_cond_type		c_type;
373 	TAILQ_HEAD(cond_head, pthread)	c_queue;
374 	struct pthread_mutex		*c_mutex;
375 	long				c_flags;
376 	long				c_seqno;
377 };
378 
379 struct pthread_cond_attr {
380 	enum pthread_cond_type	c_type;
381 	long			c_flags;
382 };
383 
384 struct pthread_barrier {
385 	pthread_mutex_t	b_lock;
386 	pthread_cond_t	b_cond;
387 	int		b_count;
388 	int		b_waiters;
389 	int		b_generation;
390 };
391 
392 struct pthread_barrierattr {
393 	int		pshared;
394 };
395 
396 struct pthread_spinlock {
397 	volatile int	s_lock;
398 	pthread_t	s_owner;
399 };
400 
401 /*
402  * Flags for condition variables.
403  */
404 #define COND_FLAGS_PRIVATE	0x01
405 #define COND_FLAGS_INITED	0x02
406 #define COND_FLAGS_BUSY		0x04
407 
408 /*
409  * Static cond initialization values.
410  */
411 #define PTHREAD_COND_STATIC_INITIALIZER				\
412 	{ LCK_INITIALIZER, COND_TYPE_FAST, TAILQ_INITIALIZER,	\
413 	NULL, NULL, 0, 0 }
414 
415 /*
416  * Cleanup definitions.
417  */
418 struct pthread_cleanup {
419 	struct pthread_cleanup	*next;
420 	void			(*routine) (void *);
421 	void			*routine_arg;
422 	int			onstack;
423 };
424 
425 #define	THR_CLEANUP_PUSH(td, func, arg) {		\
426 	struct pthread_cleanup __cup;			\
427 							\
428 	__cup.routine = func;				\
429 	__cup.routine_arg = arg;			\
430 	__cup.onstack = 1;				\
431 	__cup.next = (td)->cleanup;			\
432 	(td)->cleanup = &__cup;
433 
434 #define	THR_CLEANUP_POP(td, exec)			\
435 	(td)->cleanup = __cup.next;			\
436 	if ((exec) != 0)				\
437 		__cup.routine(__cup.routine_arg);	\
438 }
439 
440 struct pthread_atfork {
441 	TAILQ_ENTRY(pthread_atfork) qe;
442 	void (*prepare)(void);
443 	void (*parent)(void);
444 	void (*child)(void);
445 };
446 
447 struct pthread_attr {
448 	int	sched_policy;
449 	int	sched_inherit;
450 	int	sched_interval;
451 	int	prio;
452 	int	suspend;
453 #define	THR_STACK_USER		0x100	/* 0xFF reserved for <pthread.h> */
454 #define	THR_SIGNAL_THREAD	0x200	/* This is a signal thread */
455 	int	flags;
456 	void	*arg_attr;
457 	void	(*cleanup_attr) (void *);
458 	void	*stackaddr_attr;
459 	size_t	stacksize_attr;
460 	size_t	guardsize_attr;
461 };
462 
463 /*
464  * Thread creation state attributes.
465  */
466 #define THR_CREATE_RUNNING		0
467 #define THR_CREATE_SUSPENDED		1
468 
469 /*
470  * Miscellaneous definitions.
471  */
472 #define THR_STACK32_DEFAULT			(1 * 1024 * 1024)
473 #define THR_STACK64_DEFAULT			(2 * 1024 * 1024)
474 
475 /*
476  * Maximum size of initial thread's stack.  This perhaps deserves to be larger
477  * than the stacks of other threads, since many applications are likely to run
478  * almost entirely on this stack.
479  */
480 #define THR_STACK32_INITIAL			(2 * 1024 * 1024)
481 #define THR_STACK64_INITIAL			(4 * 1024 * 1024)
482 
483 /*
484  * Define the different priority ranges.  All applications have thread
485  * priorities constrained within 0-31.  The threads library raises the
486  * priority when delivering signals in order to ensure that signal
487  * delivery happens (from the POSIX spec) "as soon as possible".
488  * In the future, the threads library will also be able to map specific
489  * threads into real-time (cooperating) processes or kernel threads.
490  * The RT and SIGNAL priorities will be used internally and added to
491  * thread base priorities so that the scheduling queue can handle both
492  * normal and RT priority threads with and without signal handling.
493  *
494  * The approach taken is that, within each class, signal delivery
495  * always has priority over thread execution.
496  */
497 #define THR_DEFAULT_PRIORITY			15
498 #define THR_MIN_PRIORITY			0
499 #define THR_MAX_PRIORITY			31	/* 0x1F */
500 #define THR_SIGNAL_PRIORITY			32	/* 0x20 */
501 #define THR_RT_PRIORITY				64	/* 0x40 */
502 #define THR_FIRST_PRIORITY			THR_MIN_PRIORITY
503 #define THR_LAST_PRIORITY	\
504 	(THR_MAX_PRIORITY + THR_SIGNAL_PRIORITY + THR_RT_PRIORITY)
505 #define THR_BASE_PRIORITY(prio)	((prio) & THR_MAX_PRIORITY)
506 
507 /*
508  * Clock resolution in microseconds.
509  */
510 #define CLOCK_RES_USEC				10000
511 
512 /*
513  * Time slice period in microseconds.
514  */
515 #define TIMESLICE_USEC				20000
516 
517 /*
518  * XXX - Define a thread-safe macro to get the current time of day
519  *       which is updated at regular intervals by something.
520  *
521  * For now, we just make the system call to get the time.
522  */
523 #define	KSE_GET_TOD(curkse, tsp) \
524 do {							\
525 	*tsp = (curkse)->k_kcb->kcb_kmbx.km_timeofday;	\
526 	if ((tsp)->tv_sec == 0)				\
527 		clock_gettime(CLOCK_REALTIME, tsp);	\
528 } while (0)
529 
530 struct pthread_rwlockattr {
531 	int		pshared;
532 };
533 
534 struct pthread_rwlock {
535 	pthread_mutex_t	lock;	/* monitor lock */
536 	pthread_cond_t	read_signal;
537 	pthread_cond_t	write_signal;
538 	int		state;	/* 0 = idle  >0 = # of readers  -1 = writer */
539 	int		blocked_writers;
540 };
541 
542 /*
543  * Thread states.
544  */
545 enum pthread_state {
546 	PS_RUNNING,
547 	PS_LOCKWAIT,
548 	PS_MUTEX_WAIT,
549 	PS_COND_WAIT,
550 	PS_SLEEP_WAIT,
551 	PS_SIGSUSPEND,
552 	PS_SIGWAIT,
553 	PS_JOIN,
554 	PS_SUSPENDED,
555 	PS_DEAD,
556 	PS_DEADLOCK,
557 	PS_STATE_MAX
558 };
559 
560 struct sigwait_data {
561 	sigset_t	*waitset;
562 	siginfo_t	*siginfo;	/* used to save siginfo for sigwaitinfo() */
563 };
564 
565 union pthread_wait_data {
566 	pthread_mutex_t	mutex;
567 	pthread_cond_t	cond;
568 	struct lock	*lock;
569 	struct sigwait_data *sigwait;
570 };
571 
572 /*
573  * Define a continuation routine that can be used to perform a
574  * transfer of control:
575  */
576 typedef void	(*thread_continuation_t) (void *);
577 
578 /*
579  * This stores a thread's state prior to running a signal handler.
580  * It is used when a signal is delivered to a thread blocked in
581  * userland.  If the signal handler returns normally, the thread's
582  * state is restored from here.
583  */
584 struct pthread_sigframe {
585 	int			psf_valid;
586 	int			psf_flags;
587 	int			psf_cancelflags;
588 	int			psf_interrupted;
589 	int			psf_timeout;
590 	int			psf_signo;
591 	enum pthread_state	psf_state;
592 	union pthread_wait_data psf_wait_data;
593 	struct timespec		psf_wakeup_time;
594 	sigset_t		psf_sigset;
595 	sigset_t		psf_sigmask;
596 	int			psf_seqno;
597 	thread_continuation_t	psf_continuation;
598 };
599 
600 struct join_status {
601 	struct pthread	*thread;
602 	void		*ret;
603 	int		error;
604 };
605 
606 struct pthread_specific_elem {
607 	void	*data;
608 	int	seqno;
609 };
610 
611 typedef void (*const_key_destructor_t)(const void *);
612 typedef void (*key_destructor_t)(void *);
613 
614 struct pthread_key {
615 	volatile int	allocated;
616 	volatile int	count;
617 	int		seqno;
618 	key_destructor_t destructor;
619 };
620 
621 #define	MAX_THR_LOCKLEVEL	5
622 /*
623  * Thread structure.
624  */
625 struct pthread {
626 	/* Thread control block */
627 	struct tcb		*tcb;
628 
629 	/*
630 	 * Magic value to help recognize a valid thread structure
631 	 * from an invalid one:
632 	 */
633 #define	THR_MAGIC		((u_int32_t) 0xd09ba115)
634 	u_int32_t		magic;
635 	char			*name;
636 	u_int64_t		uniqueid; /* for gdb */
637 
638 	/* Queue entry for list of all threads: */
639 	TAILQ_ENTRY(pthread)	tle;	/* link for all threads in process */
640 	TAILQ_ENTRY(pthread)	kle;	/* link for all threads in KSE/KSEG */
641 
642 	/* Queue entry for GC lists: */
643 	TAILQ_ENTRY(pthread)	gcle;
644 
645 	/* Hash queue entry */
646 	LIST_ENTRY(pthread)	hle;
647 
648 	/*
649 	 * Lock for accesses to this thread structure.
650 	 */
651 	struct lock		lock;
652 	struct lockuser		lockusers[MAX_THR_LOCKLEVEL];
653 	int			locklevel;
654 	kse_critical_t		critical[MAX_KSE_LOCKLEVEL];
655 	struct kse		*kse;
656 	struct kse_group	*kseg;
657 
658 	/*
659 	 * Thread start routine, argument, stack pointer and thread
660 	 * attributes.
661 	 */
662 	void			*(*start_routine)(void *);
663 	void			*arg;
664 	struct pthread_attr	attr;
665 
666 	int			active;		/* thread running */
667 	int			blocked;	/* thread blocked in kernel */
668 	int			need_switchout;
669 
670 	/*
671 	 * Used for tracking delivery of signal handlers.
672 	 */
673 	siginfo_t		*siginfo;
674 	thread_continuation_t	sigbackout;
675 
676  	/*
677 	 * Cancelability flags - the lower 2 bits are used by cancel
678 	 * definitions in pthread.h
679 	 */
680 #define THR_AT_CANCEL_POINT		0x0004
681 #define THR_CANCELLING			0x0008
682 #define THR_CANCEL_NEEDED		0x0010
683 	int			cancelflags;
684 
685 	thread_continuation_t	continuation;
686 
687 	/*
688 	 * The thread's base and pending signal masks.  The active
689 	 * signal mask is stored in the thread's context (in mailbox).
690 	 */
691 	sigset_t		sigmask;
692 	sigset_t		sigpend;
693 	sigset_t		*oldsigmask;
694 	volatile int		check_pending;
695 	int			refcount;
696 
697 	/* Thread state: */
698 	enum pthread_state	state;
699 	volatile int		lock_switch;
700 
701 	/*
702 	 * Number of microseconds accumulated by this thread when
703 	 * time slicing is active.
704 	 */
705 	long			slice_usec;
706 
707 	/*
708 	 * Time to wake up thread. This is used for sleeping threads and
709 	 * for any operation which may time out (such as select).
710 	 */
711 	struct timespec		wakeup_time;
712 
713 	/* TRUE if operation has timed out. */
714 	int			timeout;
715 
716 	/*
717 	 * Error variable used instead of errno. The function __error()
718 	 * returns a pointer to this.
719 	 */
720 	int			error;
721 
722 	/*
723 	 * The joiner is the thread that is joining to this thread.  The
724 	 * join status keeps track of a join operation to another thread.
725 	 */
726 	struct pthread		*joiner;
727 	struct join_status	join_status;
728 
729 	/*
730 	 * The current thread can belong to only one scheduling queue at
731 	 * a time (ready or waiting queue).  It can also belong to:
732 	 *
733 	 *   o A queue of threads waiting for a mutex
734 	 *   o A queue of threads waiting for a condition variable
735 	 *
736 	 * It is possible for a thread to belong to more than one of the
737 	 * above queues if it is handling a signal.  A thread may only
738 	 * enter a mutex or condition variable queue when it is not
739 	 * being called from a signal handler.  If a thread is a member
740 	 * of one of these queues when a signal handler is invoked, it
741 	 * must be removed from the queue before invoking the handler
742 	 * and then added back to the queue after return from the handler.
743 	 *
744 	 * Use pqe for the scheduling queue link (both ready and waiting),
745 	 * sqe for synchronization (mutex, condition variable, and join)
746 	 * queue links, and qe for all other links.
747 	 */
748 	TAILQ_ENTRY(pthread)	pqe;	/* priority, wait queues link */
749 	TAILQ_ENTRY(pthread)	sqe;	/* synchronization queue link */
750 
751 	/* Wait data. */
752 	union pthread_wait_data data;
753 
754 	/*
755 	 * Set to TRUE if a blocking operation was
756 	 * interrupted by a signal:
757 	 */
758 	int			interrupted;
759 
760 	/*
761 	 * Set to non-zero when this thread has entered a critical
762 	 * region.  We allow for recursive entries into critical regions.
763 	 */
764 	int			critical_count;
765 
766 	/*
767 	 * Set to TRUE if this thread should yield after leaving a
768 	 * critical region to check for signals, messages, etc.
769 	 */
770 	int			critical_yield;
771 
772 	int			sflags;
773 #define THR_FLAGS_IN_SYNCQ	0x0001
774 
775 	/* Miscellaneous flags; only set with scheduling lock held. */
776 	int			flags;
777 #define THR_FLAGS_PRIVATE	0x0001
778 #define THR_FLAGS_IN_WAITQ	0x0002	/* in waiting queue using pqe link */
779 #define THR_FLAGS_IN_RUNQ	0x0004	/* in run queue using pqe link */
780 #define	THR_FLAGS_EXITING	0x0008	/* thread is exiting */
781 #define	THR_FLAGS_SUSPENDED	0x0010	/* thread is suspended */
782 
783 	/* Thread list flags; only set with thread list lock held. */
784 #define	TLFLAGS_GC_SAFE		0x0001	/* thread safe for cleaning */
785 #define	TLFLAGS_IN_TDLIST	0x0002	/* thread in all thread list */
786 #define	TLFLAGS_IN_GCLIST	0x0004	/* thread in gc list */
787 	int			tlflags;
788 
789 	/*
790 	 * Base priority is the user setable and retrievable priority
791 	 * of the thread.  It is only affected by explicit calls to
792 	 * set thread priority and upon thread creation via a thread
793 	 * attribute or default priority.
794 	 */
795 	char			base_priority;
796 
797 	/*
798 	 * Inherited priority is the priority a thread inherits by
799 	 * taking a priority inheritence or protection mutex.  It
800 	 * is not affected by base priority changes.  Inherited
801 	 * priority defaults to and remains 0 until a mutex is taken
802 	 * that is being waited on by any other thread whose priority
803 	 * is non-zero.
804 	 */
805 	char			inherited_priority;
806 
807 	/*
808 	 * Active priority is always the maximum of the threads base
809 	 * priority and inherited priority.  When there is a change
810 	 * in either the base or inherited priority, the active
811 	 * priority must be recalculated.
812 	 */
813 	char			active_priority;
814 
815 	/* Number of priority ceiling or protection mutexes owned. */
816 	int			priority_mutex_count;
817 
818 	/* Number rwlocks rdlocks held. */
819 	int			rdlock_count;
820 
821 	/*
822 	 * Queue of currently owned mutexes.
823 	 */
824 	TAILQ_HEAD(, pthread_mutex)	mutexq;
825 
826 	void				*ret;
827 	struct pthread_specific_elem	*specific;
828 	int				specific_data_count;
829 
830 	/* Alternative stack for sigaltstack() */
831 	stack_t				sigstk;
832 
833 	/*
834 	 * Current locks bitmap for rtld.
835 	 */
836 	int	rtld_bits;
837 
838 	/* Cleanup handlers Link List */
839 	struct pthread_cleanup *cleanup;
840 	const char		*fname;	/* Ptr to source file name  */
841 	int			lineno;	/* Source line number.      */
842 };
843 
844 /*
845  * Critical regions can also be detected by looking at the threads
846  * current lock level.  Ensure these macros increment and decrement
847  * the lock levels such that locks can not be held with a lock level
848  * of 0.
849  */
850 #define	THR_IN_CRITICAL(thrd)					\
851 	(((thrd)->locklevel > 0) ||				\
852 	((thrd)->critical_count > 0))
853 
854 #define	THR_YIELD_CHECK(thrd)					\
855 do {								\
856 	if (!THR_IN_CRITICAL(thrd)) {				\
857 		if (__predict_false(_libkse_debug))		\
858 			_thr_debug_check_yield(thrd);		\
859 		if ((thrd)->critical_yield != 0)		\
860 			_thr_sched_switch(thrd);		\
861 		if ((thrd)->check_pending != 0) 		\
862 			_thr_sig_check_pending(thrd);		\
863 	}							\
864 } while (0)
865 
866 #define	THR_LOCK_ACQUIRE(thrd, lck)				\
867 do {								\
868 	if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) {		\
869 		THR_DEACTIVATE_LAST_LOCK(thrd);			\
870 		(thrd)->locklevel++;				\
871 		_lock_acquire((lck),				\
872 		    &(thrd)->lockusers[(thrd)->locklevel - 1],	\
873 		    (thrd)->active_priority);			\
874 	} else 							\
875 		PANIC("Exceeded maximum lock level");		\
876 } while (0)
877 
878 #define	THR_LOCK_RELEASE(thrd, lck)				\
879 do {								\
880 	if ((thrd)->locklevel > 0) {				\
881 		_lock_release((lck),				\
882 		    &(thrd)->lockusers[(thrd)->locklevel - 1]);	\
883 		(thrd)->locklevel--;				\
884 		THR_ACTIVATE_LAST_LOCK(thrd);			\
885 		if ((thrd)->locklevel == 0)			\
886 			THR_YIELD_CHECK(thrd);			\
887 	}							\
888 } while (0)
889 
890 #define THR_ACTIVATE_LAST_LOCK(thrd)					\
891 do {									\
892 	if ((thrd)->locklevel > 0)					\
893 		_lockuser_setactive(					\
894 		    &(thrd)->lockusers[(thrd)->locklevel - 1], 1);	\
895 } while (0)
896 
897 #define	THR_DEACTIVATE_LAST_LOCK(thrd)					\
898 do {									\
899 	if ((thrd)->locklevel > 0)					\
900 		_lockuser_setactive(					\
901 		    &(thrd)->lockusers[(thrd)->locklevel - 1], 0);	\
902 } while (0)
903 
904 /*
905  * For now, threads will have their own lock separate from their
906  * KSE scheduling lock.
907  */
908 #define	THR_LOCK(thr)			THR_LOCK_ACQUIRE(thr, &(thr)->lock)
909 #define	THR_UNLOCK(thr)			THR_LOCK_RELEASE(thr, &(thr)->lock)
910 #define	THR_THREAD_LOCK(curthrd, thr)	THR_LOCK_ACQUIRE(curthrd, &(thr)->lock)
911 #define	THR_THREAD_UNLOCK(curthrd, thr)	THR_LOCK_RELEASE(curthrd, &(thr)->lock)
912 
913 /*
914  * Priority queue manipulation macros (using pqe link).  We use
915  * the thread's kseg link instead of the kse link because a thread
916  * does not (currently) have a statically assigned kse.
917  */
918 #define THR_RUNQ_INSERT_HEAD(thrd)	\
919 	_pq_insert_head(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
920 #define THR_RUNQ_INSERT_TAIL(thrd)	\
921 	_pq_insert_tail(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
922 #define THR_RUNQ_REMOVE(thrd)		\
923 	_pq_remove(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
924 
925 /*
926  * Macros to insert/remove threads to the all thread list and
927  * the gc list.
928  */
929 #define	THR_LIST_ADD(thrd) do {					\
930 	if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) == 0) {	\
931 		TAILQ_INSERT_HEAD(&_thread_list, thrd, tle);	\
932 		_thr_hash_add(thrd);				\
933 		(thrd)->tlflags |= TLFLAGS_IN_TDLIST;		\
934 	}							\
935 } while (0)
936 #define	THR_LIST_REMOVE(thrd) do {				\
937 	if (((thrd)->tlflags & TLFLAGS_IN_TDLIST) != 0) {	\
938 		TAILQ_REMOVE(&_thread_list, thrd, tle);		\
939 		_thr_hash_remove(thrd);				\
940 		(thrd)->tlflags &= ~TLFLAGS_IN_TDLIST;		\
941 	}							\
942 } while (0)
943 #define	THR_GCLIST_ADD(thrd) do {				\
944 	if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) == 0) {	\
945 		TAILQ_INSERT_HEAD(&_thread_gc_list, thrd, gcle);\
946 		(thrd)->tlflags |= TLFLAGS_IN_GCLIST;		\
947 		_gc_count++;					\
948 	}							\
949 } while (0)
950 #define	THR_GCLIST_REMOVE(thrd) do {				\
951 	if (((thrd)->tlflags & TLFLAGS_IN_GCLIST) != 0) {	\
952 		TAILQ_REMOVE(&_thread_gc_list, thrd, gcle);	\
953 		(thrd)->tlflags &= ~TLFLAGS_IN_GCLIST;		\
954 		_gc_count--;					\
955 	}							\
956 } while (0)
957 
958 #define GC_NEEDED()	(atomic_load_acq_int(&_gc_count) >= 5)
959 
960 /*
961  * Locking the scheduling queue for another thread uses that thread's
962  * KSEG lock.
963  */
964 #define	THR_SCHED_LOCK(curthr, thr) do {		\
965 	(curthr)->critical[(curthr)->locklevel] = _kse_critical_enter(); \
966 	(curthr)->locklevel++;				\
967 	KSE_SCHED_LOCK((curthr)->kse, (thr)->kseg);	\
968 } while (0)
969 
970 #define	THR_SCHED_UNLOCK(curthr, thr) do {		\
971 	KSE_SCHED_UNLOCK((curthr)->kse, (thr)->kseg);	\
972 	(curthr)->locklevel--;				\
973 	_kse_critical_leave((curthr)->critical[(curthr)->locklevel]); \
974 } while (0)
975 
976 /* Take the scheduling lock with the intent to call the scheduler. */
977 #define	THR_LOCK_SWITCH(curthr) do {			\
978 	(void)_kse_critical_enter();			\
979 	KSE_SCHED_LOCK((curthr)->kse, (curthr)->kseg);	\
980 } while (0)
981 #define	THR_UNLOCK_SWITCH(curthr) do {			\
982 	KSE_SCHED_UNLOCK((curthr)->kse, (curthr)->kseg);\
983 } while (0)
984 
985 #define	THR_CRITICAL_ENTER(thr)		(thr)->critical_count++
986 #define	THR_CRITICAL_LEAVE(thr)	do {		\
987 	(thr)->critical_count--;		\
988 	if (((thr)->critical_yield != 0) &&	\
989 	    ((thr)->critical_count == 0)) {	\
990 		(thr)->critical_yield = 0;	\
991 		_thr_sched_switch(thr);		\
992 	}					\
993 } while (0)
994 
995 #define	THR_IS_ACTIVE(thrd) \
996 	((thrd)->kse != NULL) && ((thrd)->kse->k_curthread == (thrd))
997 
998 #define	THR_IN_SYNCQ(thrd)	(((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
999 
1000 #define	THR_IS_SUSPENDED(thrd) \
1001 	(((thrd)->state == PS_SUSPENDED) || \
1002 	(((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
1003 #define	THR_IS_EXITING(thrd)	(((thrd)->flags & THR_FLAGS_EXITING) != 0)
1004 #define DBG_CAN_RUN(thrd) (((thrd)->tcb->tcb_tmbx.tm_dflags & \
1005 	TMDF_SUSPEND) == 0)
1006 
1007 extern int __isthreaded;
1008 
1009 static inline int
_kse_isthreaded(void)1010 _kse_isthreaded(void)
1011 {
1012 	return (__isthreaded != 0);
1013 }
1014 
1015 /*
1016  * Global variables for the pthread kernel.
1017  */
1018 
1019 SCLASS void		*_usrstack	SCLASS_PRESET(NULL);
1020 SCLASS struct kse	*_kse_initial	SCLASS_PRESET(NULL);
1021 SCLASS struct pthread	*_thr_initial	SCLASS_PRESET(NULL);
1022 /* For debugger */
1023 SCLASS int		_libkse_debug		SCLASS_PRESET(0);
1024 SCLASS int		_thread_activated	SCLASS_PRESET(0);
1025 SCLASS int		_thread_scope_system	SCLASS_PRESET(0);
1026 
1027 /* List of all threads: */
1028 SCLASS TAILQ_HEAD(, pthread)	_thread_list
1029     SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_list));
1030 
1031 /* List of threads needing GC: */
1032 SCLASS TAILQ_HEAD(, pthread)	_thread_gc_list
1033     SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_gc_list));
1034 
1035 SCLASS int	_thread_active_threads  SCLASS_PRESET(1);
1036 
1037 SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _thr_atfork_list;
1038 SCLASS pthread_mutex_t		_thr_atfork_mutex;
1039 
1040 /* Default thread attributes: */
1041 SCLASS struct pthread_attr _pthread_attr_default
1042     SCLASS_PRESET({
1043 	SCHED_RR, 0, TIMESLICE_USEC, THR_DEFAULT_PRIORITY,
1044 	THR_CREATE_RUNNING,	PTHREAD_CREATE_JOINABLE, NULL,
1045 	NULL, NULL, /* stacksize */0, /* guardsize */0
1046     });
1047 
1048 /* Default mutex attributes: */
1049 SCLASS struct pthread_mutex_attr _pthread_mutexattr_default
1050     SCLASS_PRESET({PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 });
1051 
1052 /* Default condition variable attributes: */
1053 SCLASS struct pthread_cond_attr _pthread_condattr_default
1054     SCLASS_PRESET({COND_TYPE_FAST, 0});
1055 
1056 /* Clock resolution in usec.	*/
1057 SCLASS int		_clock_res_usec		SCLASS_PRESET(CLOCK_RES_USEC);
1058 
1059 /* Array of signal actions for this process: */
1060 SCLASS struct sigaction	_thread_sigact[_SIG_MAXSIG];
1061 
1062 /*
1063  * Lock for above count of dummy handlers and for the process signal
1064  * mask and pending signal sets.
1065  */
1066 SCLASS struct lock	_thread_signal_lock;
1067 
1068 /* Pending signals and mask for this process: */
1069 SCLASS sigset_t		_thr_proc_sigpending;
1070 SCLASS siginfo_t	_thr_proc_siginfo[_SIG_MAXSIG];
1071 
1072 SCLASS pid_t		_thr_pid		SCLASS_PRESET(0);
1073 
1074 /* Garbage collector lock. */
1075 SCLASS struct lock	_gc_lock;
1076 SCLASS int		_gc_check		SCLASS_PRESET(0);
1077 SCLASS int		_gc_count		SCLASS_PRESET(0);
1078 
1079 SCLASS struct lock	_mutex_static_lock;
1080 SCLASS struct lock	_rwlock_static_lock;
1081 SCLASS struct lock	_keytable_lock;
1082 SCLASS struct lock	_thread_list_lock;
1083 SCLASS size_t		_thr_guard_default;
1084 SCLASS size_t		_thr_stack_default;
1085 SCLASS size_t		_thr_stack_initial;
1086 SCLASS int		_thr_page_size;
1087 SCLASS pthread_t	_thr_sig_daemon;
1088 SCLASS int		_thr_debug_flags	SCLASS_PRESET(0);
1089 
1090 /* Undefine the storage class and preset specifiers: */
1091 #undef  SCLASS
1092 #undef	SCLASS_PRESET
1093 
1094 
1095 /*
1096  * Function prototype definitions.
1097  */
1098 __BEGIN_DECLS
1099 int	_cond_reinit(pthread_cond_t *);
1100 struct kse *_kse_alloc(struct pthread *, int sys_scope);
1101 kse_critical_t _kse_critical_enter(void);
1102 void	_kse_critical_leave(kse_critical_t);
1103 int	_kse_in_critical(void);
1104 void	_kse_free(struct pthread *, struct kse *);
1105 void	_kse_init(void);
1106 struct kse_group *_kseg_alloc(struct pthread *);
1107 void	_kse_lock_wait(struct lock *, struct lockuser *lu);
1108 void	_kse_lock_wakeup(struct lock *, struct lockuser *lu);
1109 void	_kse_single_thread(struct pthread *);
1110 int	_kse_setthreaded(int);
1111 void	_kseg_free(struct kse_group *);
1112 int	_mutex_cv_lock(pthread_mutex_t *);
1113 int	_mutex_cv_unlock(pthread_mutex_t *);
1114 void	_mutex_notify_priochange(struct pthread *, struct pthread *, int);
1115 int	_mutex_reinit(struct pthread_mutex *);
1116 void	_mutex_unlock_private(struct pthread *);
1117 void	_libpthread_init(struct pthread *);
1118 int	_pq_alloc(struct pq_queue *, int, int);
1119 void	_pq_free(struct pq_queue *);
1120 int	_pq_init(struct pq_queue *);
1121 void	_pq_remove(struct pq_queue *pq, struct pthread *);
1122 void	_pq_insert_head(struct pq_queue *pq, struct pthread *);
1123 void	_pq_insert_tail(struct pq_queue *pq, struct pthread *);
1124 struct pthread *_pq_first(struct pq_queue *pq);
1125 struct pthread *_pq_first_debug(struct pq_queue *pq);
1126 void	*_pthread_getspecific(pthread_key_t);
1127 int	_pthread_key_create(pthread_key_t *, void (*) (void *));
1128 int	_pthread_key_delete(pthread_key_t);
1129 int	_pthread_mutex_destroy(pthread_mutex_t *);
1130 int	_pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
1131 int	_pthread_mutex_lock(pthread_mutex_t *);
1132 int	_pthread_mutex_trylock(pthread_mutex_t *);
1133 int	_pthread_mutex_unlock(pthread_mutex_t *);
1134 int	_pthread_mutexattr_init(pthread_mutexattr_t *);
1135 int	_pthread_mutexattr_destroy(pthread_mutexattr_t *);
1136 int	_pthread_mutexattr_settype(pthread_mutexattr_t *, int);
1137 int	_pthread_once(pthread_once_t *, void (*) (void));
1138 int	_pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *);
1139 int	_pthread_rwlock_destroy (pthread_rwlock_t *);
1140 struct pthread *_pthread_self(void);
1141 int	_pthread_setspecific(pthread_key_t, const void *);
1142 void	_pthread_yield(void);
1143 void	_pthread_cleanup_push(void (*routine) (void *), void *routine_arg);
1144 void	_pthread_cleanup_pop(int execute);
1145 struct pthread *_thr_alloc(struct pthread *);
1146 void	_thr_exit(const char *, int, const char *) __dead2;
1147 void	_thr_exit_cleanup(void);
1148 void	_thr_lock_wait(struct lock *lock, struct lockuser *lu);
1149 void	_thr_lock_wakeup(struct lock *lock, struct lockuser *lu);
1150 void	_thr_mutex_reinit(pthread_mutex_t *);
1151 int	_thr_ref_add(struct pthread *, struct pthread *, int);
1152 void	_thr_ref_delete(struct pthread *, struct pthread *);
1153 void	_thr_rtld_init(void);
1154 void	_thr_rtld_fini(void);
1155 int	_thr_schedule_add(struct pthread *, struct pthread *);
1156 void	_thr_schedule_remove(struct pthread *, struct pthread *);
1157 void	_thr_setrunnable(struct pthread *curthread, struct pthread *thread);
1158 struct kse_mailbox *_thr_setrunnable_unlocked(struct pthread *thread);
1159 struct kse_mailbox *_thr_sig_add(struct pthread *, int, siginfo_t *);
1160 void	_thr_sig_dispatch(struct kse *, int, siginfo_t *);
1161 int	_thr_stack_alloc(struct pthread_attr *);
1162 void	_thr_stack_free(struct pthread_attr *);
1163 void    _thr_exit_cleanup(void);
1164 void	_thr_free(struct pthread *, struct pthread *);
1165 void	_thr_gc(struct pthread *);
1166 void    _thr_panic_exit(char *, int, char *);
1167 void    _thread_cleanupspecific(void);
1168 void    _thread_dump_info(void);
1169 void	_thread_printf(int, const char *, ...);
1170 void	_thr_sched_switch(struct pthread *);
1171 void	_thr_sched_switch_unlocked(struct pthread *);
1172 void    _thr_set_timeout(const struct timespec *);
1173 void	_thr_seterrno(struct pthread *, int);
1174 void    _thr_sig_handler(int, siginfo_t *, void *);
1175 void    _thr_sig_check_pending(struct pthread *);
1176 void	_thr_sig_rundown(struct pthread *, ucontext_t *);
1177 void	_thr_sig_send(struct pthread *pthread, int sig);
1178 void	_thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
1179 void	_thr_spinlock_init(void);
1180 void	_thr_cancel_enter(struct pthread *);
1181 void	_thr_cancel_leave(struct pthread *, int);
1182 int	_thr_setconcurrency(int new_level);
1183 int	_thr_setmaxconcurrency(void);
1184 void	_thr_critical_enter(struct pthread *);
1185 void	_thr_critical_leave(struct pthread *);
1186 int	_thr_start_sig_daemon(void);
1187 int	_thr_getprocsig(int sig, siginfo_t *siginfo);
1188 int	_thr_getprocsig_unlocked(int sig, siginfo_t *siginfo);
1189 void	_thr_signal_init(void);
1190 void	_thr_signal_deinit(void);
1191 void	_thr_hash_add(struct pthread *);
1192 void	_thr_hash_remove(struct pthread *);
1193 struct pthread *_thr_hash_find(struct pthread *);
1194 void	_thr_finish_cancellation(void *arg);
1195 int	_thr_sigonstack(void *sp);
1196 void	_thr_debug_check_yield(struct pthread *);
1197 
1198 /*
1199  * Aliases for _pthread functions. Should be called instead of
1200  * originals if PLT replocation is unwanted at runtme.
1201  */
1202 int	_thr_cond_broadcast(pthread_cond_t *);
1203 int	_thr_cond_signal(pthread_cond_t *);
1204 int	_thr_cond_wait(pthread_cond_t *, pthread_mutex_t *);
1205 int	_thr_mutex_lock(pthread_mutex_t *);
1206 int	_thr_mutex_unlock(pthread_mutex_t *);
1207 int	_thr_rwlock_rdlock (pthread_rwlock_t *);
1208 int	_thr_rwlock_wrlock (pthread_rwlock_t *);
1209 int	_thr_rwlock_unlock (pthread_rwlock_t *);
1210 
1211 /* #include <sys/aio.h> */
1212 #ifdef _SYS_AIO_H_
1213 int	__sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
1214 #endif
1215 
1216 /* #include <fcntl.h> */
1217 #ifdef  _SYS_FCNTL_H_
1218 int     __sys_fcntl(int, int, ...);
1219 int     __sys_open(const char *, int, ...);
1220 #endif
1221 
1222 /* #include <sys/ioctl.h> */
1223 #ifdef _SYS_IOCTL_H_
1224 int	__sys_ioctl(int, unsigned long, ...);
1225 #endif
1226 
1227 /* #inclde <sched.h> */
1228 #ifdef	_SCHED_H_
1229 int	__sys_sched_yield(void);
1230 #endif
1231 
1232 /* #include <signal.h> */
1233 #ifdef _SIGNAL_H_
1234 int	__sys_kill(pid_t, int);
1235 int     __sys_sigaction(int, const struct sigaction *, struct sigaction *);
1236 int     __sys_sigpending(sigset_t *);
1237 int     __sys_sigprocmask(int, const sigset_t *, sigset_t *);
1238 int     __sys_sigsuspend(const sigset_t *);
1239 int     __sys_sigreturn(ucontext_t *);
1240 int     __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
1241 #endif
1242 
1243 /* #include <sys/socket.h> */
1244 #ifdef _SYS_SOCKET_H_
1245 int	__sys_accept(int, struct sockaddr *, socklen_t *);
1246 int	__sys_connect(int, const struct sockaddr *, socklen_t);
1247 int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
1248 	    off_t *, int);
1249 #endif
1250 
1251 /* #include <sys/uio.h> */
1252 #ifdef  _SYS_UIO_H_
1253 ssize_t __sys_readv(int, const struct iovec *, int);
1254 ssize_t __sys_writev(int, const struct iovec *, int);
1255 #endif
1256 
1257 /* #include <time.h> */
1258 #ifdef	_TIME_H_
1259 int	__sys_nanosleep(const struct timespec *, struct timespec *);
1260 #endif
1261 
1262 /* #include <unistd.h> */
1263 #ifdef  _UNISTD_H_
1264 int     __sys_close(int);
1265 int     __sys_execve(const char *, char * const *, char * const *);
1266 int	__sys_fork(void);
1267 int	__sys_fsync(int);
1268 pid_t	__sys_getpid(void);
1269 int     __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
1270 ssize_t __sys_read(int, void *, size_t);
1271 ssize_t __sys_write(int, const void *, size_t);
1272 void	__sys_exit(int);
1273 int	__sys_sigwait(const sigset_t *, int *);
1274 int	__sys_sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *);
1275 #endif
1276 
1277 /* #include <poll.h> */
1278 #ifdef _SYS_POLL_H_
1279 int 	__sys_poll(struct pollfd *, unsigned, int);
1280 #endif
1281 
1282 /* #include <sys/mman.h> */
1283 #ifdef _SYS_MMAN_H_
1284 int	__sys_msync(void *, size_t, int);
1285 #endif
1286 
1287 static __inline int
_thr_dump_enabled(void)1288 _thr_dump_enabled(void)
1289 {
1290 
1291 	return ((_thr_debug_flags & DBG_INFO_DUMP) != 0);
1292 }
1293 
1294 #endif  /* !_THR_PRIVATE_H */
1295