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