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