thr_uberdata.h revision 2
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * This is an implementation-specific include file for threading support. 2N/A * It is not to be seen by the clients of the library. 2N/A * This file also describes uberdata in libc. 2N/A * The term "uberdata" refers to data that is unique and visible across 2N/A * all link maps. The name is meant to imply that such data is truly 2N/A * global, not just locally global to a particular link map. 2N/A * See the Linker and Libraries Guide for a full description of alternate 2N/A * link maps and how they are set up and used. 2N/A * Alternate link maps implement multiple global namespaces within a single 2N/A * process. There may be multiple instances of identical dynamic libraries 2N/A * loaded in a process's address space at the same time, each on a different 2N/A * link map (as determined by the dynamic linker), each with its own set of 2N/A * global variables. Which particular instance of a global variable is seen 2N/A * by a thread running in the process is determined by the link map on which 2N/A * the thread happens to be executing at the time. 2N/A * However, there are aspects of a process that are unique across all 2N/A * link maps, in particular the structures used to implement threads 2N/A * of control (in Sparc terminology, there is only one %g7 regardless 2N/A * of the link map on which the thread is executing). 2N/A * All uberdata is referenced from a base pointer in the thread's ulwp_t 2N/A * structure (which is also uberdata). All allocations and deallocations 2N/A * of uberdata are made via the uberdata-aware lmalloc() and lfree() 2N/A * interfaces (malloc() and free() are simply locally-global). 2N/A * Special libc-private access to errno. 2N/A * We do this so that references to errno do not invoke the dynamic linker. 2N/A * and why they are different for sparc and intel. 2N/A/* lock.lock64.pad[x] 4 5 6 7 */ 2N/A/* lock.lock64.pad[x] 7 6 5 4 */ 2N/A#
error "neither __sparc nor __x86 is defined" 2N/A * Fetch the owner of a USYNC_THREAD mutex. 2N/A * Don't use this with process-shared mutexes; 2N/A * the owing thread may be in a different process. 2N/A * Test if a thread owns a process-private (USYNC_THREAD) mutex. 2N/A * This is inappropriate for a process-shared (USYNC_PROCESS) mutex. 2N/A * The 'mp' argument must not have side-effects since it is evaluated twice. 2N/A * uberflags.uf_tdb_register_sync is an interface with libc_db to enable the 2N/A * collection of lock statistics by a debugger or other collecting tool. 2N/A * uberflags.uf_thread_error_detection is set by an environment variable: 2N/A * _THREAD_ERROR_DETECTION 2N/A * 0 == no detection of locking primitive errors. 2N/A * 1 == detect errors and issue a warning message. 2N/A * 2 == detect errors, issue a warning message, and dump core. 2N/A * We bundle these together in uberflags.uf_trs_ted to make a test of either 2N/A * being non-zero a single memory reference (for speed of mutex_lock(), etc). 2N/A * uberflags.uf_mt is set non-zero when the first thread (in addition 2N/A * to the main thread) is created. 2N/A * We bundle all these flags together in uberflags.uf_all to make a test 2N/A * of any being non-zero a single memory reference (again, for speed). 2N/A * To enable further optimization, the "ul_schedctl_called" member 2N/A * of the ulwp_t structure (below) serves double-duty: 2N/A * 1. If NULL, it means that the thread must call __schedctl() 2N/A * to set up its schedctl mappings before acquiring a mutex. 2N/A * This is required by the implementation of adaptive mutex locking. 2N/A * 2. If non-NULL, it points to uberdata.uberflags, so that tests of 2N/A * uberflags can be made without additional memory references. 2N/A * This allows the common case of _mutex_lock() and _mutex_unlock() for 2N/A * USYNC_THREAD mutexes with no error detection and no lock statistics 2N/A * to be optimized for speed. 2N/A/* double the default stack size for 64-bit processes */ 2N/Atypedef struct {
/* structure returned by fnstenv */ 2N/A int fstat;
/* status word (flags, etc) */ 2N/A int ftag;
/* tag of which regs busy */ 2N/A int misc[
4];
/* other stuff, 28 bytes total */ 2N/A#
endif /* _SYSCALL32 */ 2N/Atypedef struct {
/* fp state structure */ 2N/A#
endif /* _SYSCALL32 */ 2N/A * Cleanup handler related data. 2N/A * pthread.h exports only the size of this structure, so check 2N/A void (*
func)(
void *);
/* cleanup handler address */ 2N/A void *
arg;
/* handler's argument */ 2N/A * Thread-Specific Data (TSD) 2N/A * TSD_NFAST includes the invalid key zero, so there 2N/A * are really only (TSD_NFAST - 1) fast key slots. 2N/A * The tsd union is designed to burn a little memory (9 words) to make 2N/A * lookups blindingly fast. Note that tsd_nalloc could be placed at the 2N/A * end of the pad region to increase the likelihood that it falls on the 2N/A * same cache line as the data. 2N/A#
endif /* _SYSCALL32 */ 2N/A * Thread-Local Storage (TLS) 2N/A#
endif /* _SYSCALL32 */ 2N/A * Sleep queue root for USYNC_THREAD condvars and mutexes. 2N/A * There is a default queue root for each queue head (see below). 2N/A * Also, each ulwp_t contains a queue root that can be used 2N/A * when the thread is enqueued on the queue, if necessary 2N/A * (when more than one wchan hashes to the same queue head). 2N/A * Sleep queue heads for USYNC_THREAD condvars and mutexes. 2N/A * The size and alignment is 128 bytes to reduce cache conflicts. 2N/A * Each queue head points to a list of queue roots, defined above. 2N/A * Each queue head contains a default queue root for use when only one 2N/A * is needed. It is always at the tail of the queue root hash chain. 2N/A/* queue types passed to queue_lock() */ 2N/A * Scheduling class information structure. 2N/A * Memory block for chain of owned ceiling mutexes. 2N/A * Pointer to an rwlock that is held for reading. 2N/A * Used in rw_rdlock() to allow a thread that already holds a read 2N/A * lock to acquire another read lock on the same rwlock even if 2N/A * there are writers waiting. This to avoid deadlock when acquiring 2N/A * a read lock more than once in the presence of pending writers. 2N/A * POSIX mandates this behavior. 2N/A#
endif /* _SYSCALL32 */ 2N/A * Maximum number of read locks allowed for one thread on one rwlock. 2N/A * This could be as large as INT_MAX, but the SUSV3 test suite would 2N/A * take an inordinately long time to complete. This is big enough. 2N/A * Round up an integral value to a multiple of 64 2N/A * NOTE: Whatever changes are made to ulwp_t must be 2N/A * NOTE: ul_self *must* be the first member of ulwp_t on x86 2N/A * Low-level x86 code relies on this. 2N/A * These members always need to come first on sparc. 2N/A * For dtrace, a ulwp_t must be aligned on a 64-byte boundary. 2N/A /* or pthread_detach() was called */ 2N/A /* per-thread copies of the corresponding global variables */ 2N/A /* 0 means there is but a single entry */ 2N/A union {
/* single entry or pointer to array */ 2N/A /* 0 means there is but a single entry */ 2N/A union {
/* single entry or pointer to array */ 2N/A /* PROBE_SUPPORT begin */ 2N/A /* PROBE_SUPPORT end */ 2N/A /* the following members *must* be last in the structure */ 2N/A /* they are discarded when ulwp is replaced on thr_exit() */ 2N/A * This is the size of a replacement ulwp, retained only for the benefit 2N/A * of thr_join(). The trailing members are unneeded for this purpose. 2N/A * Definitions for static initialization of signal sets, 2N/A * plus some sneaky optimizations in various places. 2N/A * pthread_atfork() related data, used to store atfork handlers. 2N/A void (*
parent)(
void);
/* post-fork parent handler */ 2N/A void (*
child)(
void);
/* post-fork child handler */ 2N/A * Element in the table and in the list of registered process 2N/A * robust locks. We keep track of these to make sure that we 2N/A * only call ___lwp_mutex_register() once for each such lock 2N/A * after it is first mapped in (or newly mapped in). 2N/A * Invalid address, used to mark an unused element in the hash table. 2N/A * Parameters of the lock registration hash table. 2N/A * Make our hot locks reside on private cache lines (64 bytes). 2N/A * Make our semi-hot locks reside on semi-private cache lines (32 bytes). 2N/A * The threads hash table is used for fast lookup and locking of an active 2N/A * thread structure (ulwp_t) given a thread-id. It is an N-element array of 2N/A * thr_hash_table_t structures, where N == 1 before the main thread creates 2N/A * the first additional thread and N == 1024 afterwards. Each element of the 2N/A * table is 64 bytes in size and alignment to reduce cache conflicts. 2N/A#
endif /* _SYSCALL32 */ 2N/A * siguaction members have 128-byte size and 64-byte alignment. 2N/A * We know that sizeof (struct sigaction) is 32 bytes for both 2N/A * _ILP32 and _LP64 and that sizeof (rwlock_t) is 64 bytes. 2N/A#
endif /* _SYSCALL32 */ 2N/A * Bucket structures, used by lmalloc()/lfree(). 2N/A * A bucket's size and alignment is 64 bytes. 2N/A char pad64[
64 -
/* pad out to 64 bytes */ 2N/A char pad64[
64 -
/* pad out to 64 bytes */ 2N/A#
endif /* _SYSCALL32 */ 2N/A#
define NBUCKETS 10 /* sizes ranging from 64 to 32768 */ 2N/A * atexit() data structures. 2N/A#
endif /* _SYSCALL32 */ 2N/A * This is data that is global to all link maps (uberdata, aka super-global). 2N/A * Every object before this point has size and alignment of 64 bytes. 2N/A * Don't add any other type of data before this point. 2N/A char *
progname;
/* the basename of the program, from argv[0] */ 2N/A * Grab and release the hash table lock for the specified lwp. 2N/A /* or pthread_detach() was called */ 2N/A /* per-thread copies of the corresponding global variables */ 2N/A /* 0 means there is but a single entry */ 2N/A union {
/* single entry or pointer to array */ 2N/A /* 0 means there is but a single entry */ 2N/A union {
/* single entry or pointer to array */ 2N/A /* PROBE_SUPPORT begin */ 2N/A /* PROBE_SUPPORT end */ 2N/A /* the following members *must* be last in the structure */ 2N/A /* they are discarded when ulwp is replaced on thr_exit() */ 2N/A#
endif /* _SYSCALL32 */ 2N/A * Implementation-specific attribute types for pthread_mutexattr_init() etc. 2N/A/* _curthread() is inline for speed */ 2N/A/* this version (also inline) can be tested for NULL */ 2N/A/* get the current stack pointer (also inline) */ 2N/A * Suppress __attribute__((...)) if we are not compiling with gcc 2N/A/* Fetch the dispatch (kernel) priority of a thread */ 2N/A * Implementation functions. Not visible outside of the library itself. 2N/A * Utility function used when waking up many threads (more than MAXLWPS) 2N/A * all at once. See mutex_wakeup_all(), cond_broadcast(), and rw_unlock(). 2N/A#
define MAXLWPS 128 /* max remembered lwpids before overflow */ 2N/A#
define NEWLWPS 2048 /* max remembered lwpids at first overflow */ 2N/A/* enter a critical section */ 2N/A/* exit a critical section, take deferred actions if necessary */ 2N/A * Like enter_critical()/exit_critical() but just for deferring signals. 2N/A * Unlike enter_critical()/exit_critical(), ul_sigdefer may be set while 2N/A * calling application functions like constructors and destructors. 2N/A * Care must be taken if the application function attempts to set 2N/A * the signal mask while a deferred signal is present; the setting 2N/A * of the signal mask must also be deferred. 2N/A/* these are exported functions */ 2N/A * When restoring the signal mask after having previously called 2N/A * block_all_signals(), if we have a deferred signal present then 2N/A * do nothing other than ASSERT() that we are in a critical region. 2N/A * The signal mask will be set when we emerge from the critical region 2N/A * and call take_deferred_signal(). There is no race condition here 2N/A * because the kernel currently has all signals blocked for this thread. 2N/A/* actual system call traps */ 2N/A/* not cancellation points: */ 2N/A * System call wrappers (direct interfaces to the kernel) 2N/A#
endif /* _THR_UBERDATA_H */