1 /* Linuxthreads - a simple clone()-based implementation of Posix        */
2 /* threads for Linux.                                                   */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
4 /*                                                                      */
5 /* This program is free software; you can redistribute it and/or        */
6 /* modify it under the terms of the GNU Library General Public License  */
7 /* as published by the Free Software Foundation; either version 2       */
8 /* of the License, or (at your option) any later version.               */
9 /*                                                                      */
10 /* This program 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        */
13 /* GNU Library General Public License for more details.                 */
14 
15 #ifndef _DESCR_H
16 #define _DESCR_H	1
17 
18 #define __need_res_state
19 #include <resolv.h>
20 #include <setjmp.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <tls.h>
24 #include <l4/sys/utcb.h>
25 #include <pt-machine.h>
26 #include <sched.h>
27 /* The type of thread descriptors */
28 typedef struct pthread *pthread_descr;
29 
30 
31 
32 /* Arguments passed to thread creation routine */
33 struct pthread_start_args {
34   void *(*start_routine)(void *); /* function to run */
35   void *arg;                      /* its argument */
36 };
37 
38 
39 /* Callback interface for removing the thread from waiting on an
40    object if it is cancelled while waiting or about to wait.
41    This hold a pointer to the object, and a pointer to a function
42    which ``extricates'' the thread from its enqueued state.
43    The function takes two arguments: pointer to the wait object,
44    and a pointer to the thread. It returns 1 if an extrication
45    actually occured, and hence the thread must also be signalled.
46    It returns 0 if the thread had already been extricated. */
47 typedef struct _pthread_extricate_struct {
48     void *pu_object;
49     int (*pu_extricate_func)(void *, pthread_descr);
50 } pthread_extricate_if;
51 
52 
53 /* Atomic counter made possible by compare_and_swap */
54 struct pthread_atomic {
55   long p_count;
56   int p_spinlock;
57 };
58 
59 
60 /* Context info for read write locks. The pthread_rwlock_info structure
61    is information about a lock that has been read-locked by the thread
62    in whose list this structure appears. The pthread_rwlock_context
63    is embedded in the thread context and contains a pointer to the
64    head of the list of lock info structures, as well as a count of
65    read locks that are untracked, because no info structure could be
66    allocated for them. */
67 struct _pthread_rwlock_t;
68 typedef struct _pthread_rwlock_info {
69   struct _pthread_rwlock_info *pr_next;
70   struct _pthread_rwlock_t *pr_lock;
71   int pr_lock_count;
72 } pthread_readlock_info;
73 
74 #ifndef TCB_ALIGNMENT
75 # define TCB_ALIGNMENT	sizeof (double)
76 #endif
77 
78 
79 /* We keep thread specific data in a special data structure, a two-level
80    array.  The top-level array contains pointers to dynamically allocated
81    arrays of a certain number of data pointers.  So we can implement a
82    sparse array.  Each dynamic second-level array has
83         PTHREAD_KEY_2NDLEVEL_SIZE
84    entries.  This value shouldn't be too large.  */
85 #define PTHREAD_KEY_2NDLEVEL_SIZE       32
86 
87 /* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE
88    keys in each subarray.  */
89 #define PTHREAD_KEY_1STLEVEL_SIZE \
90   ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
91    / PTHREAD_KEY_2NDLEVEL_SIZE)
92 
93 
94 union dtv;
95 
96 struct pthread
97 {
98   union
99   {
100 #if !defined(TLS_DTV_AT_TP)
101     /* This overlaps the TCB as used for TLS without threads (see tls.h).  */
102     tcbhead_t header;
103 #else
104     struct
105     {
106       int multiple_threads;
107       int gscope_flag;
108 # ifndef CONFIG_L4
109 # ifndef __ASSUME_PRIVATE_FUTEX
110       int private_futex;
111 # endif
112 # endif
113     } header;
114 #endif
115 
116     /* This extra padding has no special purpose, and this structure layout
117        is private and subject to change without affecting the official ABI.
118        We just have it here in case it might be convenient for some
119        implementation-specific instrumentation hack or suchlike.  */
120     void *__padding[24];
121   };
122 
123   pthread_descr p_nextlive, p_prevlive;
124                                 /* Double chaining of active threads */
125   pthread_descr p_nextwaiting;  /* Next element in the queue holding the thr */
126   pthread_descr p_nextlock;	/* can be on a queue and waiting on a lock */
127   pthread_t p_tid;              /* Thread identifier */
128 
129   int p_priority;               /* Thread priority (== 0 if not realtime) */
130   int p_sched_policy;
131   __cpu_mask p_affinity_mask[1]; /* L4 addition; small, more needs dynamic allocations */
132 
133 
134   l4_cap_idx_t     p_thsem_cap;
135   l4_cap_idx_t     p_th_cap;
136   struct _pthread_fastlock * p_lock; /* Spinlock for synchronized accesses */
137   sigjmp_buf * p_cancel_jmp;    /* where to siglongjmp on a cancel or NULL */
138   char p_terminated;            /* true if terminated e.g. by pthread_exit */
139   char p_detached;              /* true if detached */
140   char p_exited;                /* true if the assoc. process terminated */
141   void * p_retval;              /* placeholder for return value */
142   int p_retcode;                /* placeholder for return code */
143   pthread_descr p_joining;      /* thread joining on that thread or NULL */
144   struct _pthread_cleanup_buffer * p_cleanup; /* cleanup functions */
145   char p_cancelstate;           /* cancellation state */
146   char p_canceltype;            /* cancellation type (deferred/async) */
147   char p_canceled;              /* cancellation request pending */
148   struct pthread_start_args p_start_args; /* arguments for thread creation */
149   void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */
150 #if !(USE_TLS && HAVE___THREAD)
151   void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */
152   int * p_errnop;               /* pointer to used errno variable */
153   int p_errno;                  /* error returned by last system call */
154   int * p_h_errnop;             /* pointer to used h_errno variable */
155   int p_h_errno;                /* error returned by last netdb function */
156   struct __res_state *p_resp;	/* Pointer to resolver state */
157 #endif
158   struct __res_state p_res;	/* per-thread resolver state */
159   int p_userstack;		/* nonzero if the user provided the stack */
160   void *p_guardaddr;		/* address of guard area or NULL */
161   size_t p_guardsize;		/* size of guard area */
162   struct pthread_atomic p_resume_count; /* number of times restart() was
163 					   called on thread */
164   char p_woken_by_cancel;       /* cancellation performed wakeup */
165   char p_condvar_avail;		/* flag if conditional variable became avail */
166   char p_sem_avail;             /* flag if semaphore became available */
167   pthread_extricate_if *p_extricate; /* See above */
168   pthread_readlock_info *p_readlock_list;  /* List of readlock info structs */
169   pthread_readlock_info *p_readlock_free;  /* Free list of structs */
170   int p_untracked_readlock_count;	/* Readlocks not tracked by list */
171   int p_inheritsched;           /* copied from the thread attribute */
172 #ifdef USE_TLS
173   char *p_stackaddr;		/* Stack address.  */
174 #endif
175   size_t p_alloca_cutoff;	/* Maximum size which should be allocated
176 				   using alloca() instead of malloc().  */
177   /* New elements must be added at the end.  */
178 } __attribute__ ((aligned (TCB_ALIGNMENT)));
179 
180 
181 
182 /* Limit between the stack of the initial thread (above) and the
183    stacks of other threads (below). Aligned on a STACK_SIZE boundary.
184    Initially 0, meaning that the current thread is (by definition)
185    the initial thread. */
186 
187 extern char *__pthread_initial_thread_bos;
188 
189 /* Descriptor of the initial thread */
190 
191 extern struct pthread __pthread_initial_thread;
192 
193 /* Limits of the thread manager stack. */
194 
195 extern char *__pthread_manager_thread_bos;
196 extern char *__pthread_manager_thread_tos;
197 
198 /* Descriptor of the manager thread */
199 
200 extern struct pthread __pthread_manager_thread;
201 extern pthread_descr __pthread_manager_threadp L4_HIDDEN;
202 
203 /* Indicate whether at least one thread has a user-defined stack (if 1),
204    or all threads have stacks supplied by LinuxThreads (if 0). */
205 
206 extern int __pthread_nonstandard_stacks;
207 
208 /* The max size of the thread stack segments.  If the default
209    THREAD_SELF implementation is used, this must be a power of two and
210    a multiple of PAGE_SIZE.  */
211 #ifndef STACK_SIZE
212 #define STACK_SIZE  (2 * 1024 * 1024)
213 #endif
214 
215 /* Get some notion of the current stack.  Need not be exactly the top
216    of the stack, just something somewhere in the current frame.  */
217 #ifndef CURRENT_STACK_FRAME
218 #define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
219 #endif
220 
221 /* Recover thread descriptor for the current thread */
222 
223 extern pthread_descr __pthread_find_self (void) __attribute__ ((pure));
224 
225 static __inline__ pthread_descr thread_self (void) __attribute__ ((pure));
thread_self(void)226 static __inline__ pthread_descr thread_self (void)
227 { return (pthread_descr)(l4_utcb_tcr()->user[0]); }
228 
229 #endif	/* descr.h */
230