Back to index

glibc  2.9
descr.h
Go to the documentation of this file.
00001 /* Linuxthreads - a simple clone()-based implementation of Posix        */
00002 /* threads for Linux.                                                   */
00003 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
00004 /*                                                                      */
00005 /* This program is free software; you can redistribute it and/or        */
00006 /* modify it under the terms of the GNU Library General Public License  */
00007 /* as published by the Free Software Foundation; either version 2       */
00008 /* of the License, or (at your option) any later version.               */
00009 /*                                                                      */
00010 /* This program is distributed in the hope that it will be useful,      */
00011 /* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
00012 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
00013 /* GNU Library General Public License for more details.                 */
00014 
00015 #ifndef _DESCR_H
00016 #define _DESCR_H     1
00017 
00018 #define __need_res_state
00019 #include <resolv.h>
00020 #include <sched.h>
00021 #include <setjmp.h>
00022 #include <signal.h>
00023 #include <stdint.h>
00024 #include <sys/types.h>
00025 #include <hp-timing.h>
00026 #include <tls.h>
00027 
00028 /* Fast thread-specific data internal to libc.  */
00029 enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
00030                      _LIBC_TSD_KEY_DL_ERROR,
00031                      _LIBC_TSD_KEY_RPC_VARS,
00032                      _LIBC_TSD_KEY_LOCALE,
00033                      _LIBC_TSD_KEY_CTYPE_B,
00034                      _LIBC_TSD_KEY_CTYPE_TOLOWER,
00035                      _LIBC_TSD_KEY_CTYPE_TOUPPER,
00036                      _LIBC_TSD_KEY_N };
00037 
00038 /* The type of thread descriptors */
00039 typedef struct _pthread_descr_struct *pthread_descr;
00040 
00041 
00042 /* Some more includes.  */
00043 #include <pt-machine.h>
00044 #include <linuxthreads_db/thread_dbP.h>
00045 
00046 
00047 /* Arguments passed to thread creation routine */
00048 struct pthread_start_args {
00049   void *(*start_routine)(void *); /* function to run */
00050   void *arg;                      /* its argument */
00051   sigset_t mask;                  /* initial signal mask for thread */
00052   int schedpolicy;                /* initial scheduling policy (if any) */
00053   struct sched_param schedparam;  /* initial scheduling parameters (if any) */
00054 };
00055 
00056 
00057 /* Callback interface for removing the thread from waiting on an
00058    object if it is cancelled while waiting or about to wait.
00059    This hold a pointer to the object, and a pointer to a function
00060    which ``extricates'' the thread from its enqueued state.
00061    The function takes two arguments: pointer to the wait object,
00062    and a pointer to the thread. It returns 1 if an extrication
00063    actually occured, and hence the thread must also be signalled.
00064    It returns 0 if the thread had already been extricated. */
00065 typedef struct _pthread_extricate_struct {
00066     void *pu_object;
00067     int (*pu_extricate_func)(void *, pthread_descr);
00068 } pthread_extricate_if;
00069 
00070 
00071 /* Atomic counter made possible by compare_and_swap */
00072 struct pthread_atomic {
00073   long p_count;
00074   int p_spinlock;
00075 };
00076 
00077 
00078 /* Context info for read write locks. The pthread_rwlock_info structure
00079    is information about a lock that has been read-locked by the thread
00080    in whose list this structure appears. The pthread_rwlock_context
00081    is embedded in the thread context and contains a pointer to the
00082    head of the list of lock info structures, as well as a count of
00083    read locks that are untracked, because no info structure could be
00084    allocated for them. */
00085 struct _pthread_rwlock_t;
00086 typedef struct _pthread_rwlock_info {
00087   struct _pthread_rwlock_info *pr_next;
00088   struct _pthread_rwlock_t *pr_lock;
00089   int pr_lock_count;
00090 } pthread_readlock_info;
00091 
00092 
00093 /* We keep thread specific data in a special data structure, a two-level
00094    array.  The top-level array contains pointers to dynamically allocated
00095    arrays of a certain number of data pointers.  So we can implement a
00096    sparse array.  Each dynamic second-level array has
00097        PTHREAD_KEY_2NDLEVEL_SIZE
00098    entries.  This value shouldn't be too large.  */
00099 #define PTHREAD_KEY_2NDLEVEL_SIZE  32
00100 
00101 /* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE
00102    keys in each subarray.  */
00103 #define PTHREAD_KEY_1STLEVEL_SIZE \
00104   ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
00105    / PTHREAD_KEY_2NDLEVEL_SIZE)
00106 
00107 
00108 union dtv;
00109 
00110 struct _pthread_descr_struct
00111 {
00112 #if !defined USE_TLS || !TLS_DTV_AT_TP || INCLUDE_TLS_PADDING
00113   /* This overlaps tcbhead_t (see tls.h), as used for TLS without threads.  */
00114   union
00115   {
00116     struct
00117     {
00118       void *tcb;            /* Pointer to the TCB.  This is not always
00119                                the address of this thread descriptor.  */
00120       union dtv *dtvp;
00121       pthread_descr self;   /* Pointer to this structure */
00122       int multiple_threads;
00123       uintptr_t sysinfo;
00124       uintptr_t stack_guard;
00125       uintptr_t pointer_guard;
00126     } data;
00127     void *__padding[16];
00128   } p_header;
00129 # define p_multiple_threads p_header.data.multiple_threads
00130 #elif TLS_MULTIPLE_THREADS_IN_TCB
00131   int p_multiple_threads;
00132 #endif
00133 
00134   pthread_descr p_nextlive, p_prevlive;
00135                                 /* Double chaining of active threads */
00136   pthread_descr p_nextwaiting;  /* Next element in the queue holding the thr */
00137   pthread_descr p_nextlock; /* can be on a queue and waiting on a lock */
00138   pthread_t p_tid;              /* Thread identifier */
00139   int p_pid;                    /* PID of Unix process */
00140   int p_priority;               /* Thread priority (== 0 if not realtime) */
00141   struct _pthread_fastlock * p_lock; /* Spinlock for synchronized accesses */
00142   int p_signal;                 /* last signal received */
00143   sigjmp_buf * p_signal_jmp;    /* where to siglongjmp on a signal or NULL */
00144   sigjmp_buf * p_cancel_jmp;    /* where to siglongjmp on a cancel or NULL */
00145   char p_terminated;            /* true if terminated e.g. by pthread_exit */
00146   char p_detached;              /* true if detached */
00147   char p_exited;                /* true if the assoc. process terminated */
00148   void * p_retval;              /* placeholder for return value */
00149   int p_retcode;                /* placeholder for return code */
00150   pthread_descr p_joining;      /* thread joining on that thread or NULL */
00151   struct _pthread_cleanup_buffer * p_cleanup; /* cleanup functions */
00152   char p_cancelstate;           /* cancellation state */
00153   char p_canceltype;            /* cancellation type (deferred/async) */
00154   char p_canceled;              /* cancellation request pending */
00155   char * p_in_sighandler;       /* stack address of sighandler, or NULL */
00156   char p_sigwaiting;            /* true if a sigwait() is in progress */
00157   struct pthread_start_args p_start_args; /* arguments for thread creation */
00158   void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */
00159 #if !(USE_TLS && HAVE___THREAD)
00160   void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */
00161   int * p_errnop;               /* pointer to used errno variable */
00162   int p_errno;                  /* error returned by last system call */
00163   int * p_h_errnop;             /* pointer to used h_errno variable */
00164   int p_h_errno;                /* error returned by last netdb function */
00165   struct __res_state *p_resp;      /* Pointer to resolver state */
00166 #endif
00167   struct __res_state p_res; /* per-thread resolver state */
00168   int p_userstack;          /* nonzero if the user provided the stack */
00169   void *p_guardaddr;        /* address of guard area or NULL */
00170   size_t p_guardsize;              /* size of guard area */
00171   int p_nr;                     /* Index of descriptor in __pthread_handles */
00172   int p_report_events;             /* Nonzero if events must be reported.  */
00173   td_eventbuf_t p_eventbuf;     /* Data for event.  */
00174   struct pthread_atomic p_resume_count; /* number of times restart() was
00175                                       called on thread */
00176   char p_woken_by_cancel;       /* cancellation performed wakeup */
00177   char p_condvar_avail;            /* flag if conditional variable became avail */
00178   char p_sem_avail;             /* flag if semaphore became available */
00179   pthread_extricate_if *p_extricate; /* See above */
00180   pthread_readlock_info *p_readlock_list;  /* List of readlock info structs */
00181   pthread_readlock_info *p_readlock_free;  /* Free list of structs */
00182   int p_untracked_readlock_count;  /* Readlocks not tracked by list */
00183   int p_inheritsched;           /* copied from the thread attribute */
00184 #if HP_TIMING_AVAIL
00185   hp_timing_t p_cpuclock_offset; /* Initial CPU clock for thread.  */
00186 #endif
00187 #ifdef USE_TLS
00188   char *p_stackaddr;        /* Stack address.  */
00189 #endif
00190   size_t p_alloca_cutoff;   /* Maximum size which should be allocated
00191                                using alloca() instead of malloc().  */
00192   /* New elements must be added at the end.  */
00193 
00194   /* This member must be last.  */
00195   char end_padding[];
00196 
00197 #define PTHREAD_STRUCT_END_PADDING \
00198   (sizeof (struct _pthread_descr_struct)                      \
00199    - offsetof (struct _pthread_descr_struct, end_padding))
00200 } __attribute__ ((aligned(32))); /* We need to align the structure so that
00201                                 doubles are aligned properly.  This is 8
00202                                 bytes on MIPS and 16 bytes on MIPS64.
00203                                 32 bytes might give better cache
00204                                 utilization.  */
00205 
00206 
00207 
00208 /* Limit between the stack of the initial thread (above) and the
00209    stacks of other threads (below). Aligned on a STACK_SIZE boundary.
00210    Initially 0, meaning that the current thread is (by definition)
00211    the initial thread. */
00212 
00213 extern char *__pthread_initial_thread_bos;
00214 
00215 /* Descriptor of the initial thread */
00216 
00217 extern struct _pthread_descr_struct __pthread_initial_thread;
00218 
00219 /* Limits of the thread manager stack. */
00220 
00221 extern char *__pthread_manager_thread_bos;
00222 extern char *__pthread_manager_thread_tos;
00223 
00224 /* Descriptor of the manager thread */
00225 
00226 extern struct _pthread_descr_struct __pthread_manager_thread;
00227 extern pthread_descr __pthread_manager_threadp attribute_hidden;
00228 
00229 /* Indicate whether at least one thread has a user-defined stack (if 1),
00230    or all threads have stacks supplied by LinuxThreads (if 0). */
00231 
00232 extern int __pthread_nonstandard_stacks;
00233 
00234 /* The max size of the thread stack segments.  If the default
00235    THREAD_SELF implementation is used, this must be a power of two and
00236    a multiple of PAGE_SIZE.  */
00237 #ifndef STACK_SIZE
00238 #define STACK_SIZE  (2 * 1024 * 1024)
00239 #endif
00240 
00241 /* Get some notion of the current stack.  Need not be exactly the top
00242    of the stack, just something somewhere in the current frame.  */
00243 #ifndef CURRENT_STACK_FRAME
00244 #define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
00245 #endif
00246 
00247 /* Recover thread descriptor for the current thread */
00248 
00249 extern pthread_descr __pthread_find_self (void) __attribute__ ((pure));
00250 
00251 static inline pthread_descr thread_self (void) __attribute__ ((pure));
00252 static inline pthread_descr thread_self (void)
00253 {
00254 #ifdef THREAD_SELF
00255   return THREAD_SELF;
00256 #else
00257   char *sp = CURRENT_STACK_FRAME;
00258   if (sp >= __pthread_initial_thread_bos)
00259     return &__pthread_initial_thread;
00260   else if (sp >= __pthread_manager_thread_bos
00261           && sp < __pthread_manager_thread_tos)
00262     return &__pthread_manager_thread;
00263   else if (__pthread_nonstandard_stacks)
00264     return __pthread_find_self();
00265   else
00266 #ifdef _STACK_GROWS_DOWN
00267     return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
00268 #else
00269     return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1));
00270 #endif
00271 #endif
00272 }
00273 
00274 #endif /* descr.h */