]>
Commit | Line | Data |
---|---|---|
535b764d UD |
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 <sched.h> | |
21 | #include <setjmp.h> | |
22 | #include <signal.h> | |
131fd126 | 23 | #include <stdint.h> |
535b764d UD |
24 | #include <sys/types.h> |
25 | #include <hp-timing.h> | |
bb0ddc2f | 26 | #include <tls.h> |
535b764d | 27 | |
270d9d47 UD |
28 | /* Fast thread-specific data internal to libc. */ |
29 | enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, | |
30 | _LIBC_TSD_KEY_DL_ERROR, | |
31 | _LIBC_TSD_KEY_RPC_VARS, | |
32 | _LIBC_TSD_KEY_LOCALE, | |
33 | _LIBC_TSD_KEY_CTYPE_B, | |
34 | _LIBC_TSD_KEY_CTYPE_TOLOWER, | |
35 | _LIBC_TSD_KEY_CTYPE_TOUPPER, | |
36 | _LIBC_TSD_KEY_N }; | |
535b764d UD |
37 | |
38 | /* The type of thread descriptors */ | |
39 | typedef struct _pthread_descr_struct *pthread_descr; | |
40 | ||
41 | ||
42 | /* Some more includes. */ | |
43 | #include <pt-machine.h> | |
44 | #include <linuxthreads_db/thread_dbP.h> | |
45 | ||
46 | ||
47 | /* Arguments passed to thread creation routine */ | |
48 | struct pthread_start_args { | |
49 | void *(*start_routine)(void *); /* function to run */ | |
50 | void *arg; /* its argument */ | |
51 | sigset_t mask; /* initial signal mask for thread */ | |
52 | int schedpolicy; /* initial scheduling policy (if any) */ | |
53 | struct sched_param schedparam; /* initial scheduling parameters (if any) */ | |
54 | }; | |
55 | ||
56 | ||
57 | /* Callback interface for removing the thread from waiting on an | |
58 | object if it is cancelled while waiting or about to wait. | |
59 | This hold a pointer to the object, and a pointer to a function | |
60 | which ``extricates'' the thread from its enqueued state. | |
61 | The function takes two arguments: pointer to the wait object, | |
62 | and a pointer to the thread. It returns 1 if an extrication | |
63 | actually occured, and hence the thread must also be signalled. | |
64 | It returns 0 if the thread had already been extricated. */ | |
65 | typedef struct _pthread_extricate_struct { | |
66 | void *pu_object; | |
67 | int (*pu_extricate_func)(void *, pthread_descr); | |
68 | } pthread_extricate_if; | |
69 | ||
70 | ||
71 | /* Atomic counter made possible by compare_and_swap */ | |
72 | struct pthread_atomic { | |
73 | long p_count; | |
74 | int p_spinlock; | |
75 | }; | |
76 | ||
77 | ||
78 | /* Context info for read write locks. The pthread_rwlock_info structure | |
79 | is information about a lock that has been read-locked by the thread | |
80 | in whose list this structure appears. The pthread_rwlock_context | |
81 | is embedded in the thread context and contains a pointer to the | |
82 | head of the list of lock info structures, as well as a count of | |
83 | read locks that are untracked, because no info structure could be | |
84 | allocated for them. */ | |
85 | struct _pthread_rwlock_t; | |
86 | typedef struct _pthread_rwlock_info { | |
87 | struct _pthread_rwlock_info *pr_next; | |
88 | struct _pthread_rwlock_t *pr_lock; | |
89 | int pr_lock_count; | |
90 | } pthread_readlock_info; | |
91 | ||
92 | ||
93 | /* We keep thread specific data in a special data structure, a two-level | |
94 | array. The top-level array contains pointers to dynamically allocated | |
95 | arrays of a certain number of data pointers. So we can implement a | |
96 | sparse array. Each dynamic second-level array has | |
97 | PTHREAD_KEY_2NDLEVEL_SIZE | |
98 | entries. This value shouldn't be too large. */ | |
99 | #define PTHREAD_KEY_2NDLEVEL_SIZE 32 | |
100 | ||
101 | /* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE | |
102 | keys in each subarray. */ | |
103 | #define PTHREAD_KEY_1STLEVEL_SIZE \ | |
104 | ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \ | |
105 | / PTHREAD_KEY_2NDLEVEL_SIZE) | |
106 | ||
107 | ||
108 | union dtv; | |
109 | ||
bb0ddc2f RM |
110 | struct _pthread_descr_struct |
111 | { | |
112 | #if !defined USE_TLS || !TLS_DTV_AT_TP | |
113 | /* This overlaps tcbhead_t (see tls.h), as used for TLS without threads. */ | |
114 | union | |
115 | { | |
116 | struct | |
117 | { | |
557fab43 UD |
118 | void *tcb; /* Pointer to the TCB. This is not always |
119 | the address of this thread descriptor. */ | |
535b764d | 120 | union dtv *dtvp; |
557fab43 | 121 | pthread_descr self; /* Pointer to this structure */ |
82f81a90 | 122 | int multiple_threads; |
299601a1 | 123 | # ifdef NEED_DL_SYSINFO |
131fd126 | 124 | uintptr_t sysinfo; |
299601a1 | 125 | # endif |
535b764d UD |
126 | } data; |
127 | void *__padding[16]; | |
128 | } p_header; | |
c86e6aec UD |
129 | # define p_multiple_threads p_header.data.multiple_threads |
130 | #elif TLS_MULTIPLE_THREADS_IN_TCB | |
131 | int p_multiple_threads; | |
bb0ddc2f | 132 | #endif |
c86e6aec | 133 | |
535b764d UD |
134 | pthread_descr p_nextlive, p_prevlive; |
135 | /* Double chaining of active threads */ | |
136 | pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */ | |
137 | pthread_descr p_nextlock; /* can be on a queue and waiting on a lock */ | |
138 | pthread_t p_tid; /* Thread identifier */ | |
139 | int p_pid; /* PID of Unix process */ | |
140 | int p_priority; /* Thread priority (== 0 if not realtime) */ | |
141 | struct _pthread_fastlock * p_lock; /* Spinlock for synchronized accesses */ | |
142 | int p_signal; /* last signal received */ | |
143 | sigjmp_buf * p_signal_jmp; /* where to siglongjmp on a signal or NULL */ | |
144 | sigjmp_buf * p_cancel_jmp; /* where to siglongjmp on a cancel or NULL */ | |
145 | char p_terminated; /* true if terminated e.g. by pthread_exit */ | |
146 | char p_detached; /* true if detached */ | |
147 | char p_exited; /* true if the assoc. process terminated */ | |
148 | void * p_retval; /* placeholder for return value */ | |
149 | int p_retcode; /* placeholder for return code */ | |
150 | pthread_descr p_joining; /* thread joining on that thread or NULL */ | |
151 | struct _pthread_cleanup_buffer * p_cleanup; /* cleanup functions */ | |
152 | char p_cancelstate; /* cancellation state */ | |
153 | char p_canceltype; /* cancellation type (deferred/async) */ | |
154 | char p_canceled; /* cancellation request pending */ | |
535b764d UD |
155 | char * p_in_sighandler; /* stack address of sighandler, or NULL */ |
156 | char p_sigwaiting; /* true if a sigwait() is in progress */ | |
157 | struct pthread_start_args p_start_args; /* arguments for thread creation */ | |
158 | void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */ | |
c2afe833 | 159 | #if !(USE_TLS && HAVE___THREAD) |
535b764d | 160 | void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */ |
c2afe833 RM |
161 | int * p_errnop; /* pointer to used errno variable */ |
162 | int p_errno; /* error returned by last system call */ | |
163 | int * p_h_errnop; /* pointer to used h_errno variable */ | |
164 | int p_h_errno; /* error returned by last netdb function */ | |
165 | struct __res_state *p_resp; /* Pointer to resolver state */ | |
c2afe833 | 166 | #endif |
0e9d6240 | 167 | struct __res_state p_res; /* per-thread resolver state */ |
535b764d UD |
168 | int p_userstack; /* nonzero if the user provided the stack */ |
169 | void *p_guardaddr; /* address of guard area or NULL */ | |
170 | size_t p_guardsize; /* size of guard area */ | |
171 | int p_nr; /* Index of descriptor in __pthread_handles */ | |
172 | int p_report_events; /* Nonzero if events must be reported. */ | |
173 | td_eventbuf_t p_eventbuf; /* Data for event. */ | |
174 | struct pthread_atomic p_resume_count; /* number of times restart() was | |
175 | called on thread */ | |
176 | char p_woken_by_cancel; /* cancellation performed wakeup */ | |
177 | char p_condvar_avail; /* flag if conditional variable became avail */ | |
178 | char p_sem_avail; /* flag if semaphore became available */ | |
179 | pthread_extricate_if *p_extricate; /* See above */ | |
180 | pthread_readlock_info *p_readlock_list; /* List of readlock info structs */ | |
181 | pthread_readlock_info *p_readlock_free; /* Free list of structs */ | |
182 | int p_untracked_readlock_count; /* Readlocks not tracked by list */ | |
535b764d UD |
183 | int p_inheritsched; /* copied from the thread attribute */ |
184 | #if HP_TIMING_AVAIL | |
185 | hp_timing_t p_cpuclock_offset; /* Initial CPU clock for thread. */ | |
557fab43 UD |
186 | #endif |
187 | #ifdef USE_TLS | |
188 | char *p_stackaddr; /* Stack address. */ | |
535b764d | 189 | #endif |
6166815d UD |
190 | size_t p_alloca_cutoff; /* Maximum size which should be allocated |
191 | using alloca() instead of malloc(). */ | |
c86e6aec | 192 | /* New elements must be added at the end. */ |
535b764d UD |
193 | } __attribute__ ((aligned(32))); /* We need to align the structure so that |
194 | doubles are aligned properly. This is 8 | |
195 | bytes on MIPS and 16 bytes on MIPS64. | |
196 | 32 bytes might give better cache | |
197 | utilization. */ | |
198 | ||
cd30b01e UD |
199 | |
200 | ||
201 | /* Limit between the stack of the initial thread (above) and the | |
202 | stacks of other threads (below). Aligned on a STACK_SIZE boundary. | |
203 | Initially 0, meaning that the current thread is (by definition) | |
204 | the initial thread. */ | |
205 | ||
206 | extern char *__pthread_initial_thread_bos; | |
207 | ||
208 | /* Descriptor of the initial thread */ | |
209 | ||
210 | extern struct _pthread_descr_struct __pthread_initial_thread; | |
211 | ||
212 | /* Limits of the thread manager stack. */ | |
213 | ||
214 | extern char *__pthread_manager_thread_bos; | |
215 | extern char *__pthread_manager_thread_tos; | |
216 | ||
217 | /* Descriptor of the manager thread */ | |
218 | ||
219 | extern struct _pthread_descr_struct __pthread_manager_thread; | |
65af7e61 | 220 | extern pthread_descr __pthread_manager_threadp attribute_hidden; |
cd30b01e UD |
221 | |
222 | /* Indicate whether at least one thread has a user-defined stack (if 1), | |
223 | or all threads have stacks supplied by LinuxThreads (if 0). */ | |
224 | ||
225 | extern int __pthread_nonstandard_stacks; | |
226 | ||
227 | /* The max size of the thread stack segments. If the default | |
228 | THREAD_SELF implementation is used, this must be a power of two and | |
229 | a multiple of PAGE_SIZE. */ | |
230 | #ifndef STACK_SIZE | |
231 | #define STACK_SIZE (2 * 1024 * 1024) | |
232 | #endif | |
233 | ||
234 | /* Get some notion of the current stack. Need not be exactly the top | |
235 | of the stack, just something somewhere in the current frame. */ | |
236 | #ifndef CURRENT_STACK_FRAME | |
237 | #define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) | |
238 | #endif | |
239 | ||
240 | /* Recover thread descriptor for the current thread */ | |
241 | ||
242 | extern pthread_descr __pthread_find_self (void) __attribute__ ((const)); | |
243 | ||
244 | static inline pthread_descr thread_self (void) __attribute__ ((const)); | |
245 | static inline pthread_descr thread_self (void) | |
246 | { | |
247 | #ifdef THREAD_SELF | |
248 | return THREAD_SELF; | |
249 | #else | |
250 | char *sp = CURRENT_STACK_FRAME; | |
251 | if (sp >= __pthread_initial_thread_bos) | |
252 | return &__pthread_initial_thread; | |
253 | else if (sp >= __pthread_manager_thread_bos | |
254 | && sp < __pthread_manager_thread_tos) | |
255 | return &__pthread_manager_thread; | |
256 | else if (__pthread_nonstandard_stacks) | |
257 | return __pthread_find_self(); | |
258 | else | |
259 | #ifdef _STACK_GROWS_DOWN | |
260 | return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1; | |
261 | #else | |
262 | return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1)); | |
263 | #endif | |
264 | #endif | |
265 | } | |
266 | ||
535b764d | 267 | #endif /* descr.h */ |