(linenum→info "unix/slp.c:2238")

glibc/2.7/nptl/descr.h

    1: /* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3:    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #ifndef _DESCR_H
   21: #define _DESCR_H        1
   22: 
   23: #include <limits.h>
   24: #include <sched.h>
   25: #include <setjmp.h>
   26: #include <stdbool.h>
   27: #include <sys/types.h>
   28: #include <hp-timing.h>
   29: #include <list.h>
   30: #include <lowlevellock.h>
   31: #include <pthreaddef.h>
   32: #include <dl-sysdep.h>
   33: #include "../nptl_db/thread_db.h"
   34: #include <tls.h>
   35: #ifdef HAVE_FORCED_UNWIND
   36: # include <unwind.h>
   37: #endif
   38: #define __need_res_state
   39: #include <resolv.h>
   40: #include <kernel-features.h>
   41: 
   42: #ifndef TCB_ALIGNMENT
   43: # define TCB_ALIGNMENT  sizeof (double)
   44: #endif
   45: 
   46: 
   47: /* We keep thread specific data in a special data structure, a two-level
   48:    array.  The top-level array contains pointers to dynamically allocated
   49:    arrays of a certain number of data pointers.  So we can implement a
   50:    sparse array.  Each dynamic second-level array has
   51:         PTHREAD_KEY_2NDLEVEL_SIZE
   52:    entries.  This value shouldn't be too large.  */
   53: #define PTHREAD_KEY_2NDLEVEL_SIZE       32
   54: 
   55: /* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE
   56:    keys in each subarray.  */
   57: #define PTHREAD_KEY_1STLEVEL_SIZE \
   58:   ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
   59:    / PTHREAD_KEY_2NDLEVEL_SIZE)
   60: 
   61: 
   62: 
   63: 
   64: /* Internal version of the buffer to store cancellation handler
   65:    information.  */
   66: struct pthread_unwind_buf
   67: {
   68:   struct
   69:   {
   70:     __jmp_buf jmp_buf;
   71:     int mask_was_saved;
   72:   } cancel_jmp_buf[1];
   73: 
   74:   union
   75:   {
   76:     /* This is the placeholder of the public version.  */
   77:     void *pad[4];
   78: 
   79:     struct
   80:     {
   81:       /* Pointer to the previous cleanup buffer.  */
   82:       struct pthread_unwind_buf *prev;
   83: 
   84:       /* Backward compatibility: state of the old-style cleanup
   85:          handler at the time of the previous new-style cleanup handler
   86:          installment.  */
   87:       struct _pthread_cleanup_buffer *cleanup;
   88: 
   89:       /* Cancellation type before the push call.  */
   90:       int canceltype;
   91:     } data;
   92:   } priv;
   93: };
   94: 
   95: 
   96: /* Opcodes and data types for communication with the signal handler to
   97:    change user/group IDs.  */
   98: struct xid_command
   99: {
  100:   int syscall_no;
  101:   long int id[3];
  102:   volatile int cntr;
  103: };
  104: 
  105: 
  106: /* Data structure used by the kernel to find robust futexes.  */
  107: struct robust_list_head
  108: {
  109:   void *list;
  110:   long int futex_offset;
  111:   void *list_op_pending;
  112: };
  113: 
  114: 
  115: /* Data strcture used to handle thread priority protection.  */
  116: struct priority_protection_data
  117: {
  118:   int priomax;
  119:   unsigned int priomap[];
  120: };
  121: 
  122: 
  123: /* Thread descriptor data structure.  */
  124: struct pthread
  125: {
  126:   union
  127:   {
  128: #if !TLS_DTV_AT_TP
  129:     /* This overlaps the TCB as used for TLS without threads (see tls.h).  */
  130:     tcbhead_t header;
  131: #else
  132:     struct
  133:     {
  134:       int multiple_threads;
  135:       int gscope_flag;
  136: # ifndef __ASSUME_PRIVATE_FUTEX
  137:       int private_futex;
  138: # endif
  139:     } header;
  140: #endif
  141: 
  142:     /* This extra padding has no special purpose, and this structure layout
  143:        is private and subject to change without affecting the official ABI.
  144:        We just have it here in case it might be convenient for some
  145:        implementation-specific instrumentation hack or suchlike.  */
  146:     void *__padding[16];
  147:   };
  148: 
  149:   /* This descriptor's link on the `stack_used' or `__stack_user' list.  */
  150:   list_t list;
  151: 
  152:   /* Thread ID - which is also a 'is this thread descriptor (and
  153:      therefore stack) used' flag.  */
  154:   pid_t tid;
  155: 
  156:   /* Process ID - thread group ID in kernel speak.  */
  157:   pid_t pid;
  158: 
  159:   /* List of robust mutexes the thread is holding.  */
  160: #ifdef __PTHREAD_MUTEX_HAVE_PREV
  161:   void *robust_prev;
  162:   struct robust_list_head robust_head;
  163: 
  164:   /* The list above is strange.  It is basically a double linked list
  165:      but the pointer to the next/previous element of the list points
  166:      in the middle of the object, the __next element.  Whenever
  167:      casting to __pthread_list_t we need to adjust the pointer
  168:      first.  */
  169: # define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
  170: 
  171: # define ENQUEUE_MUTEX_BOTH(mutex, val)                                       \
  172:   do {                                                                        \
  173:     __pthread_list_t *next = (__pthread_list_t *)                             \
  174:       ((((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_head.list)) & ~1ul)   \
  175:        - QUEUE_PTR_ADJUST);                                                   \
  176:     next->__prev = (void *) &mutex->__data.__list.__next;                     \
  177:     mutex->__data.__list.__next = THREAD_GETMEM (THREAD_SELF,                 \
  178:                                                  robust_head.list);             \
  179:     mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head;         \
  180:     THREAD_SETMEM (THREAD_SELF, robust_head.list,                             \
  181:                    (void *) (((uintptr_t) &mutex->__data.__list.__next)             \
  182:                              | val));                                              \
  183:   } while (0)
  184: # define DEQUEUE_MUTEX(mutex) \
  185:   do {                                                                        \
  186:     __pthread_list_t *next = (__pthread_list_t *)                             \
  187:       ((char *) (((uintptr_t) mutex->__data.__list.__next) & ~1ul)            \
  188:        - QUEUE_PTR_ADJUST);                                                   \
  189:     next->__prev = mutex->__data.__list.__prev;                               \
  190:     __pthread_list_t *prev = (__pthread_list_t *)                             \
  191:       ((char *) (((uintptr_t) mutex->__data.__list.__prev) & ~1ul)            \
  192:        - QUEUE_PTR_ADJUST);                                                   \
  193:     prev->__next = mutex->__data.__list.__next;                               \
  194:     mutex->__data.__list.__prev = NULL;                                       \
  195:     mutex->__data.__list.__next = NULL;                                       \
  196:   } while (0)
  197: #else
  198:   union
  199:   {
  200:     __pthread_slist_t robust_list;
  201:     struct robust_list_head robust_head;
  202:   };
  203: 
  204: # define ENQUEUE_MUTEX_BOTH(mutex, val)                                       \
  205:   do {                                                                        \
  206:     mutex->__data.__list.__next                                               \
  207:       = THREAD_GETMEM (THREAD_SELF, robust_list.__next);                      \
  208:     THREAD_SETMEM (THREAD_SELF, robust_list.__next,                           \
  209:                    (void *) (((uintptr_t) &mutex->__data.__list) | val));     \
  210:   } while (0)
  211: # define DEQUEUE_MUTEX(mutex) \
  212:   do {                                                                        \
  213:     __pthread_slist_t *runp = (__pthread_slist_t *)                           \
  214:       (((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_list.__next)) & ~1ul); \
  215:     if (runp == &mutex->__data.__list)                                        \
  216:       THREAD_SETMEM (THREAD_SELF, robust_list.__next, runp->__next);          \
  217:     else                                                                      \
  218:       {                                                                       \
  219:         __pthread_slist_t *next = (__pthread_slist_t *)                      \
  220:           (((uintptr_t) runp->__next) & ~1ul);                               \
  221:         while (next != &mutex->__data.__list)                                \
  222:           {                                                                  \
  223:             runp = next;                                                     \
  224:             next = (__pthread_slist_t *) (((uintptr_t) runp->__next) & ~1ul); \
  225:           }                                                                  \
  226:                                                                               \
  227:         runp->__next = next->__next;                                         \
  228:         mutex->__data.__list.__next = NULL;                                  \
  229:       }                                                                       \
  230:   } while (0)
  231: #endif
  232: #define ENQUEUE_MUTEX(mutex) ENQUEUE_MUTEX_BOTH (mutex, 0)
  233: #define ENQUEUE_MUTEX_PI(mutex) ENQUEUE_MUTEX_BOTH (mutex, 1)
  234: 
  235:   /* List of cleanup buffers.  */
  236:   struct _pthread_cleanup_buffer *cleanup;
  237: 
  238:   /* Unwind information.  */
  239:   struct pthread_unwind_buf *cleanup_jmp_buf;
  240: #define HAVE_CLEANUP_JMP_BUF
  241: 
  242:   /* Flags determining processing of cancellation.  */
  243:   int cancelhandling;
  244:   /* Bit set if cancellation is disabled.  */
  245: #define CANCELSTATE_BIT         0
  246: #define CANCELSTATE_BITMASK     0x01
  247:   /* Bit set if asynchronous cancellation mode is selected.  */
  248: #define CANCELTYPE_BIT          1
  249: #define CANCELTYPE_BITMASK      0x02
  250:   /* Bit set if canceling has been initiated.  */
  251: #define CANCELING_BIT           2
  252: #define CANCELING_BITMASK       0x04
  253:   /* Bit set if canceled.  */
  254: #define CANCELED_BIT            3
  255: #define CANCELED_BITMASK        0x08
  256:   /* Bit set if thread is exiting.  */
  257: #define EXITING_BIT             4
  258: #define EXITING_BITMASK         0x10
  259:   /* Bit set if thread terminated and TCB is freed.  */
  260: #define TERMINATED_BIT          5
  261: #define TERMINATED_BITMASK      0x20
  262:   /* Bit set if thread is supposed to change XID.  */
  263: #define SETXID_BIT              6
  264: #define SETXID_BITMASK          0x40
  265:   /* Mask for the rest.  Helps the compiler to optimize.  */
  266: #define CANCEL_RESTMASK         0xffffff80
  267: 
  268: #define CANCEL_ENABLED_AND_CANCELED(value) \
  269:   (((value) & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK       \
  270:                | CANCEL_RESTMASK | TERMINATED_BITMASK)) == CANCELED_BITMASK)
  271: #define CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS(value) \
  272:   (((value) & (CANCELSTATE_BITMASK | CANCELTYPE_BITMASK | CANCELED_BITMASK    \
  273:                | EXITING_BITMASK | CANCEL_RESTMASK | TERMINATED_BITMASK))     \
  274:    == (CANCELTYPE_BITMASK | CANCELED_BITMASK))
  275: 
  276:   /* Flags.  Including those copied from the thread attribute.  */
  277:   int flags;
  278: 
  279:   /* We allocate one block of references here.  This should be enough
  280:      to avoid allocating any memory dynamically for most applications.  */
  281:   struct pthread_key_data
  282:   {
  283:     /* Sequence number.  We use uintptr_t to not require padding on
  284:        32- and 64-bit machines.  On 64-bit machines it helps to avoid
  285:        wrapping, too.  */
  286:     uintptr_t seq;
  287: 
  288:     /* Data pointer.  */
  289:     void *data;
  290:   } specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
  291: 
  292:   /* Two-level array for the thread-specific data.  */
  293:   struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
  294: 
  295:   /* Flag which is set when specific data is set.  */
  296:   bool specific_used;
  297: 
  298:   /* True if events must be reported.  */
  299:   bool report_events;
  300: 
  301:   /* True if the user provided the stack.  */
  302:   bool user_stack;
  303: 
  304:   /* True if thread must stop at startup time.  */
  305:   bool stopped_start;
  306: 
  307:   /* The parent's cancel handling at the time of the pthread_create
  308:      call.  This might be needed to undo the effects of a cancellation.  */
  309:   int parent_cancelhandling;
  310: 
  311:   /* Lock to synchronize access to the descriptor.  */
  312:   int lock;
  313: 
  314:   /* Lock for synchronizing setxid calls.  */
  315:   int setxid_futex;
  316: 
  317: #if HP_TIMING_AVAIL
  318:   /* Offset of the CPU clock at start thread start time.  */
  319:   hp_timing_t cpuclock_offset;
  320: #endif
  321: 
  322:   /* If the thread waits to join another one the ID of the latter is
  323:      stored here.
  324: 
  325:      In case a thread is detached this field contains a pointer of the
  326:      TCB if the thread itself.  This is something which cannot happen
  327:      in normal operation.  */
  328:   struct pthread *joinid;
  329:   /* Check whether a thread is detached.  */
  330: #define IS_DETACHED(pd) ((pd)->joinid == (pd))
  331: 
  332:   /* The result of the thread function.  */
  333:   void *result;
  334: 
  335:   /* Scheduling parameters for the new thread.  */
  336:   struct sched_param schedparam;
  337:   int schedpolicy;
  338: 
  339:   /* Start position of the code to be executed and the argument passed
  340:      to the function.  */
  341:   void *(*start_routine) (void *);
  342:   void *arg;
  343: 
  344:   /* Debug state.  */
  345:   td_eventbuf_t eventbuf;
  346:   /* Next descriptor with a pending event.  */
  347:   struct pthread *nextevent;
  348: 
  349: #ifdef HAVE_FORCED_UNWIND
  350:   /* Machine-specific unwind info.  */
  351:   struct _Unwind_Exception exc;
  352: #endif
  353: 
  354:   /* If nonzero pointer to area allocated for the stack and its
  355:      size.  */
  356:   void *stackblock;
  357:   size_t stackblock_size;
  358:   /* Size of the included guard area.  */
  359:   size_t guardsize;
  360:   /* This is what the user specified and what we will report.  */
  361:   size_t reported_guardsize;
  362: 
  363:   /* Thread Priority Protection data.  */
  364:   struct priority_protection_data *tpp;
  365: 
  366:   /* Resolver state.  */
  367:   struct __res_state res;
  368: 
  369:   /* This member must be last.  */
  370:   char end_padding[];
  371: 
  372: #define PTHREAD_STRUCT_END_PADDING \
  373:   (sizeof (struct pthread) - offsetof (struct pthread, end_padding))
  374: } __attribute ((aligned (TCB_ALIGNMENT)));
  375: 
  376: 
  377: #endif  /* descr.h */
Syntax (Markdown)