Home | History | Annotate | Download | only in inc
      1      0  stevel /*
      2      0  stevel  * CDDL HEADER START
      3      0  stevel  *
      4      0  stevel  * The contents of this file are subject to the terms of the
      5   1885     raf  * Common Development and Distribution License (the "License").
      6   1885     raf  * You may not use this file except in compliance with the License.
      7      0  stevel  *
      8      0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0  stevel  * or http://www.opensolaris.org/os/licensing.
     10      0  stevel  * See the License for the specific language governing permissions
     11      0  stevel  * and limitations under the License.
     12      0  stevel  *
     13      0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0  stevel  *
     19      0  stevel  * CDDL HEADER END
     20      0  stevel  */
     21   1016     raf 
     22      0  stevel /*
     23   9170   Roger  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24      0  stevel  * Use is subject to license terms.
     25      0  stevel  */
     26      0  stevel 
     27      0  stevel #ifndef _THR_UBERDATA_H
     28      0  stevel #define	_THR_UBERDATA_H
     29      0  stevel 
     30      0  stevel #include <stdlib.h>
     31      0  stevel #include <unistd.h>
     32      0  stevel #include <sys/types.h>
     33      0  stevel #include <fcntl.h>
     34      0  stevel #include <string.h>
     35      0  stevel #include <signal.h>
     36      0  stevel #include <ucontext.h>
     37      0  stevel #include <thread.h>
     38      0  stevel #include <pthread.h>
     39   6812     raf #include <atomic.h>
     40      0  stevel #include <link.h>
     41      0  stevel #include <sys/resource.h>
     42      0  stevel #include <sys/lwp.h>
     43      0  stevel #include <errno.h>
     44      0  stevel #include <sys/asm_linkage.h>
     45      0  stevel #include <sys/regset.h>
     46      0  stevel #include <sys/fcntl.h>
     47      0  stevel #include <sys/mman.h>
     48      0  stevel #include <synch.h>
     49      0  stevel #include <door.h>
     50      0  stevel #include <limits.h>
     51      0  stevel #include <sys/synch32.h>
     52      0  stevel #include <schedctl.h>
     53      0  stevel #include <sys/priocntl.h>
     54      0  stevel #include <thread_db.h>
     55   2248     raf #include <setjmp.h>
     56      0  stevel #include "libc_int.h"
     57      0  stevel #include "tdb_agent.h"
     58   2248     raf #include "thr_debug.h"
     59      0  stevel 
     60      0  stevel /*
     61      0  stevel  * This is an implementation-specific include file for threading support.
     62      0  stevel  * It is not to be seen by the clients of the library.
     63      0  stevel  *
     64      0  stevel  * This file also describes uberdata in libc.
     65      0  stevel  *
     66      0  stevel  * The term "uberdata" refers to data that is unique and visible across
     67      0  stevel  * all link maps.  The name is meant to imply that such data is truly
     68      0  stevel  * global, not just locally global to a particular link map.
     69      0  stevel  *
     70      0  stevel  * See the Linker and Libraries Guide for a full description of alternate
     71      0  stevel  * link maps and how they are set up and used.
     72      0  stevel  *
     73      0  stevel  * Alternate link maps implement multiple global namespaces within a single
     74      0  stevel  * process.  There may be multiple instances of identical dynamic libraries
     75      0  stevel  * loaded in a process's address space at the same time, each on a different
     76      0  stevel  * link map (as determined by the dynamic linker), each with its own set of
     77      0  stevel  * global variables.  Which particular instance of a global variable is seen
     78      0  stevel  * by a thread running in the process is determined by the link map on which
     79      0  stevel  * the thread happens to be executing at the time.
     80      0  stevel  *
     81      0  stevel  * However, there are aspects of a process that are unique across all
     82      0  stevel  * link maps, in particular the structures used to implement threads
     83      0  stevel  * of control (in Sparc terminology, there is only one %g7 regardless
     84      0  stevel  * of the link map on which the thread is executing).
     85      0  stevel  *
     86      0  stevel  * All uberdata is referenced from a base pointer in the thread's ulwp_t
     87      0  stevel  * structure (which is also uberdata).  All allocations and deallocations
     88      0  stevel  * of uberdata are made via the uberdata-aware lmalloc() and lfree()
     89      0  stevel  * interfaces (malloc() and free() are simply locally-global).
     90      0  stevel  */
     91      0  stevel 
     92      0  stevel /*
     93      0  stevel  * Special libc-private access to errno.
     94      0  stevel  * We do this so that references to errno do not invoke the dynamic linker.
     95      0  stevel  */
     96      0  stevel #undef errno
     97      0  stevel #define	errno (*curthread->ul_errnop)
     98      0  stevel 
     99      0  stevel /*
    100      0  stevel  * See <sys/synch32.h> for the reasons for these values
    101      0  stevel  * and why they are different for sparc and intel.
    102      0  stevel  */
    103      0  stevel #if defined(__sparc)
    104   6057     raf 
    105      0  stevel /* lock.lock64.pad[x]	   4 5 6 7 */
    106      0  stevel #define	LOCKMASK	0xff000000
    107      0  stevel #define	WAITERMASK	0x000000ff
    108   5629     raf #define	SPINNERMASK	0x00ff0000
    109   5629     raf #define	SPINNERSHIFT	16
    110      0  stevel #define	WAITER		0x00000001
    111      0  stevel #define	LOCKSET		0xff
    112      0  stevel #define	LOCKCLEAR	0
    113   6057     raf 
    114   6057     raf #define	PIDSHIFT	32
    115   6057     raf #define	LOCKMASK64	0xffffffffff000000ULL
    116   6057     raf #define	LOCKBYTE64	0x00000000ff000000ULL
    117   6057     raf #define	WAITERMASK64	0x00000000000000ffULL
    118   6057     raf #define	SPINNERMASK64	0x0000000000ff0000ULL
    119   6057     raf 
    120   1016     raf #elif defined(__x86)
    121   6057     raf 
    122      0  stevel /* lock.lock64.pad[x]	   7 6 5 4 */
    123      0  stevel #define	LOCKMASK	0xff000000
    124      0  stevel #define	WAITERMASK	0x00ff0000
    125   5629     raf #define	SPINNERMASK	0x0000ff00
    126   5629     raf #define	SPINNERSHIFT	8
    127      0  stevel #define	WAITER		0x00010000
    128      0  stevel #define	LOCKSET		0x01
    129      0  stevel #define	LOCKCLEAR	0
    130   6057     raf 
    131   6057     raf #define	PIDSHIFT	0
    132   6057     raf #define	LOCKMASK64	0xff000000ffffffffULL
    133   6057     raf #define	LOCKBYTE64	0x0100000000000000ULL
    134   6057     raf #define	WAITERMASK64	0x00ff000000000000ULL
    135   6057     raf #define	SPINNERMASK64	0x0000ff0000000000ULL
    136   6057     raf 
    137      0  stevel #else
    138   1016     raf #error "neither __sparc nor __x86 is defined"
    139      0  stevel #endif
    140      0  stevel 
    141      0  stevel /*
    142      0  stevel  * Fetch the owner of a USYNC_THREAD mutex.
    143      0  stevel  * Don't use this with process-shared mutexes;
    144      0  stevel  * the owing thread may be in a different process.
    145      0  stevel  */
    146      0  stevel #define	MUTEX_OWNER(mp)	((ulwp_t *)(uintptr_t)(mp)->mutex_owner)
    147      0  stevel 
    148      0  stevel /*
    149   4574     raf  * Test if a thread owns a process-private (USYNC_THREAD) mutex.
    150   4574     raf  * This is inappropriate for a process-shared (USYNC_PROCESS) mutex.
    151      0  stevel  * The 'mp' argument must not have side-effects since it is evaluated twice.
    152      0  stevel  */
    153      0  stevel #define	MUTEX_OWNED(mp, thrp)	\
    154      0  stevel 	((mp)->mutex_lockw != 0 && MUTEX_OWNER(mp) == thrp)
    155      0  stevel 
    156      0  stevel 
    157      0  stevel /*
    158      0  stevel  * uberflags.uf_tdb_register_sync is an interface with libc_db to enable the
    159      0  stevel  * collection of lock statistics by a debugger or other collecting tool.
    160      0  stevel  *
    161      0  stevel  * uberflags.uf_thread_error_detection is set by an environment variable:
    162      0  stevel  *	_THREAD_ERROR_DETECTION
    163      0  stevel  *		0 == no detection of locking primitive errors.
    164      0  stevel  *		1 == detect errors and issue a warning message.
    165      0  stevel  *		2 == detect errors, issue a warning message, and dump core.
    166      0  stevel  *
    167      0  stevel  * We bundle these together in uberflags.uf_trs_ted to make a test of either
    168      0  stevel  * being non-zero a single memory reference (for speed of mutex_lock(), etc).
    169      0  stevel  *
    170      0  stevel  * uberflags.uf_mt is set non-zero when the first thread (in addition
    171      0  stevel  * to the main thread) is created.
    172      0  stevel  *
    173      0  stevel  * We bundle all these flags together in uberflags.uf_all to make a test
    174      0  stevel  * of any being non-zero a single memory reference (again, for speed).
    175      0  stevel  */
    176      0  stevel typedef union {
    177      0  stevel 	int	uf_all;			/* combined all flags */
    178      0  stevel 	struct {
    179      0  stevel 		short	h_pad;
    180      0  stevel 		short	h_trs_ted;	/* combined reg sync & error detect */
    181      0  stevel 	} uf_h;
    182      0  stevel 	struct {
    183      0  stevel 		char	x_mt;
    184      0  stevel 		char	x_pad;
    185      0  stevel 		char	x_tdb_register_sync;
    186      0  stevel 		char	x_thread_error_detection;
    187      0  stevel 	} uf_x;
    188      0  stevel } uberflags_t;
    189      0  stevel 
    190      0  stevel #define	uf_mt				uf_x.x_mt
    191      0  stevel #define	uf_tdb_register_sync		uf_x.x_tdb_register_sync
    192      0  stevel #define	uf_thread_error_detection	uf_x.x_thread_error_detection
    193      0  stevel #define	uf_trs_ted			uf_h.h_trs_ted	/* both of the above */
    194      0  stevel 
    195      0  stevel /*
    196      0  stevel  * NOTE WELL:
    197      0  stevel  * To enable further optimization, the "ul_schedctl_called" member
    198      0  stevel  * of the ulwp_t structure (below) serves double-duty:
    199      0  stevel  *	1. If NULL, it means that the thread must call __schedctl()
    200      0  stevel  *	   to set up its schedctl mappings before acquiring a mutex.
    201      0  stevel  *	   This is required by the implementation of adaptive mutex locking.
    202      0  stevel  *	2. If non-NULL, it points to uberdata.uberflags, so that tests of
    203      0  stevel  *	   uberflags can be made without additional memory references.
    204      0  stevel  * This allows the common case of _mutex_lock() and _mutex_unlock() for
    205      0  stevel  * USYNC_THREAD mutexes with no error detection and no lock statistics
    206      0  stevel  * to be optimized for speed.
    207      0  stevel  */
    208      0  stevel 
    209      0  stevel /* double the default stack size for 64-bit processes */
    210      0  stevel #ifdef _LP64
    211      0  stevel #define	MINSTACK	(8 * 1024)
    212      0  stevel #define	DEFAULTSTACK	(2 * 1024 * 1024)
    213      0  stevel #else
    214      0  stevel #define	MINSTACK	(4 * 1024)
    215      0  stevel #define	DEFAULTSTACK	(1024 * 1024)
    216      0  stevel #endif
    217      0  stevel 
    218      0  stevel #define	MUTEX_TRY	0
    219      0  stevel #define	MUTEX_LOCK	1
    220   6247     raf #define	MUTEX_NOCEIL	0x40
    221      0  stevel 
    222   1016     raf #if defined(__x86)
    223      0  stevel 
    224      0  stevel typedef struct {	/* structure returned by fnstenv */
    225      0  stevel 	int	fctrl;		/* control word */
    226      0  stevel 	int	fstat;		/* status word (flags, etc) */
    227      0  stevel 	int	ftag;		/* tag of which regs busy */
    228      0  stevel 	int	misc[4];	/* other stuff, 28 bytes total */
    229      0  stevel } fpuenv_t;
    230      0  stevel 
    231      0  stevel #ifdef _SYSCALL32
    232      0  stevel typedef fpuenv_t fpuenv32_t;
    233      0  stevel #endif	/* _SYSCALL32 */
    234      0  stevel 
    235      0  stevel #elif defined(__sparc)
    236      0  stevel 
    237      0  stevel typedef struct {	/* fp state structure */
    238      0  stevel 	greg_t	fsr;
    239      0  stevel 	greg_t	fpu_en;
    240      0  stevel } fpuenv_t;
    241      0  stevel 
    242      0  stevel #ifdef _SYSCALL32
    243      0  stevel typedef struct {
    244      0  stevel 	greg32_t	fsr;
    245      0  stevel 	greg32_t	fpu_en;
    246      0  stevel } fpuenv32_t;
    247      0  stevel #endif	/* _SYSCALL32 */
    248      0  stevel 
    249   1016     raf #endif	/* __x86 */
    250      0  stevel 
    251   1016     raf #if defined(__x86)
    252      0  stevel extern	void	ht_pause(void);		/* "pause" instruction */
    253      0  stevel #define	SMT_PAUSE()	ht_pause()
    254   9202   Jason #elif defined(SMT_PAUSE_FUNCTION)
    255   9202   Jason extern	void	SMT_PAUSE_FUNCTION(void);
    256   9202   Jason #define	SMT_PAUSE()	SMT_PAUSE_FUNCTION()
    257      0  stevel #else
    258      0  stevel #define	SMT_PAUSE()
    259   1016     raf #endif	/* __x86 */
    260      0  stevel 
    261      0  stevel /*
    262      0  stevel  * Cleanup handler related data.
    263      0  stevel  * This structure is exported as _cleanup_t in pthread.h.
    264      0  stevel  * pthread.h exports only the size of this structure, so check
    265      0  stevel  * _cleanup_t in pthread.h before making any change here.
    266      0  stevel  */
    267      0  stevel typedef struct __cleanup {
    268      0  stevel 	struct __cleanup *next;		/* pointer to next handler */
    269      0  stevel 	caddr_t	fp;			/* current frame pointer */
    270      0  stevel 	void	(*func)(void *);	/* cleanup handler address */
    271      0  stevel 	void	*arg;			/* handler's argument */
    272      0  stevel } __cleanup_t;
    273      0  stevel 
    274      0  stevel /*
    275      0  stevel  * Thread-Specific Data (TSD)
    276      0  stevel  * TSD_NFAST includes the invalid key zero, so there
    277      0  stevel  * are really only (TSD_NFAST - 1) fast key slots.
    278      0  stevel  */
    279      0  stevel typedef	void (*PFrV)(void *);
    280      0  stevel #define	TSD_UNALLOCATED	((PFrV)1)
    281      0  stevel #define	TSD_NFAST	9
    282      0  stevel 
    283      0  stevel /*
    284      0  stevel  * The tsd union is designed to burn a little memory (9 words) to make
    285      0  stevel  * lookups blindingly fast.  Note that tsd_nalloc could be placed at the
    286      0  stevel  * end of the pad region to increase the likelihood that it falls on the
    287      0  stevel  * same cache line as the data.
    288      0  stevel  */
    289      0  stevel typedef union tsd {
    290      0  stevel 	uint_t tsd_nalloc;		/* Amount of allocated storage */
    291      0  stevel 	void *tsd_pad[TSD_NFAST];
    292      0  stevel 	void *tsd_data[1];
    293      0  stevel } tsd_t;
    294      0  stevel 
    295      0  stevel typedef struct {
    296      0  stevel 	mutex_t tsdm_lock;		/* Lock protecting the data */
    297      0  stevel 	uint_t tsdm_nkeys;		/* Number of allocated keys */
    298      0  stevel 	uint_t tsdm_nused;		/* Number of used keys */
    299      0  stevel 	PFrV *tsdm_destro;		/* Per-key destructors */
    300      0  stevel 	char tsdm_pad[64 -		/* pad to 64 bytes */
    301      0  stevel 		(sizeof (mutex_t) + 2 * sizeof (uint_t) + sizeof (PFrV *))];
    302      0  stevel } tsd_metadata_t;
    303      0  stevel 
    304      0  stevel #ifdef _SYSCALL32
    305      0  stevel typedef union tsd32 {
    306      0  stevel 	uint_t tsd_nalloc;		/* Amount of allocated storage */
    307      0  stevel 	caddr32_t tsd_pad[TSD_NFAST];
    308      0  stevel 	caddr32_t tsd_data[1];
    309      0  stevel } tsd32_t;
    310      0  stevel 
    311      0  stevel typedef struct {
    312      0  stevel 	mutex_t tsdm_lock;		/* Lock protecting the data */
    313      0  stevel 	uint_t tsdm_nkeys;		/* Number of allocated keys */
    314      0  stevel 	uint_t tsdm_nused;		/* Number of used keys */
    315      0  stevel 	caddr32_t tsdm_destro;		/* Per-key destructors */
    316      0  stevel 	char tsdm_pad[64 -		/* pad to 64 bytes */
    317      0  stevel 		(sizeof (mutex_t) + 2 * sizeof (uint_t) + sizeof (caddr32_t))];
    318      0  stevel } tsd_metadata32_t;
    319      0  stevel #endif	/* _SYSCALL32 */
    320      0  stevel 
    321      0  stevel 
    322      0  stevel /*
    323      0  stevel  * Thread-Local Storage (TLS)
    324      0  stevel  */
    325      0  stevel typedef struct {
    326      0  stevel 	void		*tls_data;
    327      0  stevel 	size_t		tls_size;
    328      0  stevel } tls_t;
    329      0  stevel 
    330      0  stevel typedef struct {
    331      0  stevel 	mutex_t	tls_lock;		/* Lock protecting the data */
    332      0  stevel 	tls_t	tls_modinfo;		/* Root of all TLS_modinfo data */
    333      0  stevel 	tls_t	static_tls;		/* Template for static TLS */
    334      0  stevel 	char	tls_pad[64 -		/* pad to 64 bytes */
    335      0  stevel 		(sizeof (mutex_t) + 2 * sizeof (tls_t))];
    336      0  stevel } tls_metadata_t;
    337      0  stevel 
    338      0  stevel #ifdef _SYSCALL32
    339      0  stevel typedef struct {
    340      0  stevel 	caddr32_t	tls_data;
    341      0  stevel 	size32_t	tls_size;
    342      0  stevel } tls32_t;
    343      0  stevel 
    344      0  stevel typedef struct {
    345      0  stevel 	mutex_t	tls_lock;		/* Lock protecting the data */
    346      0  stevel 	tls32_t	tls_modinfo;		/* Root of all TLS_modinfo data */
    347      0  stevel 	tls32_t	static_tls;		/* Template for static TLS */
    348      0  stevel 	char	tls_pad[64 -		/* pad to 64 bytes */
    349      0  stevel 		(sizeof (mutex_t) + 2 * sizeof (tls32_t))];
    350      0  stevel } tls_metadata32_t;
    351      0  stevel #endif	/* _SYSCALL32 */
    352      0  stevel 
    353      0  stevel 
    354      0  stevel /*
    355   6247     raf  * Sleep queue root for USYNC_THREAD condvars and mutexes.
    356   6247     raf  * There is a default queue root for each queue head (see below).
    357   6247     raf  * Also, each ulwp_t contains a queue root that can be used
    358   6247     raf  * when the thread is enqueued on the queue, if necessary
    359   6247     raf  * (when more than one wchan hashes to the same queue head).
    360   6247     raf  */
    361   6247     raf typedef struct queue_root {
    362   6247     raf 	struct queue_root	*qr_next;
    363   6247     raf 	struct queue_root	*qr_prev;
    364   6247     raf 	struct ulwp		*qr_head;
    365   6247     raf 	struct ulwp		*qr_tail;
    366   6247     raf 	void			*qr_wchan;
    367   6247     raf 	uint32_t		qr_rtcount;
    368   6247     raf 	uint32_t		qr_qlen;
    369   6247     raf 	uint32_t		qr_qmax;
    370   6247     raf } queue_root_t;
    371   6247     raf 
    372   6247     raf #ifdef _SYSCALL32
    373   6247     raf typedef struct queue_root32 {
    374   6247     raf 	caddr32_t		qr_next;
    375   6247     raf 	caddr32_t		qr_prev;
    376   6247     raf 	caddr32_t		qr_head;
    377   6247     raf 	caddr32_t		qr_tail;
    378   6247     raf 	caddr32_t		qr_wchan;
    379   6247     raf 	uint32_t		qr_rtcount;
    380   6247     raf 	uint32_t		qr_qlen;
    381   6247     raf 	uint32_t		qr_qmax;
    382   6247     raf } queue_root32_t;
    383   6247     raf #endif
    384   6247     raf 
    385   6247     raf /*
    386   6247     raf  * Sleep queue heads for USYNC_THREAD condvars and mutexes.
    387   6247     raf  * The size and alignment is 128 bytes to reduce cache conflicts.
    388   6247     raf  * Each queue head points to a list of queue roots, defined above.
    389   6247     raf  * Each queue head contains a default queue root for use when only one
    390   6247     raf  * is needed.  It is always at the tail of the queue root hash chain.
    391      0  stevel  */
    392      0  stevel typedef union {
    393   6247     raf 	uint64_t		qh_64[16];
    394      0  stevel 	struct {
    395      0  stevel 		mutex_t		q_lock;
    396      0  stevel 		uint8_t		q_qcnt;
    397   6247     raf 		uint8_t		q_type;		/* MX or CV */
    398   6247     raf 		uint8_t		q_pad1[2];
    399   6247     raf 		uint32_t	q_lockcount;
    400      0  stevel 		uint32_t	q_qlen;
    401      0  stevel 		uint32_t	q_qmax;
    402   6247     raf 		void		*q_wchan;	/* valid only while locked */
    403   6247     raf 		struct queue_root *q_root;	/* valid only while locked */
    404   6247     raf 		struct queue_root *q_hlist;
    405   6247     raf #if !defined(_LP64)
    406   6247     raf 		caddr_t		q_pad2[3];
    407   6247     raf #endif
    408   6247     raf 		queue_root_t	q_def_root;
    409   6247     raf 		uint32_t	q_hlen;
    410   6247     raf 		uint32_t	q_hmax;
    411      0  stevel 	} qh_qh;
    412      0  stevel } queue_head_t;
    413      0  stevel 
    414      0  stevel #define	qh_lock		qh_qh.q_lock
    415      0  stevel #define	qh_qcnt		qh_qh.q_qcnt
    416   6247     raf #define	qh_type		qh_qh.q_type
    417   6247     raf #if defined(THREAD_DEBUG)
    418      0  stevel #define	qh_lockcount	qh_qh.q_lockcount
    419      0  stevel #define	qh_qlen		qh_qh.q_qlen
    420      0  stevel #define	qh_qmax		qh_qh.q_qmax
    421   6247     raf #endif
    422   6247     raf #define	qh_wchan	qh_qh.q_wchan
    423   6247     raf #define	qh_root		qh_qh.q_root
    424   6247     raf #define	qh_hlist	qh_qh.q_hlist
    425   6247     raf #define	qh_def_root	qh_qh.q_def_root
    426   6247     raf #define	qh_hlen		qh_qh.q_hlen
    427   6247     raf #define	qh_hmax		qh_qh.q_hmax
    428      0  stevel 
    429   6247     raf /* queue types passed to queue_lock() */
    430      0  stevel #define	MX	0
    431      0  stevel #define	CV	1
    432   4574     raf #define	QHASHSHIFT	9			/* number of hashing bits */
    433   4574     raf #define	QHASHSIZE	(1 << QHASHSHIFT)	/* power of 2 (1<<9 == 512) */
    434   4574     raf #define	QUEUE_HASH(wchan, type)	((uint_t)			\
    435   4574     raf 	((((uintptr_t)(wchan) >> 3)				\
    436   4574     raf 	^ ((uintptr_t)(wchan) >> (QHASHSHIFT + 3)))		\
    437      0  stevel 	& (QHASHSIZE - 1)) + (((type) == MX)? 0 : QHASHSIZE))
    438      0  stevel 
    439      0  stevel extern	queue_head_t	*queue_lock(void *, int);
    440      0  stevel extern	void		queue_unlock(queue_head_t *);
    441   6247     raf extern	void		enqueue(queue_head_t *, struct ulwp *, int);
    442   6247     raf extern	struct ulwp	*dequeue(queue_head_t *, int *);
    443   6247     raf extern	struct ulwp	**queue_slot(queue_head_t *, struct ulwp **, int *);
    444   6247     raf extern	struct ulwp	*queue_waiter(queue_head_t *);
    445   6247     raf extern	int		dequeue_self(queue_head_t *);
    446   6247     raf extern	void		queue_unlink(queue_head_t *,
    447   4570     raf 				struct ulwp **, struct ulwp *);
    448      0  stevel extern	void		unsleep_self(void);
    449      0  stevel extern	void		spin_lock_set(mutex_t *);
    450      0  stevel extern	void		spin_lock_clear(mutex_t *);
    451   6247     raf 
    452   6247     raf /*
    453   6247     raf  * Scheduling class information structure.
    454   6247     raf  */
    455   6247     raf typedef struct {
    456   6247     raf 	short		pcc_state;
    457   6247     raf 	short		pcc_policy;
    458   6247     raf 	pri_t		pcc_primin;
    459   6247     raf 	pri_t		pcc_primax;
    460   6247     raf 	pcinfo_t	pcc_info;
    461   6247     raf } pcclass_t;
    462      0  stevel 
    463      0  stevel /*
    464      0  stevel  * Memory block for chain of owned ceiling mutexes.
    465      0  stevel  */
    466      0  stevel typedef struct mxchain {
    467      0  stevel 	struct mxchain	*mxchain_next;
    468      0  stevel 	mutex_t		*mxchain_mx;
    469      0  stevel } mxchain_t;
    470      0  stevel 
    471      0  stevel /*
    472      0  stevel  * Pointer to an rwlock that is held for reading.
    473      0  stevel  * Used in rw_rdlock() to allow a thread that already holds a read
    474      0  stevel  * lock to acquire another read lock on the same rwlock even if
    475      0  stevel  * there are writers waiting.  This to avoid deadlock when acquiring
    476      0  stevel  * a read lock more than once in the presence of pending writers.
    477      0  stevel  * POSIX mandates this behavior.
    478      0  stevel  */
    479      0  stevel typedef struct {
    480      0  stevel 	void	*rd_rwlock;	/* the rwlock held for reading */
    481      0  stevel 	size_t	rd_count;	/* count of read locks applied */
    482      0  stevel } readlock_t;
    483      0  stevel 
    484      0  stevel #ifdef _SYSCALL32
    485      0  stevel typedef struct {
    486      0  stevel 	caddr32_t	rd_rwlock;
    487      0  stevel 	size32_t	rd_count;
    488      0  stevel } readlock32_t;
    489      0  stevel #endif	/* _SYSCALL32 */
    490      0  stevel 
    491      0  stevel /*
    492      0  stevel  * Maximum number of read locks allowed for one thread on one rwlock.
    493      0  stevel  * This could be as large as INT_MAX, but the SUSV3 test suite would
    494      0  stevel  * take an inordinately long time to complete.  This is big enough.
    495      0  stevel  */
    496      0  stevel #define	READ_LOCK_MAX	100000
    497      0  stevel 
    498      0  stevel #define	ul_tlsent	ul_tls.tls_data	/* array of pointers to dynamic TLS */
    499      0  stevel #define	ul_ntlsent	ul_tls.tls_size	/* number of entries in ul_tlsent */
    500      0  stevel 
    501      0  stevel /*
    502      0  stevel  * Round up an integral value to a multiple of 64
    503      0  stevel  */
    504      0  stevel #define	roundup64(x)	(-(-(x) & -64))
    505      0  stevel 
    506      0  stevel /*
    507      0  stevel  * NOTE:  Whatever changes are made to ulwp_t must be
    508      0  stevel  * reflected in $SRC/cmd/mdb/common/modules/libc/libc.c
    509      0  stevel  *
    510      0  stevel  * NOTE: ul_self *must* be the first member of ulwp_t on x86
    511      0  stevel  * Low-level x86 code relies on this.
    512      0  stevel  */
    513      0  stevel typedef struct ulwp {
    514      0  stevel 	/*
    515      0  stevel 	 * These members always need to come first on sparc.
    516      0  stevel 	 * For dtrace, a ulwp_t must be aligned on a 64-byte boundary.
    517      0  stevel 	 */
    518      0  stevel #if defined(__sparc)
    519      0  stevel 	uint32_t	ul_dinstr;	/* scratch space for dtrace */
    520      0  stevel 	uint32_t	ul_padsparc0[15];
    521      0  stevel 	uint32_t	ul_dsave;	/* dtrace: save %g1, %g0, %sp */
    522      0  stevel 	uint32_t	ul_drestore;	/* dtrace: restore %g0, %g0, %g0 */
    523      0  stevel 	uint32_t	ul_dftret;	/* dtrace: return probe fasttrap */
    524      0  stevel 	uint32_t	ul_dreturn;	/* dtrace: return %o0 */
    525      0  stevel #endif
    526      0  stevel 	struct ulwp	*ul_self;	/* pointer to self */
    527      0  stevel #if defined(__i386)
    528      0  stevel 	uint8_t		ul_dinstr[40];	/* scratch space for dtrace */
    529      0  stevel #elif defined(__amd64)
    530      0  stevel 	uint8_t		ul_dinstr[56];	/* scratch space for dtrace */
    531      0  stevel #endif
    532      0  stevel 	struct uberdata *ul_uberdata;	/* uber (super-global) data */
    533      0  stevel 	tls_t		ul_tls;		/* dynamic thread-local storage base */
    534      0  stevel 	struct ulwp	*ul_forw;	/* forw, back all_lwps list, */
    535      0  stevel 	struct ulwp	*ul_back;	/* protected by link_lock */
    536      0  stevel 	struct ulwp	*ul_next;	/* list to keep track of stacks */
    537      0  stevel 	struct ulwp	*ul_hash;	/* hash chain linked list */
    538      0  stevel 	void		*ul_rval;	/* return value from thr_exit() */
    539      0  stevel 	caddr_t		ul_stk;		/* mapping base of the stack */
    540      0  stevel 	size_t		ul_mapsiz;	/* mapping size of the stack */
    541      0  stevel 	size_t		ul_guardsize;	/* normally _lpagesize */
    542      0  stevel 	uintptr_t	ul_stktop;	/* broken thr_stksegment() interface */
    543      0  stevel 	size_t		ul_stksiz;	/* broken thr_stksegment() interface */
    544      0  stevel 	stack_t		ul_ustack;	/* current stack boundaries */
    545      0  stevel 	int		ul_ix;		/* hash index */
    546      0  stevel 	lwpid_t		ul_lwpid;	/* thread id, aka the lwp id */
    547   6247     raf 	pri_t		ul_pri;		/* scheduling priority */
    548   6247     raf 	pri_t		ul_epri;	/* real-time ceiling priority */
    549      0  stevel 	char		ul_policy;	/* scheduling policy */
    550   6247     raf 	char		ul_cid;		/* scheduling class id */
    551      0  stevel 	union {
    552      0  stevel 		struct {
    553      0  stevel 			char	cursig;	/* deferred signal number */
    554      0  stevel 			char	pleasestop; /* lwp requested to stop itself */
    555      0  stevel 		} s;
    556      0  stevel 		short	curplease;	/* for testing both at once */
    557      0  stevel 	} ul_cp;
    558      0  stevel 	char		ul_stop;	/* reason for stopping */
    559      0  stevel 	char		ul_signalled;	/* this lwp was cond_signal()d */
    560      0  stevel 	char		ul_dead;	/* this lwp has called thr_exit */
    561      0  stevel 	char		ul_unwind;	/* posix: unwind C++ stack */
    562      0  stevel 	char		ul_detached;	/* THR_DETACHED at thread_create() */
    563      0  stevel 					/* or pthread_detach() was called */
    564      0  stevel 	char		ul_writer;	/* sleeping in rw_wrlock() */
    565      0  stevel 	char		ul_stopping;	/* set by curthread: stopping self */
    566   1885     raf 	char		ul_cancel_prologue;	/* for _cancel_prologue() */
    567      0  stevel 	short		ul_preempt;	/* no_preempt()/preempt() */
    568      0  stevel 	short		ul_savpreempt;	/* pre-existing preempt value */
    569      0  stevel 	char		ul_sigsuspend;	/* thread is in sigsuspend/pollsys */
    570      0  stevel 	char		ul_main;	/* thread is the main thread */
    571      0  stevel 	char		ul_fork;	/* thread is performing a fork */
    572      0  stevel 	char		ul_primarymap;	/* primary link-map is initialized */
    573      0  stevel 	/* per-thread copies of the corresponding global variables */
    574   5629     raf 	uint8_t		ul_max_spinners;	/* thread_max_spinners */
    575      0  stevel 	char		ul_door_noreserve;	/* thread_door_noreserve */
    576      0  stevel 	char		ul_queue_fifo;		/* thread_queue_fifo */
    577      0  stevel 	char		ul_cond_wait_defer;	/* thread_cond_wait_defer */
    578      0  stevel 	char		ul_error_detection;	/* thread_error_detection */
    579      0  stevel 	char		ul_async_safe;		/* thread_async_safe */
    580   6247     raf 	char		ul_rt;			/* found on an RT queue */
    581   6247     raf 	char		ul_rtqueued;		/* was RT when queued */
    582   7255     raf 	char		ul_misaligned;		/* thread_locks_misaligned */
    583   7255     raf 	char		ul_pad[3];
    584      0  stevel 	int		ul_adaptive_spin;	/* thread_adaptive_spin */
    585      0  stevel 	int		ul_queue_spin;		/* thread_queue_spin */
    586      0  stevel 	volatile int	ul_critical;	/* non-zero == in a critical region */
    587      0  stevel 	int		ul_sigdefer;	/* non-zero == defer signals */
    588      0  stevel 	int		ul_vfork;	/* thread is the child of vfork() */
    589      0  stevel 	int		ul_cancelable;	/* _cancelon()/_canceloff() */
    590      0  stevel 	char		ul_cancel_pending;  /* pthread_cancel() was called */
    591      0  stevel 	char		ul_cancel_disabled; /* PTHREAD_CANCEL_DISABLE */
    592      0  stevel 	char		ul_cancel_async;    /* PTHREAD_CANCEL_ASYNCHRONOUS */
    593      0  stevel 	char		ul_save_async;	/* saved copy of ul_cancel_async */
    594      0  stevel 	char		ul_mutator;	/* lwp is a mutator (java interface) */
    595      0  stevel 	char		ul_created;	/* created suspended */
    596      0  stevel 	char		ul_replace;	/* replacement; must be free()d */
    597      0  stevel 	uchar_t		ul_nocancel;	/* cancellation can't happen */
    598      0  stevel 	int		ul_errno;	/* per-thread errno */
    599      0  stevel 	int		*ul_errnop;	/* pointer to errno or self->ul_errno */
    600      0  stevel 	__cleanup_t	*ul_clnup_hdr;	/* head of cleanup handlers list */
    601   6247     raf 	uberflags_t	*ul_schedctl_called;	/* ul_schedctl is set up */
    602   6247     raf 	volatile sc_shared_t *ul_schedctl;	/* schedctl data */
    603      0  stevel 	int		ul_bindflags;	/* bind_guard() interface to ld.so.1 */
    604   5891     raf 	uint_t		ul_libc_locks;	/* count of cancel_safe_mutex_lock()s */
    605      0  stevel 	tsd_t		*ul_stsd;	/* slow TLS for keys >= TSD_NFAST */
    606      0  stevel 	void		*ul_ftsd[TSD_NFAST]; /* fast TLS for keys < TSD_NFAST */
    607      0  stevel 	td_evbuf_t	ul_td_evbuf;	/* event buffer */
    608      0  stevel 	char		ul_td_events_enable;	/* event mechanism enabled */
    609      0  stevel 	char		ul_sync_obj_reg;	/* tdb_sync_obj_register() */
    610      0  stevel 	char		ul_qtype;	/* MX or CV */
    611      0  stevel 	char		ul_cv_wake;	/* != 0: just wake up, don't requeue */
    612  10637   Roger 	int		ul_rtld;	/* thread is running inside ld.so.1 */
    613      0  stevel 	int		ul_usropts;	/* flags given to thr_create() */
    614      0  stevel 	void		*(*ul_startpc)(void *); /* start func (thr_create()) */
    615      0  stevel 	void		*ul_startarg;	/* argument for start function */
    616      0  stevel 	void		*ul_wchan;	/* synch object when sleeping */
    617      0  stevel 	struct ulwp	*ul_link;	/* sleep queue link */
    618      0  stevel 	queue_head_t	*ul_sleepq;	/* sleep queue thread is waiting on */
    619      0  stevel 	mutex_t		*ul_cvmutex;	/* mutex dropped when waiting on a cv */
    620      0  stevel 	mxchain_t	*ul_mxchain;	/* chain of owned ceiling mutexes */
    621   6247     raf 	int		ul_save_state;	/* bind_guard() interface to ld.so.1 */
    622   4574     raf 	uint_t		ul_rdlockcnt;	/* # entries in ul_readlock array */
    623   4574     raf 				/* 0 means there is but a single entry */
    624   4574     raf 	union {				/* single entry or pointer to array */
    625      0  stevel 		readlock_t	single;
    626      0  stevel 		readlock_t	*array;
    627      0  stevel 	} ul_readlock;
    628   4574     raf 	uint_t		ul_heldlockcnt;	/* # entries in ul_heldlocks array */
    629   4574     raf 				/* 0 means there is but a single entry */
    630   4574     raf 	union {				/* single entry or pointer to array */
    631   4574     raf 		mutex_t		*single;
    632   4574     raf 		mutex_t		**array;
    633   4574     raf 	} ul_heldlocks;
    634      0  stevel 	/* PROBE_SUPPORT begin */
    635      0  stevel 	void		*ul_tpdp;
    636      0  stevel 	/* PROBE_SUPPORT end */
    637      0  stevel 	ucontext_t	*ul_siglink;	/* pointer to previous context */
    638      0  stevel 	uint_t		ul_spin_lock_spin;	/* spin lock statistics */
    639      0  stevel 	uint_t		ul_spin_lock_spin2;
    640      0  stevel 	uint_t		ul_spin_lock_sleep;
    641      0  stevel 	uint_t		ul_spin_lock_wakeup;
    642   6247     raf 	queue_root_t	ul_queue_root;	/* root of a sleep queue */
    643   6247     raf 	id_t		ul_rtclassid;	/* real-time class id */
    644   6247     raf 	uint_t		ul_pilocks;	/* count of PI locks held */
    645      0  stevel 		/* the following members *must* be last in the structure */
    646      0  stevel 		/* they are discarded when ulwp is replaced on thr_exit() */
    647      0  stevel 	sigset_t	ul_sigmask;	/* thread's current signal mask */
    648      0  stevel 	sigset_t	ul_tmpmask;	/* signal mask for sigsuspend/pollsys */
    649      0  stevel 	siginfo_t	ul_siginfo;	/* deferred siginfo */
    650      0  stevel 	mutex_t		ul_spinlock;	/* used when suspending/continuing */
    651      0  stevel 	fpuenv_t	ul_fpuenv;	/* floating point state */
    652      0  stevel 	uintptr_t	ul_sp;		/* stack pointer when blocked */
    653      0  stevel 	void		*ul_ex_unwind;	/* address of _ex_unwind() or -1 */
    654      0  stevel #if defined(sparc)
    655      0  stevel 	void		*ul_unwind_ret;	/* used only by _ex_clnup_handler() */
    656      0  stevel #endif
    657      0  stevel } ulwp_t;
    658      0  stevel 
    659      0  stevel #define	ul_cursig	ul_cp.s.cursig		/* deferred signal number */
    660      0  stevel #define	ul_pleasestop	ul_cp.s.pleasestop	/* lwp requested to stop */
    661      0  stevel #define	ul_curplease	ul_cp.curplease		/* for testing both at once */
    662      0  stevel 
    663      0  stevel /*
    664      0  stevel  * This is the size of a replacement ulwp, retained only for the benefit
    665      0  stevel  * of thr_join().  The trailing members are unneeded for this purpose.
    666      0  stevel  */
    667      0  stevel #define	REPLACEMENT_SIZE	((size_t)&((ulwp_t *)NULL)->ul_sigmask)
    668      0  stevel 
    669      0  stevel /*
    670      0  stevel  * Definitions for static initialization of signal sets,
    671      0  stevel  * plus some sneaky optimizations in various places.
    672      0  stevel  */
    673      0  stevel 
    674      0  stevel #define	SIGMASK(sig)	((uint32_t)1 << (((sig) - 1) & (32 - 1)))
    675      0  stevel 
    676      0  stevel #if (MAXSIG > 32 && MAXSIG <= 64)
    677      0  stevel #define	FILLSET0	0xffffffffu
    678      0  stevel #define	FILLSET1	((1u << (MAXSIG - 32)) - 1)
    679      0  stevel #else
    680      0  stevel #error "fix me: MAXSIG out of bounds"
    681      0  stevel #endif
    682      0  stevel 
    683      0  stevel #define	CANTMASK0	(SIGMASK(SIGKILL) | SIGMASK(SIGSTOP))
    684      0  stevel #define	CANTMASK1	0
    685      0  stevel 
    686      0  stevel #define	MASKSET0	(FILLSET0 & ~CANTMASK0)
    687      0  stevel #define	MASKSET1	(FILLSET1 & ~CANTMASK1)
    688      0  stevel 
    689   2248     raf extern	const sigset_t maskset;		/* set of all maskable signals */
    690      0  stevel 
    691      0  stevel extern	int	thread_adaptive_spin;
    692      0  stevel extern	uint_t	thread_max_spinners;
    693      0  stevel extern	int	thread_queue_spin;
    694      0  stevel extern	int	thread_queue_fifo;
    695      0  stevel extern	int	thread_queue_dump;
    696      0  stevel extern	int	thread_cond_wait_defer;
    697      0  stevel extern	int	thread_async_safe;
    698      0  stevel extern	int	thread_queue_verify;
    699      0  stevel 
    700      0  stevel /*
    701      0  stevel  * pthread_atfork() related data, used to store atfork handlers.
    702      0  stevel  */
    703      0  stevel typedef struct atfork {
    704      0  stevel 	struct atfork *forw;		/* forward pointer */
    705      0  stevel 	struct atfork *back;		/* backward pointer */
    706      0  stevel 	void (*prepare)(void);		/* pre-fork handler */
    707      0  stevel 	void (*parent)(void);		/* post-fork parent handler */
    708      0  stevel 	void (*child)(void);		/* post-fork child handler */
    709      0  stevel } atfork_t;
    710      0  stevel 
    711      0  stevel /*
    712   9170   Roger  * Element in the table and in the list of registered process
    713   9170   Roger  * robust locks.  We keep track of these to make sure that we
    714   9170   Roger  * only call ___lwp_mutex_register() once for each such lock
    715   9170   Roger  * after it is first mapped in (or newly mapped in).
    716   4574     raf  */
    717   4574     raf typedef struct robust {
    718   9170   Roger 	struct robust	*robust_next;	/* hash table list */
    719   9170   Roger 	struct robust	*robust_list;	/* global list */
    720   4574     raf 	mutex_t		*robust_lock;
    721   4574     raf } robust_t;
    722   9170   Roger 
    723   9170   Roger /*
    724   9170   Roger  * Invalid address, used to mark an unused element in the hash table.
    725   9170   Roger  */
    726   9170   Roger #define	INVALID_ADDR	((void *)(uintptr_t)(-1L))
    727   4574     raf 
    728   4574     raf /*
    729   4574     raf  * Parameters of the lock registration hash table.
    730   4574     raf  */
    731   7063     raf #define	LOCKSHIFT	15			/* number of hashing bits */
    732   7063     raf #define	LOCKHASHSZ	(1 << LOCKSHIFT)	/* power of 2 (1<<15 == 32K) */
    733   4574     raf #define	LOCK_HASH(addr)	(uint_t)			\
    734   4574     raf 	((((uintptr_t)(addr) >> 3)			\
    735   4574     raf 	^ ((uintptr_t)(addr) >> (LOCKSHIFT + 3)))	\
    736   4574     raf 	& (LOCKHASHSZ - 1))
    737   4574     raf 
    738   4574     raf /*
    739      0  stevel  * Make our hot locks reside on private cache lines (64 bytes).
    740      0  stevel  */
    741      0  stevel typedef struct {
    742      0  stevel 	mutex_t	pad_lock;
    743   4843     raf 	char	pad_pad[64 - sizeof (mutex_t)];
    744      0  stevel } pad_lock_t;
    745   4843     raf 
    746   4843     raf /*
    747   4843     raf  * Make our semi-hot locks reside on semi-private cache lines (32 bytes).
    748   4843     raf  */
    749   4843     raf typedef struct {
    750   4843     raf 	mutex_t	pad_lock;
    751   4843     raf 	char	pad_pad[32 - sizeof (mutex_t)];
    752   4843     raf } pad32_lock_t;
    753      0  stevel 
    754      0  stevel /*
    755      0  stevel  * The threads hash table is used for fast lookup and locking of an active
    756      0  stevel  * thread structure (ulwp_t) given a thread-id.  It is an N-element array of
    757      0  stevel  * thr_hash_table_t structures, where N == 1 before the main thread creates
    758      0  stevel  * the first additional thread and N == 1024 afterwards.  Each element of the
    759      0  stevel  * table is 64 bytes in size and alignment to reduce cache conflicts.
    760      0  stevel  */
    761      0  stevel typedef struct {
    762      0  stevel 	mutex_t	hash_lock;	/* lock per bucket */
    763      0  stevel 	cond_t	hash_cond;	/* convar per bucket */
    764      0  stevel 	ulwp_t	*hash_bucket;	/* hash bucket points to the list of ulwps */
    765      0  stevel 	char	hash_pad[64 -	/* pad out to 64 bytes */
    766      0  stevel 		(sizeof (mutex_t) + sizeof (cond_t) + sizeof (ulwp_t *))];
    767      0  stevel } thr_hash_table_t;
    768      0  stevel 
    769      0  stevel #ifdef _SYSCALL32
    770      0  stevel typedef struct {
    771      0  stevel 	mutex_t	hash_lock;
    772      0  stevel 	cond_t	hash_cond;
    773      0  stevel 	caddr32_t hash_bucket;
    774      0  stevel 	char	hash_pad[64 -
    775      0  stevel 		(sizeof (mutex_t) + sizeof (cond_t) + sizeof (caddr32_t))];
    776      0  stevel } thr_hash_table32_t;
    777      0  stevel #endif	/* _SYSCALL32 */
    778      0  stevel 
    779      0  stevel 
    780      0  stevel /*
    781   4570     raf  * siguaction members have 128-byte size and 64-byte alignment.
    782   4570     raf  * We know that sizeof (struct sigaction) is 32 bytes for both
    783   4570     raf  * _ILP32 and _LP64 and that sizeof (rwlock_t) is 64 bytes.
    784      0  stevel  */
    785      0  stevel typedef struct {
    786   4570     raf 	rwlock_t	sig_lock;
    787      0  stevel 	struct sigaction sig_uaction;
    788   4570     raf 	char	sig_pad[128 - sizeof (rwlock_t) - sizeof (struct sigaction)];
    789      0  stevel } siguaction_t;
    790      0  stevel 
    791      0  stevel #ifdef _SYSCALL32
    792      0  stevel typedef struct {
    793   4570     raf 	rwlock_t	sig_lock;
    794      0  stevel 	struct sigaction32 sig_uaction;
    795   4570     raf 	char	sig_pad[128 - sizeof (rwlock_t) - sizeof (struct sigaction32)];
    796      0  stevel } siguaction32_t;
    797      0  stevel #endif	/* _SYSCALL32 */
    798      0  stevel 
    799      0  stevel 
    800      0  stevel /*
    801      0  stevel  * Bucket structures, used by lmalloc()/lfree().
    802      0  stevel  * See port/threads/alloc.c for details.
    803      0  stevel  * A bucket's size and alignment is 64 bytes.
    804      0  stevel  */
    805      0  stevel typedef struct {
    806      0  stevel 	mutex_t	bucket_lock;	/* protects the free list allocations */
    807      0  stevel 	void	*free_list;	/* LIFO list of blocks to allocate/free */
    808      0  stevel 	size_t	chunks;		/* number of 64K blocks mmap()ed last time */
    809      0  stevel 	char	pad64[64 -	/* pad out to 64 bytes */
    810      0  stevel 		(sizeof (mutex_t) + sizeof (void *) + sizeof (size_t))];
    811      0  stevel } bucket_t;
    812      0  stevel 
    813      0  stevel #ifdef _SYSCALL32
    814      0  stevel typedef struct {
    815      0  stevel 	mutex_t		bucket_lock;
    816      0  stevel 	caddr32_t	free_list;
    817      0  stevel 	size32_t	chunks;
    818      0  stevel 	char	pad64[64 -	/* pad out to 64 bytes */
    819      0  stevel 		(sizeof (mutex_t) + sizeof (caddr32_t) + sizeof (size32_t))];
    820      0  stevel } bucket32_t;
    821      0  stevel #endif	/* _SYSCALL32 */
    822      0  stevel 
    823      0  stevel #define	NBUCKETS	10	/* sizes ranging from 64 to 32768 */
    824      0  stevel 
    825      0  stevel 
    826      0  stevel /*
    827      0  stevel  * atexit() data structures.
    828      0  stevel  * See port/gen/atexit.c for details.
    829      0  stevel  */
    830      0  stevel typedef void (*_exithdlr_func_t) (void);
    831      0  stevel 
    832      0  stevel typedef struct _exthdlr {
    833      0  stevel 	struct _exthdlr 	*next;	/* next in handler list */
    834      0  stevel 	_exithdlr_func_t	hdlr;	/* handler itself */
    835      0  stevel } _exthdlr_t;
    836      0  stevel 
    837      0  stevel typedef struct {
    838      0  stevel 	mutex_t		exitfns_lock;
    839      0  stevel 	_exthdlr_t	*head;
    840      0  stevel 	void		*exit_frame_monitor;
    841      0  stevel 	char		exit_pad[64 -	/* pad out to 64 bytes */
    842      0  stevel 		(sizeof (mutex_t) + sizeof (_exthdlr_t *) + sizeof (void *))];
    843      0  stevel } atexit_root_t;
    844      0  stevel 
    845      0  stevel #ifdef _SYSCALL32
    846      0  stevel typedef struct {
    847      0  stevel 	mutex_t		exitfns_lock;
    848      0  stevel 	caddr32_t	head;
    849      0  stevel 	caddr32_t	exit_frame_monitor;
    850      0  stevel 	char		exit_pad[64 -	/* pad out to 64 bytes */
    851      0  stevel 		(sizeof (mutex_t) + sizeof (caddr32_t) + sizeof (caddr32_t))];
    852      0  stevel } atexit_root32_t;
    853      0  stevel #endif	/* _SYSCALL32 */
    854      0  stevel 
    855      0  stevel 
    856      0  stevel /*
    857      0  stevel  * This is data that is global to all link maps (uberdata, aka super-global).
    858      0  stevel  */
    859      0  stevel typedef struct uberdata {
    860      0  stevel 	pad_lock_t	_link_lock;
    861   6515     raf 	pad_lock_t	_ld_lock;
    862   6515     raf 	pad_lock_t	_fork_lock;
    863   6515     raf 	pad_lock_t	_atfork_lock;
    864   5002     raf 	pad32_lock_t	_callout_lock;
    865   5002     raf 	pad32_lock_t	_tdb_hash_lock;
    866      0  stevel 	tdb_sync_stats_t tdb_hash_lock_stats;
    867      0  stevel 	siguaction_t	siguaction[NSIG];
    868      0  stevel 	bucket_t	bucket[NBUCKETS];
    869      0  stevel 	atexit_root_t	atexit_root;
    870      0  stevel 	tsd_metadata_t	tsd_metadata;
    871      0  stevel 	tls_metadata_t	tls_metadata;
    872      0  stevel 	/*
    873      0  stevel 	 * Every object before this point has size and alignment of 64 bytes.
    874      0  stevel 	 * Don't add any other type of data before this point.
    875      0  stevel 	 */
    876      0  stevel 	char	primary_map;	/* set when primary link map is initialized */
    877      0  stevel 	char	bucket_init;	/* set when bucket[NBUCKETS] is initialized */
    878      0  stevel 	char	pad[2];
    879      0  stevel 	uberflags_t	uberflags;
    880      0  stevel 	queue_head_t	*queue_head;
    881      0  stevel 	thr_hash_table_t *thr_hash_table;
    882      0  stevel 	uint_t		hash_size;	/* # of entries in thr_hash_table[] */
    883      0  stevel 	uint_t		hash_mask;	/* hash_size - 1 */
    884      0  stevel 	ulwp_t	*ulwp_one;	/* main thread */
    885      0  stevel 	ulwp_t	*all_lwps;	/* circular ul_forw/ul_back list of live lwps */
    886      0  stevel 	ulwp_t	*all_zombies;	/* circular ul_forw/ul_back list of zombies */
    887      0  stevel 	int	nthreads;	/* total number of live threads/lwps */
    888      0  stevel 	int	nzombies;	/* total number of zombie threads */
    889      0  stevel 	int	ndaemons;	/* total number of THR_DAEMON threads/lwps */
    890      0  stevel 	pid_t	pid;		/* the current process's pid */
    891      0  stevel 	void	(*sigacthandler)(int, siginfo_t *, void *);
    892      0  stevel 	ulwp_t	*lwp_stacks;
    893      0  stevel 	ulwp_t	*lwp_laststack;
    894      0  stevel 	int	nfreestack;
    895      0  stevel 	int	thread_stack_cache;
    896      0  stevel 	ulwp_t	*ulwp_freelist;
    897      0  stevel 	ulwp_t	*ulwp_lastfree;
    898      0  stevel 	ulwp_t	*ulwp_replace_free;
    899      0  stevel 	ulwp_t	*ulwp_replace_last;
    900      0  stevel 	atfork_t	*atforklist;	/* circular Q for fork handlers */
    901   4574     raf 	robust_t	**robustlocks;	/* table of registered robust locks */
    902   9170   Roger 	robust_t	*robustlist;	/* list of registered robust locks */
    903      0  stevel 	struct uberdata **tdb_bootstrap;
    904      0  stevel 	tdb_t	tdb;		/* thread debug interfaces (for libc_db) */
    905      0  stevel } uberdata_t;
    906      0  stevel 
    907      0  stevel #define	link_lock	_link_lock.pad_lock
    908   6515     raf #define	ld_lock		_ld_lock.pad_lock
    909      0  stevel #define	fork_lock	_fork_lock.pad_lock
    910   4843     raf #define	atfork_lock	_atfork_lock.pad_lock
    911   5002     raf #define	callout_lock	_callout_lock.pad_lock
    912      0  stevel #define	tdb_hash_lock	_tdb_hash_lock.pad_lock
    913      0  stevel 
    914      0  stevel #pragma align 64(__uberdata)
    915      0  stevel extern	uberdata_t	__uberdata;
    916      0  stevel extern	uberdata_t	**__tdb_bootstrap;	/* known to libc_db and mdb */
    917      0  stevel extern	int		primary_link_map;
    918      0  stevel 
    919      0  stevel #define	ulwp_mutex(ulwp, udp)	\
    920      0  stevel 	(&(udp)->thr_hash_table[(ulwp)->ul_ix].hash_lock)
    921      0  stevel #define	ulwp_condvar(ulwp, udp)	\
    922      0  stevel 	(&(udp)->thr_hash_table[(ulwp)->ul_ix].hash_cond)
    923      0  stevel 
    924      0  stevel /*
    925      0  stevel  * Grab and release the hash table lock for the specified lwp.
    926      0  stevel  */
    927      0  stevel #define	ulwp_lock(ulwp, udp)	lmutex_lock(ulwp_mutex(ulwp, udp))
    928      0  stevel #define	ulwp_unlock(ulwp, udp)	lmutex_unlock(ulwp_mutex(ulwp, udp))
    929      0  stevel 
    930      0  stevel #ifdef _SYSCALL32	/* needed by libc_db */
    931      0  stevel 
    932      0  stevel typedef struct ulwp32 {
    933      0  stevel #if defined(__sparc)
    934      0  stevel 	uint32_t	ul_dinstr;	/* scratch space for dtrace */
    935      0  stevel 	uint32_t	ul_padsparc0[15];
    936      0  stevel 	uint32_t	ul_dsave;	/* dtrace: save %g1, %g0, %sp */
    937      0  stevel 	uint32_t	ul_drestore;	/* dtrace: restore %g0, %g0, %g0 */
    938      0  stevel 	uint32_t	ul_dftret;	/* dtrace: return probe fasttrap */
    939      0  stevel 	uint32_t	ul_dreturn;	/* dtrace: return %o0 */
    940      0  stevel #endif
    941      0  stevel 	caddr32_t	ul_self;	/* pointer to self */
    942   1016     raf #if defined(__x86)
    943      0  stevel 	uint8_t		ul_dinstr[40];	/* scratch space for dtrace */
    944      0  stevel #endif
    945      0  stevel 	caddr32_t	ul_uberdata;	/* uber (super-global) data */
    946      0  stevel 	tls32_t		ul_tls;		/* dynamic thread-local storage base */
    947      0  stevel 	caddr32_t	ul_forw;	/* forw, back all_lwps list, */
    948      0  stevel 	caddr32_t	ul_back;	/* protected by link_lock */
    949      0  stevel 	caddr32_t	ul_next;	/* list to keep track of stacks */
    950      0  stevel 	caddr32_t	ul_hash;	/* hash chain linked list */
    951      0  stevel 	caddr32_t	ul_rval;	/* return value from thr_exit() */
    952      0  stevel 	caddr32_t	ul_stk;		/* mapping base of the stack */
    953      0  stevel 	size32_t	ul_mapsiz;	/* mapping size of the stack */
    954      0  stevel 	size32_t	ul_guardsize;	/* normally _lpagesize */
    955      0  stevel 	caddr32_t	ul_stktop;	/* broken thr_stksegment() interface */
    956      0  stevel 	size32_t	ul_stksiz;	/* broken thr_stksegment() interface */
    957      0  stevel 	stack32_t	ul_ustack;	/* current stack boundaries */
    958      0  stevel 	int		ul_ix;		/* hash index */
    959      0  stevel 	lwpid_t		ul_lwpid;	/* thread id, aka the lwp id */
    960   6247     raf 	pri_t		ul_pri;		/* scheduling priority */
    961   6247     raf 	pri_t		ul_epri;	/* real-time ceiling priority */
    962      0  stevel 	char		ul_policy;	/* scheduling policy */
    963   6247     raf 	char		ul_cid;		/* scheduling class id */
    964      0  stevel 	union {
    965      0  stevel 		struct {
    966      0  stevel 			char	cursig;	/* deferred signal number */
    967      0  stevel 			char	pleasestop; /* lwp requested to stop itself */
    968      0  stevel 		} s;
    969      0  stevel 		short	curplease;	/* for testing both at once */
    970      0  stevel 	} ul_cp;
    971      0  stevel 	char		ul_stop;	/* reason for stopping */
    972      0  stevel 	char		ul_signalled;	/* this lwp was cond_signal()d */
    973      0  stevel 	char		ul_dead;	/* this lwp has called thr_exit */
    974      0  stevel 	char		ul_unwind;	/* posix: unwind C++ stack */
    975      0  stevel 	char		ul_detached;	/* THR_DETACHED at thread_create() */
    976      0  stevel 					/* or pthread_detach() was called */
    977      0  stevel 	char		ul_writer;	/* sleeping in rw_wrlock() */
    978      0  stevel 	char		ul_stopping;	/* set by curthread: stopping self */
    979   1885     raf 	char		ul_cancel_prologue;	/* for _cancel_prologue() */
    980      0  stevel 	short		ul_preempt;	/* no_preempt()/preempt() */
    981      0  stevel 	short		ul_savpreempt;	/* pre-existing preempt value */
    982      0  stevel 	char		ul_sigsuspend;	/* thread is in sigsuspend/pollsys */
    983      0  stevel 	char		ul_main;	/* thread is the main thread */
    984      0  stevel 	char		ul_fork;	/* thread is performing a fork */
    985      0  stevel 	char		ul_primarymap;	/* primary link-map is initialized */
    986      0  stevel 	/* per-thread copies of the corresponding global variables */
    987   5629     raf 	uint8_t		ul_max_spinners;	/* thread_max_spinners */
    988      0  stevel 	char		ul_door_noreserve;	/* thread_door_noreserve */
    989      0  stevel 	char		ul_queue_fifo;		/* thread_queue_fifo */
    990      0  stevel 	char		ul_cond_wait_defer;	/* thread_cond_wait_defer */
    991      0  stevel 	char		ul_error_detection;	/* thread_error_detection */
    992      0  stevel 	char		ul_async_safe;		/* thread_async_safe */
    993   6247     raf 	char		ul_rt;			/* found on an RT queue */
    994   6247     raf 	char		ul_rtqueued;		/* was RT when queued */
    995   7255     raf 	char		ul_misaligned;		/* thread_locks_misaligned */
    996   7255     raf 	char		ul_pad[3];
    997      0  stevel 	int		ul_adaptive_spin;	/* thread_adaptive_spin */
    998      0  stevel 	int		ul_queue_spin;		/* thread_queue_spin */
    999      0  stevel 	int		ul_critical;	/* non-zero == in a critical region */
   1000      0  stevel 	int		ul_sigdefer;	/* non-zero == defer signals */
   1001      0  stevel 	int		ul_vfork;	/* thread is the child of vfork() */
   1002      0  stevel 	int		ul_cancelable;	/* _cancelon()/_canceloff() */
   1003      0  stevel 	char		ul_cancel_pending;  /* pthread_cancel() was called */
   1004      0  stevel 	char		ul_cancel_disabled; /* PTHREAD_CANCEL_DISABLE */
   1005      0  stevel 	char		ul_cancel_async;    /* PTHREAD_CANCEL_ASYNCHRONOUS */
   1006      0  stevel 	char		ul_save_async;	/* saved copy of ul_cancel_async */
   1007      0  stevel 	char		ul_mutator;	/* lwp is a mutator (java interface) */
   1008      0  stevel 	char		ul_created;	/* created suspended */
   1009      0  stevel 	char		ul_replace;	/* replacement; must be free()d */
   1010      0  stevel 	uchar_t		ul_nocancel;	/* cancellation can't happen */
   1011      0  stevel 	int		ul_errno;	/* per-thread errno */
   1012      0  stevel 	caddr32_t	ul_errnop;	/* pointer to errno or self->ul_errno */
   1013      0  stevel 	caddr32_t	ul_clnup_hdr;	/* head of cleanup handlers list */
   1014      0  stevel 	caddr32_t	ul_schedctl_called; /* ul_schedctl is set up */
   1015      0  stevel 	caddr32_t	ul_schedctl;	/* schedctl data */
   1016      0  stevel 	int		ul_bindflags;	/* bind_guard() interface to ld.so.1 */
   1017   5891     raf 	uint_t		ul_libc_locks;	/* count of cancel_safe_mutex_lock()s */
   1018      0  stevel 	caddr32_t	ul_stsd;	/* slow TLS for keys >= TSD_NFAST */
   1019      0  stevel 	caddr32_t	ul_ftsd[TSD_NFAST]; /* fast TLS for keys < TSD_NFAST */
   1020      0  stevel 	td_evbuf32_t	ul_td_evbuf;	/* event buffer */
   1021      0  stevel 	char		ul_td_events_enable;	/* event mechanism enabled */
   1022      0  stevel 	char		ul_sync_obj_reg;	/* tdb_sync_obj_register() */
   1023      0  stevel 	char		ul_qtype;	/* MX or CV */
   1024      0  stevel 	char		ul_cv_wake;	/* != 0: just wake up, don't requeue */
   1025  10637   Roger 	int		ul_rtld;	/* thread is running inside ld.so.1 */
   1026      0  stevel 	int		ul_usropts;	/* flags given to thr_create() */
   1027      0  stevel 	caddr32_t	ul_startpc;	/* start func (thr_create()) */
   1028      0  stevel 	caddr32_t	ul_startarg;	/* argument for start function */
   1029      0  stevel 	caddr32_t	ul_wchan;	/* synch object when sleeping */
   1030      0  stevel 	caddr32_t	ul_link;	/* sleep queue link */
   1031      0  stevel 	caddr32_t	ul_sleepq;	/* sleep queue thread is waiting on */
   1032      0  stevel 	caddr32_t	ul_cvmutex;	/* mutex dropped when waiting on a cv */
   1033      0  stevel 	caddr32_t	ul_mxchain;	/* chain of owned ceiling mutexes */
   1034   6247     raf 	int		ul_save_state;	/* bind_guard() interface to ld.so.1 */
   1035   4574     raf 	uint_t		ul_rdlockcnt;	/* # entries in ul_readlock array */
   1036   4574     raf 				/* 0 means there is but a single entry */
   1037   4574     raf 	union {				/* single entry or pointer to array */
   1038      0  stevel 		readlock32_t	single;
   1039      0  stevel 		caddr32_t	array;
   1040      0  stevel 	} ul_readlock;
   1041   4574     raf 	uint_t		ul_heldlockcnt;	/* # entries in ul_heldlocks array */
   1042   4574     raf 				/* 0 means there is but a single entry */
   1043   4574     raf 	union {				/* single entry or pointer to array */
   1044   4574     raf 		caddr32_t	single;
   1045   4574     raf 		caddr32_t	array;
   1046   4574     raf 	} ul_heldlocks;
   1047      0  stevel 	/* PROBE_SUPPORT begin */
   1048      0  stevel 	caddr32_t	ul_tpdp;
   1049      0  stevel 	/* PROBE_SUPPORT end */
   1050      0  stevel 	caddr32_t	ul_siglink;	/* pointer to previous context */
   1051      0  stevel 	uint_t		ul_spin_lock_spin;	/* spin lock statistics */
   1052      0  stevel 	uint_t		ul_spin_lock_spin2;
   1053      0  stevel 	uint_t		ul_spin_lock_sleep;
   1054      0  stevel 	uint_t		ul_spin_lock_wakeup;
   1055   6247     raf 	queue_root32_t	ul_queue_root;	/* root of a sleep queue */
   1056   6247     raf 	id_t		ul_rtclassid;	/* real-time class id */
   1057   6247     raf 	uint_t		ul_pilocks;	/* count of PI locks held */
   1058      0  stevel 		/* the following members *must* be last in the structure */
   1059      0  stevel 		/* they are discarded when ulwp is replaced on thr_exit() */
   1060      0  stevel 	sigset32_t	ul_sigmask;	/* thread's current signal mask */
   1061      0  stevel 	sigset32_t	ul_tmpmask;	/* signal mask for sigsuspend/pollsys */
   1062      0  stevel 	siginfo32_t	ul_siginfo;	/* deferred siginfo */
   1063      0  stevel 	mutex_t		ul_spinlock;	/* used when suspending/continuing */
   1064      0  stevel 	fpuenv32_t	ul_fpuenv;	/* floating point state */
   1065      0  stevel 	caddr32_t	ul_sp;		/* stack pointer when blocked */
   1066      0  stevel #if defined(sparc)
   1067      0  stevel 	caddr32_t	ul_unwind_ret;	/* used only by _ex_clnup_handler() */
   1068      0  stevel #endif
   1069      0  stevel } ulwp32_t;
   1070      0  stevel 
   1071      0  stevel #define	REPLACEMENT_SIZE32	((size_t)&((ulwp32_t *)NULL)->ul_sigmask)
   1072      0  stevel 
   1073      0  stevel typedef struct uberdata32 {
   1074      0  stevel 	pad_lock_t	_link_lock;
   1075   6515     raf 	pad_lock_t	_ld_lock;
   1076   6515     raf 	pad_lock_t	_fork_lock;
   1077   6515     raf 	pad_lock_t	_atfork_lock;
   1078   5002     raf 	pad32_lock_t	_callout_lock;
   1079   5002     raf 	pad32_lock_t	_tdb_hash_lock;
   1080      0  stevel 	tdb_sync_stats_t tdb_hash_lock_stats;
   1081      0  stevel 	siguaction32_t	siguaction[NSIG];
   1082      0  stevel 	bucket32_t	bucket[NBUCKETS];
   1083      0  stevel 	atexit_root32_t	atexit_root;
   1084      0  stevel 	tsd_metadata32_t tsd_metadata;
   1085      0  stevel 	tls_metadata32_t tls_metadata;
   1086      0  stevel 	char		primary_map;
   1087      0  stevel 	char		bucket_init;
   1088      0  stevel 	char		pad[2];
   1089      0  stevel 	uberflags_t	uberflags;
   1090      0  stevel 	caddr32_t	queue_head;
   1091      0  stevel 	caddr32_t	thr_hash_table;
   1092      0  stevel 	uint_t		hash_size;
   1093      0  stevel 	uint_t		hash_mask;
   1094      0  stevel 	caddr32_t	ulwp_one;
   1095      0  stevel 	caddr32_t	all_lwps;
   1096      0  stevel 	caddr32_t	all_zombies;
   1097      0  stevel 	int		nthreads;
   1098      0  stevel 	int		nzombies;
   1099      0  stevel 	int		ndaemons;
   1100      0  stevel 	int		pid;
   1101      0  stevel 	caddr32_t	sigacthandler;
   1102      0  stevel 	caddr32_t	lwp_stacks;
   1103      0  stevel 	caddr32_t	lwp_laststack;
   1104      0  stevel 	int		nfreestack;
   1105      0  stevel 	int		thread_stack_cache;
   1106      0  stevel 	caddr32_t	ulwp_freelist;
   1107      0  stevel 	caddr32_t	ulwp_lastfree;
   1108      0  stevel 	caddr32_t	ulwp_replace_free;
   1109      0  stevel 	caddr32_t	ulwp_replace_last;
   1110      0  stevel 	caddr32_t	atforklist;
   1111   4574     raf 	caddr32_t	robustlocks;
   1112   9170   Roger 	caddr32_t	robustlist;
   1113      0  stevel 	caddr32_t	tdb_bootstrap;
   1114      0  stevel 	tdb32_t		tdb;
   1115      0  stevel } uberdata32_t;
   1116      0  stevel 
   1117      0  stevel #endif	/* _SYSCALL32 */
   1118      0  stevel 
   1119      0  stevel /* ul_stop values */
   1120      0  stevel #define	TSTP_REGULAR	0x01	/* Stopped by thr_suspend() */
   1121      0  stevel #define	TSTP_MUTATOR	0x08	/* stopped by thr_suspend_*mutator*() */
   1122      0  stevel #define	TSTP_FORK	0x20	/* stopped by suspend_fork() */
   1123      0  stevel 
   1124      0  stevel /*
   1125      0  stevel  * Implementation-specific attribute types for pthread_mutexattr_init() etc.
   1126      0  stevel  */
   1127      0  stevel 
   1128      0  stevel typedef	struct	_cvattr {
   1129      0  stevel 	int	pshared;
   1130      0  stevel 	clockid_t clockid;
   1131      0  stevel } cvattr_t;
   1132      0  stevel 
   1133      0  stevel typedef	struct	_mattr {
   1134      0  stevel 	int	pshared;
   1135      0  stevel 	int	protocol;
   1136      0  stevel 	int	prioceiling;
   1137      0  stevel 	int	type;
   1138      0  stevel 	int	robustness;
   1139      0  stevel } mattr_t;
   1140      0  stevel 
   1141      0  stevel typedef	struct	_thrattr {
   1142      0  stevel 	size_t	stksize;
   1143      0  stevel 	void	*stkaddr;
   1144      0  stevel 	int	detachstate;
   1145   1885     raf 	int	daemonstate;
   1146      0  stevel 	int	scope;
   1147      0  stevel 	int	prio;
   1148      0  stevel 	int	policy;
   1149      0  stevel 	int	inherit;
   1150      0  stevel 	size_t	guardsize;
   1151      0  stevel } thrattr_t;
   1152      0  stevel 
   1153      0  stevel typedef	struct	_rwlattr {
   1154      0  stevel 	int	pshared;
   1155      0  stevel } rwlattr_t;
   1156      0  stevel 
   1157      0  stevel /* _curthread() is inline for speed */
   1158      0  stevel extern	ulwp_t		*_curthread(void);
   1159      0  stevel #define	curthread	(_curthread())
   1160      0  stevel 
   1161      0  stevel /* this version (also inline) can be tested for NULL */
   1162      0  stevel extern	ulwp_t		*__curthread(void);
   1163      0  stevel 
   1164      0  stevel /* get the current stack pointer (also inline) */
   1165      0  stevel extern	greg_t		stkptr(void);
   1166      0  stevel 
   1167      0  stevel /*
   1168      0  stevel  * Suppress __attribute__((...)) if we are not compiling with gcc
   1169      0  stevel  */
   1170      0  stevel #if !defined(__GNUC__)
   1171      0  stevel #define	__attribute__(string)
   1172      0  stevel #endif
   1173      0  stevel 
   1174   6247     raf /* Fetch the dispatch (kernel) priority of a thread */
   1175   6247     raf #define	real_priority(ulwp)	\
   1176   6247     raf 	((ulwp)->ul_schedctl? (ulwp)->ul_schedctl->sc_priority : 0)
   1177   6247     raf 
   1178      0  stevel /*
   1179      0  stevel  * Implementation functions.  Not visible outside of the library itself.
   1180      0  stevel  */
   1181   2248     raf extern	int	__nanosleep(const timespec_t *, timespec_t *);
   1182      0  stevel extern	void	getgregs(ulwp_t *, gregset_t);
   1183      0  stevel extern	void	setgregs(ulwp_t *, gregset_t);
   1184      0  stevel extern	void	thr_panic(const char *);
   1185      0  stevel #pragma rarely_called(thr_panic)
   1186      0  stevel extern	ulwp_t	*find_lwp(thread_t);
   1187      0  stevel extern	void	finish_init(void);
   1188   6247     raf extern	void	update_sched(ulwp_t *);
   1189      0  stevel extern	void	queue_alloc(void);
   1190      0  stevel extern	void	tsd_exit(void);
   1191      0  stevel extern	void	tsd_free(ulwp_t *);
   1192      0  stevel extern	void	tls_setup(void);
   1193      0  stevel extern	void	tls_exit(void);
   1194      0  stevel extern	void	tls_free(ulwp_t *);
   1195      0  stevel extern	void	rwl_free(ulwp_t *);
   1196   4574     raf extern	void	heldlock_exit(void);
   1197   4574     raf extern	void	heldlock_free(ulwp_t *);
   1198      0  stevel extern	void	sigacthandler(int, siginfo_t *, void *);
   1199      0  stevel extern	void	signal_init(void);
   1200      0  stevel extern	int	sigequalset(const sigset_t *, const sigset_t *);
   1201      0  stevel extern	void	mutex_setup(void);
   1202      0  stevel extern	void	take_deferred_signal(int);
   1203   7657   Roger extern	void	*setup_top_frame(void *, size_t, ulwp_t *);
   1204      0  stevel extern	int	setup_context(ucontext_t *, void *(*func)(ulwp_t *),
   1205      0  stevel 			ulwp_t *ulwp, caddr_t stk, size_t stksize);
   1206      0  stevel extern	volatile sc_shared_t *setup_schedctl(void);
   1207      0  stevel extern	void	*lmalloc(size_t);
   1208      0  stevel extern	void	lfree(void *, size_t);
   1209      0  stevel extern	void	*libc_malloc(size_t);
   1210      0  stevel extern	void	*libc_realloc(void *, size_t);
   1211      0  stevel extern	void	libc_free(void *);
   1212      0  stevel extern	char	*libc_strdup(const char *);
   1213      0  stevel extern	void	ultos(uint64_t, int, char *);
   1214      0  stevel extern	void	lock_error(const mutex_t *, const char *, void *, const char *);
   1215      0  stevel extern	void	rwlock_error(const rwlock_t *, const char *, const char *);
   1216      0  stevel extern	void	thread_error(const char *);
   1217      0  stevel extern	void	grab_assert_lock(void);
   1218      0  stevel extern	void	dump_queue_statistics(void);
   1219      0  stevel extern	void	collect_queue_statistics(void);
   1220      0  stevel extern	void	record_spin_locks(ulwp_t *);
   1221   4574     raf extern	void	remember_lock(mutex_t *);
   1222   4574     raf extern	void	forget_lock(mutex_t *);
   1223   4574     raf extern	void	register_lock(mutex_t *);
   1224   9264   Roger extern	void	unregister_locks(void);
   1225      0  stevel #if defined(__sparc)
   1226      0  stevel extern	void	_flush_windows(void);
   1227      0  stevel #else
   1228      0  stevel #define	_flush_windows()
   1229      0  stevel #endif
   1230      0  stevel extern	void	set_curthread(void *);
   1231      0  stevel 
   1232   4570     raf /*
   1233   4574     raf  * Utility function used when waking up many threads (more than MAXLWPS)
   1234   4574     raf  * all at once.  See mutex_wakeup_all(), cond_broadcast(), and rw_unlock().
   1235   4570     raf  */
   1236   4570     raf #define	MAXLWPS	128	/* max remembered lwpids before overflow */
   1237   4570     raf #define	NEWLWPS	2048	/* max remembered lwpids at first overflow */
   1238   4570     raf extern	lwpid_t	*alloc_lwpids(lwpid_t *, int *, int *);
   1239   4570     raf 
   1240      0  stevel /* enter a critical section */
   1241      0  stevel #define	enter_critical(self)	(self->ul_critical++)
   1242      0  stevel 
   1243      0  stevel /* exit a critical section, take deferred actions if necessary */
   1244      0  stevel extern	void	do_exit_critical(void);
   1245      0  stevel #define	exit_critical(self)					\
   1246      0  stevel 	(void) (self->ul_critical--,				\
   1247      0  stevel 	    ((self->ul_curplease && self->ul_critical == 0)?	\
   1248      0  stevel 	    (do_exit_critical(), 0) : 0))
   1249      0  stevel 
   1250      0  stevel /*
   1251      0  stevel  * Like enter_critical()/exit_critical() but just for deferring signals.
   1252      0  stevel  * Unlike enter_critical()/exit_critical(), ul_sigdefer may be set while
   1253      0  stevel  * calling application functions like constructors and destructors.
   1254      0  stevel  * Care must be taken if the application function attempts to set
   1255      0  stevel  * the signal mask while a deferred signal is present; the setting
   1256      0  stevel  * of the signal mask must also be deferred.
   1257      0  stevel  */
   1258      0  stevel #define	sigoff(self)	(self->ul_sigdefer++)
   1259  10637   Roger #define	sigon(self)						\
   1260  10637   Roger 	(void) ((--self->ul_sigdefer == 0 &&			\
   1261  10637   Roger 	    self->ul_curplease && self->ul_critical == 0)?	\
   1262  10637   Roger 	    (do_exit_critical(), 0) : 0)
   1263      0  stevel 
   1264      0  stevel /* these are exported functions */
   1265      0  stevel extern	void	_sigoff(void);
   1266      0  stevel extern	void	_sigon(void);
   1267      0  stevel 
   1268      0  stevel #define	sigorset(s1, s2)				\
   1269      0  stevel 	(((s1)->__sigbits[0] |= (s2)->__sigbits[0]),	\
   1270      0  stevel 	((s1)->__sigbits[1] |= (s2)->__sigbits[1]),	\
   1271      0  stevel 	((s1)->__sigbits[2] |= (s2)->__sigbits[2]),	\
   1272      0  stevel 	((s1)->__sigbits[3] |= (s2)->__sigbits[3]))
   1273      0  stevel 
   1274      0  stevel #define	sigandset(s1, s2)				\
   1275      0  stevel 	(((s1)->__sigbits[0] &= (s2)->__sigbits[0]),	\
   1276      0  stevel 	((s1)->__sigbits[1] &= (s2)->__sigbits[1]),	\
   1277      0  stevel 	((s1)->__sigbits[2] &= (s2)->__sigbits[2]),	\
   1278      0  stevel 	((s1)->__sigbits[3] &= (s2)->__sigbits[3]))
   1279      0  stevel 
   1280      0  stevel #define	sigdiffset(s1, s2)				\
   1281      0  stevel 	(((s1)->__sigbits[0] &= ~(s2)->__sigbits[0]),	\
   1282      0  stevel 	((s1)->__sigbits[1] &= ~(s2)->__sigbits[1]),	\
   1283      0  stevel 	((s1)->__sigbits[2] &= ~(s2)->__sigbits[2]),	\
   1284      0  stevel 	((s1)->__sigbits[3] &= ~(s2)->__sigbits[3]))
   1285      0  stevel 
   1286      0  stevel #define	delete_reserved_signals(s)			\
   1287      0  stevel 	(((s)->__sigbits[0] &= MASKSET0),		\
   1288      0  stevel 	((s)->__sigbits[1] &= (MASKSET1 & ~SIGMASK(SIGCANCEL))),\
   1289      0  stevel 	((s)->__sigbits[2] = 0),			\
   1290      0  stevel 	((s)->__sigbits[3] = 0))
   1291      0  stevel 
   1292      0  stevel extern	void	block_all_signals(ulwp_t *self);
   1293      0  stevel 
   1294      0  stevel /*
   1295      0  stevel  * When restoring the signal mask after having previously called
   1296      0  stevel  * block_all_signals(), if we have a deferred signal present then
   1297      0  stevel  * do nothing other than ASSERT() that we are in a critical region.
   1298      0  stevel  * The signal mask will be set when we emerge from the critical region
   1299      0  stevel  * and call take_deferred_signal().  There is no race condition here
   1300      0  stevel  * because the kernel currently has all signals blocked for this thread.
   1301      0  stevel  */
   1302      0  stevel #define	restore_signals(self)						\
   1303      0  stevel 	((void) ((self)->ul_cursig?					\
   1304      0  stevel 	(ASSERT((self)->ul_critical + (self)->ul_sigdefer != 0), 0) :	\
   1305      0  stevel 	__lwp_sigmask(SIG_SETMASK, &(self)->ul_sigmask, NULL)))
   1306      0  stevel 
   1307   5891     raf extern	void	set_cancel_pending_flag(ulwp_t *, int);
   1308   5891     raf extern	void	set_cancel_eintr_flag(ulwp_t *);
   1309      0  stevel extern	void	set_parking_flag(ulwp_t *, int);
   1310   5891     raf extern	int	cancel_active(void);
   1311      0  stevel 
   1312   6812     raf extern	void	*_thrp_setup(ulwp_t *);
   1313      0  stevel extern	void	_fpinherit(ulwp_t *);
   1314      0  stevel extern	void	_lwp_start(void);
   1315      0  stevel extern	void	_lwp_terminate(void);
   1316   2248     raf extern	void	lmutex_lock(mutex_t *);
   1317      0  stevel extern	void	lmutex_unlock(mutex_t *);
   1318   4570     raf extern	void	lrw_rdlock(rwlock_t *);
   1319   4570     raf extern	void	lrw_wrlock(rwlock_t *);
   1320   4570     raf extern	void	lrw_unlock(rwlock_t *);
   1321   2248     raf extern	void	sig_mutex_lock(mutex_t *);
   1322   2248     raf extern	void	sig_mutex_unlock(mutex_t *);
   1323   2248     raf extern	int	sig_mutex_trylock(mutex_t *);
   1324   2248     raf extern	int	sig_cond_wait(cond_t *, mutex_t *);
   1325   2248     raf extern	int	sig_cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
   1326   5891     raf extern	void	cancel_safe_mutex_lock(mutex_t *);
   1327   5891     raf extern	void	cancel_safe_mutex_unlock(mutex_t *);
   1328   5891     raf extern	int	cancel_safe_mutex_trylock(mutex_t *);
   1329      0  stevel extern	void	_prefork_handler(void);
   1330      0  stevel extern	void	_postfork_parent_handler(void);
   1331      0  stevel extern	void	_postfork_child_handler(void);
   1332   2248     raf extern	void	postfork1_child(void);
   1333   2248     raf extern	void	postfork1_child_aio(void);
   1334   2248     raf extern	void	postfork1_child_sigev_aio(void);
   1335   2248     raf extern	void	postfork1_child_sigev_mq(void);
   1336   2248     raf extern	void	postfork1_child_sigev_timer(void);
   1337   2248     raf extern	void	postfork1_child_tpool(void);
   1338   4843     raf extern	void	fork_lock_enter(void);
   1339      0  stevel extern	void	fork_lock_exit(void);
   1340      0  stevel extern	void	suspend_fork(void);
   1341      0  stevel extern	void	continue_fork(int);
   1342      0  stevel extern	void	do_sigcancel(void);
   1343   2248     raf extern	void	setup_cancelsig(int);
   1344   2248     raf extern	void	init_sigev_thread(void);
   1345   2248     raf extern	void	init_aio(void);
   1346      0  stevel extern	void	_cancelon(void);
   1347      0  stevel extern	void	_canceloff(void);
   1348      0  stevel extern	void	_canceloff_nocancel(void);
   1349   2248     raf extern	void	_cancel_prologue(void);
   1350   2248     raf extern	void	_cancel_epilogue(void);
   1351      0  stevel extern	void	no_preempt(ulwp_t *);
   1352      0  stevel extern	void	preempt(ulwp_t *);
   1353      0  stevel extern	void	_thrp_unwind(void *);
   1354      0  stevel 
   1355   3235     raf extern	pid_t	__forkx(int);
   1356   3235     raf extern	pid_t	__forkallx(int);
   1357   6515     raf extern	int	__open(const char *, int, ...);
   1358   6515     raf extern	int	__close(int);
   1359   5891     raf extern	ssize_t	__read(int, void *, size_t);
   1360   5891     raf extern	ssize_t	__write(int, const void *, size_t);
   1361   6515     raf extern	int	__fcntl(int, int, ...);
   1362      0  stevel extern	int	__lwp_continue(lwpid_t);
   1363      0  stevel extern	int	__lwp_create(ucontext_t *, uint_t, lwpid_t *);
   1364      0  stevel extern	int	___lwp_suspend(lwpid_t);
   1365      0  stevel extern	int	lwp_wait(lwpid_t, lwpid_t *);
   1366      0  stevel extern	int	__lwp_wait(lwpid_t, lwpid_t *);
   1367      0  stevel extern	int	__lwp_detach(lwpid_t);
   1368      0  stevel extern	sc_shared_t *__schedctl(void);
   1369      0  stevel 
   1370      0  stevel /* actual system call traps */
   1371   6515     raf extern	int	__setcontext(const ucontext_t *);
   1372   6515     raf extern	int	__getcontext(ucontext_t *);
   1373      0  stevel extern	int	__clock_gettime(clockid_t, timespec_t *);
   1374      0  stevel extern	void	abstime_to_reltime(clockid_t, const timespec_t *, timespec_t *);
   1375      0  stevel extern	void	hrt2ts(hrtime_t, timespec_t *);
   1376      0  stevel 
   1377      0  stevel extern	int	__sigaction(int, const struct sigaction *, struct sigaction *);
   1378      0  stevel extern	int	__lwp_sigmask(int, const sigset_t *, sigset_t *);
   1379      0  stevel extern	void	__sighndlr(int, siginfo_t *, ucontext_t *, void (*)());
   1380      0  stevel extern	caddr_t	__sighndlrend;
   1381      0  stevel #pragma unknown_control_flow(__sighndlr)
   1382   2248     raf 
   1383   2248     raf /* belongs in <pthread.h> */
   1384   2248     raf #define	PTHREAD_CREATE_DAEMON_NP	0x100	/* = THR_DAEMON */
   1385   2248     raf #define	PTHREAD_CREATE_NONDAEMON_NP	0
   1386   6812     raf extern	int	pthread_attr_setdaemonstate_np(pthread_attr_t *, int);
   1387   6812     raf extern	int	pthread_attr_getdaemonstate_np(const pthread_attr_t *, int *);
   1388      0  stevel 
   1389   6812     raf extern	int	mutex_held(mutex_t *);
   1390   6247     raf extern	int	mutex_lock_internal(mutex_t *, timespec_t *, int);
   1391   6247     raf extern	int	mutex_unlock_internal(mutex_t *, int);
   1392      0  stevel 
   1393   5891     raf /* not cancellation points: */
   1394   5891     raf extern	int	__cond_wait(cond_t *, mutex_t *);
   1395   5891     raf extern	int	__cond_timedwait(cond_t *, mutex_t *, const timespec_t *);
   1396   5891     raf extern	int	__cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
   1397      0  stevel 
   1398   6812     raf extern	int	rw_read_held(rwlock_t *);
   1399   6812     raf extern	int	rw_write_held(rwlock_t *);
   1400      0  stevel 
   1401   2248     raf extern	int	_thrp_create(void *, size_t, void *(*)(void *), void *, long,
   1402   6247     raf 			thread_t *, size_t);
   1403      0  stevel extern	int	_thrp_suspend(thread_t, uchar_t);
   1404      0  stevel extern	int	_thrp_continue(thread_t, uchar_t);
   1405      0  stevel 
   1406   6812     raf extern	void	_thrp_terminate(void *);
   1407      0  stevel extern	void	_thrp_exit(void);
   1408      0  stevel 
   1409   6247     raf extern	const pcclass_t *get_info_by_class(id_t);
   1410   6247     raf extern	const pcclass_t *get_info_by_policy(int);
   1411   1885     raf extern	const thrattr_t *def_thrattr(void);
   1412   6247     raf extern	id_t	setparam(idtype_t, id_t, int, int);
   1413   6247     raf extern	id_t	setprio(idtype_t, id_t, int, int *);
   1414   6247     raf extern	id_t	getparam(idtype_t, id_t, int *, struct sched_param *);
   1415      0  stevel 
   1416      0  stevel /*
   1417      0  stevel  * System call wrappers (direct interfaces to the kernel)
   1418      0  stevel  */
   1419   9264   Roger extern	int	___lwp_mutex_register(mutex_t *, mutex_t **);
   1420  10887   Roger extern	int	___lwp_mutex_trylock(mutex_t *, ulwp_t *);
   1421  10887   Roger extern	int	___lwp_mutex_timedlock(mutex_t *, timespec_t *, ulwp_t *);
   1422      0  stevel extern	int	___lwp_mutex_unlock(mutex_t *);
   1423   4574     raf extern	int	___lwp_mutex_wakeup(mutex_t *, int);
   1424      0  stevel extern	int	___lwp_cond_wait(cond_t *, mutex_t *, timespec_t *, int);
   1425      0  stevel extern	int	___lwp_sema_timedwait(lwp_sema_t *, timespec_t *, int);
   1426      0  stevel extern	int	__lwp_rwlock_rdlock(rwlock_t *, timespec_t *);
   1427      0  stevel extern	int	__lwp_rwlock_wrlock(rwlock_t *, timespec_t *);
   1428      0  stevel extern	int	__lwp_rwlock_tryrdlock(rwlock_t *);
   1429      0  stevel extern	int	__lwp_rwlock_trywrlock(rwlock_t *);
   1430      0  stevel extern	int	__lwp_rwlock_unlock(rwlock_t *);
   1431      0  stevel extern	int	__lwp_park(timespec_t *, lwpid_t);
   1432      0  stevel extern	int	__lwp_unpark(lwpid_t);
   1433      0  stevel extern	int	__lwp_unpark_all(lwpid_t *, int);
   1434   1016     raf #if defined(__x86)
   1435      0  stevel extern	int	___lwp_private(int, int, void *);
   1436   1016     raf #endif	/* __x86 */
   1437      0  stevel 
   1438      0  stevel /*
   1439      0  stevel  * inlines
   1440      0  stevel  */
   1441      0  stevel extern	int		set_lock_byte(volatile uint8_t *);
   1442   4570     raf extern	uint32_t	atomic_swap_32(volatile uint32_t *, uint32_t);
   1443   4570     raf extern	uint32_t	atomic_cas_32(volatile uint32_t *, uint32_t, uint32_t);
   1444   4570     raf extern	void		atomic_inc_32(volatile uint32_t *);
   1445   4570     raf extern	void		atomic_dec_32(volatile uint32_t *);
   1446   4570     raf extern	void		atomic_and_32(volatile uint32_t *, uint32_t);
   1447   4570     raf extern	void		atomic_or_32(volatile uint32_t *, uint32_t);
   1448   1016     raf #if defined(__sparc)
   1449   1016     raf extern	ulong_t		caller(void);
   1450   1016     raf extern	ulong_t		getfp(void);
   1451   1016     raf #endif	/* __sparc */
   1452   1016     raf 
   1453   1016     raf #include "thr_inlines.h"
   1454      0  stevel 
   1455      0  stevel #endif	/* _THR_UBERDATA_H */
   1456