1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
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:
48:
49:
50:
51:
52:
53: #define PTHREAD_KEY_2NDLEVEL_SIZE 32
54:
55:
56:
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:
65:
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:
77: void *pad[4];
78:
79: struct
80: {
81:
82: struct pthread_unwind_buf *prev;
83:
84:
85:
86:
87: struct _pthread_cleanup_buffer *cleanup;
88:
89:
90: int canceltype;
91: } data;
92: } priv;
93: };
94:
95:
96:
97:
98: struct xid_command
99: {
100: int syscall_no;
101: long int id[3];
102: volatile int cntr;
103: };
104:
105:
106:
107: struct robust_list_head
108: {
109: void *list;
110: long int futex_offset;
111: void *list_op_pending;
112: };
113:
114:
115:
116: struct priority_protection_data
117: {
118: int priomax;
119: unsigned int priomap[];
120: };
121:
122:
123:
124: struct pthread
125: {
126: union
127: {
128: #if !TLS_DTV_AT_TP
129:
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:
143:
144:
145:
146: void *__padding[16];
147: };
148:
149:
150: list_t list;
151:
152:
153:
154: pid_t tid;
155:
156:
157: pid_t pid;
158:
159:
160: #ifdef __PTHREAD_MUTEX_HAVE_PREV
161: void *robust_prev;
162: struct robust_list_head robust_head;
163:
164:
165:
166:
167:
168:
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:
236: struct _pthread_cleanup_buffer *cleanup;
237:
238:
239: struct pthread_unwind_buf *cleanup_jmp_buf;
240: #define HAVE_CLEANUP_JMP_BUF
241:
242:
243: int cancelhandling;
244:
245: #define CANCELSTATE_BIT 0
246: #define CANCELSTATE_BITMASK 0x01
247:
248: #define CANCELTYPE_BIT 1
249: #define CANCELTYPE_BITMASK 0x02
250:
251: #define CANCELING_BIT 2
252: #define CANCELING_BITMASK 0x04
253:
254: #define CANCELED_BIT 3
255: #define CANCELED_BITMASK 0x08
256:
257: #define EXITING_BIT 4
258: #define EXITING_BITMASK 0x10
259:
260: #define TERMINATED_BIT 5
261: #define TERMINATED_BITMASK 0x20
262:
263: #define SETXID_BIT 6
264: #define SETXID_BITMASK 0x40
265:
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:
277: int flags;
278:
279:
280:
281: struct pthread_key_data
282: {
283:
284:
285:
286: uintptr_t seq;
287:
288:
289: void *data;
290: } specific_1stblock[PTHREAD_KEY_2NDLEVEL_SIZE];
291:
292:
293: struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
294:
295:
296: bool specific_used;
297:
298:
299: bool report_events;
300:
301:
302: bool user_stack;
303:
304:
305: bool stopped_start;
306:
307:
308:
309: int parent_cancelhandling;
310:
311:
312: int lock;
313:
314:
315: int setxid_futex;
316:
317: #if HP_TIMING_AVAIL
318:
319: hp_timing_t cpuclock_offset;
320: #endif
321:
322:
323:
324:
325:
326:
327:
328: struct pthread *joinid;
329:
330: #define IS_DETACHED(pd) ((pd)->joinid == (pd))
331:
332:
333: void *result;
334:
335:
336: struct sched_param schedparam;
337: int schedpolicy;
338:
339:
340:
341: void *(*start_routine) (void *);
342: void *arg;
343:
344:
345: td_eventbuf_t eventbuf;
346:
347: struct pthread *nextevent;
348:
349: #ifdef HAVE_FORCED_UNWIND
350:
351: struct _Unwind_Exception exc;
352: #endif
353:
354:
355:
356: void *stackblock;
357: size_t stackblock_size;
358:
359: size_t guardsize;
360:
361: size_t reported_guardsize;
362:
363:
364: struct priority_protection_data *tpp;
365:
366:
367: struct __res_state res;
368:
369:
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