1 /* Linuxthreads - a simple clone()-based implementation of Posix */
2 /* threads for Linux. */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
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. */
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. */
18 #define __need_res_state
22 #include <sys/types.h>
24 #include <l4/sys/utcb.h>
25 #include <pt-machine.h>
27 /* The type of thread descriptors */
28 typedef struct pthread *pthread_descr;
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 */
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 {
49 int (*pu_extricate_func)(void *, pthread_descr);
50 } pthread_extricate_if;
53 /* Atomic counter made possible by compare_and_swap */
54 struct pthread_atomic {
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;
72 } pthread_readlock_info;
75 # define TCB_ALIGNMENT sizeof (double)
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
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)
100 #if !defined(TLS_DTV_AT_TP)
101 /* This overlaps the TCB as used for TLS without threads (see tls.h). */
106 int multiple_threads;
109 # ifndef __ASSUME_PRIVATE_FUTEX
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. */
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 */
129 int p_priority; /* Thread priority (== 0 if not realtime) */
131 __cpu_mask p_affinity_mask[1]; /* L4 addition; small, more needs dynamic allocations */
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 */
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
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 */
173 char *p_stackaddr; /* Stack address. */
175 size_t p_alloca_cutoff; /* Maximum size which should be allocated
176 using alloca() instead of malloc(). */
178 unsigned ebx, ecx, edx, esi, edi;
179 /* New elements must be added at the end. */
180 } __attribute__ ((aligned (TCB_ALIGNMENT)));
184 /* Limit between the stack of the initial thread (above) and the
185 stacks of other threads (below). Aligned on a STACK_SIZE boundary.
186 Initially 0, meaning that the current thread is (by definition)
187 the initial thread. */
189 extern char *__pthread_initial_thread_bos;
191 /* Descriptor of the initial thread */
193 extern struct pthread __pthread_initial_thread;
195 /* Limits of the thread manager stack. */
197 extern char *__pthread_manager_thread_bos;
198 extern char *__pthread_manager_thread_tos;
200 /* Descriptor of the manager thread */
202 extern struct pthread __pthread_manager_thread;
203 extern pthread_descr __pthread_manager_threadp L4_HIDDEN;
205 /* Indicate whether at least one thread has a user-defined stack (if 1),
206 or all threads have stacks supplied by LinuxThreads (if 0). */
208 extern int __pthread_nonstandard_stacks;
210 /* The max size of the thread stack segments. If the default
211 THREAD_SELF implementation is used, this must be a power of two and
212 a multiple of PAGE_SIZE. */
214 #define STACK_SIZE (2 * 1024 * 1024)
217 /* Get some notion of the current stack. Need not be exactly the top
218 of the stack, just something somewhere in the current frame. */
219 #ifndef CURRENT_STACK_FRAME
220 #define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
223 /* Recover thread descriptor for the current thread */
225 extern pthread_descr __pthread_find_self (void) __attribute__ ((pure));
227 static __inline__ pthread_descr thread_self (void) __attribute__ ((pure));
228 static __inline__ pthread_descr thread_self (void)
229 { return (pthread_descr)(l4_utcb_tcr()->user[0]); }