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