Update.
[glibc.git] / linuxthreads / internals.h
blob93ec93620c062e8c72424d0b5bd7129e86435f8c
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. */
15 #ifndef _INTERNALS_H
16 #define _INTERNALS_H 1
18 /* Internal data structures */
20 /* Includes */
22 #include <limits.h>
23 #include <resolv.h>
24 #include <setjmp.h>
25 #include <signal.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
30 #include "pt-machine.h"
31 #include "semaphore.h"
32 #include "../linuxthreads_db/thread_dbP.h"
34 #ifndef THREAD_GETMEM
35 # define THREAD_GETMEM(descr, member) descr->member
36 #endif
37 #ifndef THREAD_GETMEM_NC
38 # define THREAD_GETMEM_NC(descr, member) descr->member
39 #endif
40 #ifndef THREAD_SETMEM
41 # define THREAD_SETMEM(descr, member, value) descr->member = (value)
42 #endif
43 #ifndef THREAD_SETMEM_NC
44 # define THREAD_SETMEM_NC(descr, member, value) descr->member = (value)
45 #endif
47 /* Arguments passed to thread creation routine */
49 struct pthread_start_args {
50 void * (*start_routine)(void *); /* function to run */
51 void * arg; /* its argument */
52 sigset_t mask; /* initial signal mask for thread */
53 int schedpolicy; /* initial scheduling policy (if any) */
54 struct sched_param schedparam; /* initial scheduling parameters (if any) */
58 /* We keep thread specific data in a special data structure, a two-level
59 array. The top-level array contains pointers to dynamically allocated
60 arrays of a certain number of data pointers. So we can implement a
61 sparse array. Each dynamic second-level array has
62 PTHREAD_KEY_2NDLEVEL_SIZE
63 entries. This value shouldn't be too large. */
64 #define PTHREAD_KEY_2NDLEVEL_SIZE 32
66 /* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE
67 keys in each subarray. */
68 #define PTHREAD_KEY_1STLEVEL_SIZE \
69 ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \
70 / PTHREAD_KEY_2NDLEVEL_SIZE)
72 typedef void (*destr_function)(void *);
74 struct pthread_key_struct {
75 int in_use; /* already allocated? */
76 destr_function destr; /* destruction routine */
80 #define PTHREAD_START_ARGS_INITIALIZER(fct) \
81 { (void *(*) (void *)) fct, NULL, {{0, }}, 0, { 0 } }
83 /* The type of thread descriptors */
85 typedef struct _pthread_descr_struct * pthread_descr;
87 /* Callback interface for removing the thread from waiting on an
88 object if it is cancelled while waiting or about to wait.
89 This hold a pointer to the object, and a pointer to a function
90 which ``extricates'' the thread from its enqueued state.
91 The function takes two arguments: pointer to the wait object,
92 and a pointer to the thread. It returns 1 if an extrication
93 actually occured, and hence the thread must also be signalled.
94 It returns 0 if the thread had already been extricated. */
96 typedef struct _pthread_extricate_struct {
97 void *pu_object;
98 int (*pu_extricate_func)(void *, pthread_descr);
99 } pthread_extricate_if;
101 /* Atomic counter made possible by compare_and_swap */
103 struct pthread_atomic {
104 long p_count;
105 int p_spinlock;
108 /* Context info for read write locks. The pthread_rwlock_info structure
109 is information about a lock that has been read-locked by the thread
110 in whose list this structure appears. The pthread_rwlock_context
111 is embedded in the thread context and contains a pointer to the
112 head of the list of lock info structures, as well as a count of
113 read locks that are untracked, because no info structure could be
114 allocated for them. */
116 struct _pthread_rwlock_t;
118 typedef struct _pthread_rwlock_info {
119 struct _pthread_rwlock_info *pr_next;
120 struct _pthread_rwlock_t *pr_lock;
121 int pr_lock_count;
122 } pthread_readlock_info;
124 struct _pthread_descr_struct {
125 union {
126 struct {
127 pthread_descr self; /* Pointer to this structure */
128 } data;
129 void *__padding[16];
130 } p_header;
131 pthread_descr p_nextlive, p_prevlive;
132 /* Double chaining of active threads */
133 pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */
134 pthread_descr p_nextlock; /* can be on a queue and waiting on a lock */
135 pthread_t p_tid; /* Thread identifier */
136 int p_pid; /* PID of Unix process */
137 int p_priority; /* Thread priority (== 0 if not realtime) */
138 struct _pthread_fastlock * p_lock; /* Spinlock for synchronized accesses */
139 int p_signal; /* last signal received */
140 sigjmp_buf * p_signal_jmp; /* where to siglongjmp on a signal or NULL */
141 sigjmp_buf * p_cancel_jmp; /* where to siglongjmp on a cancel or NULL */
142 char p_terminated; /* true if terminated e.g. by pthread_exit */
143 char p_detached; /* true if detached */
144 char p_exited; /* true if the assoc. process terminated */
145 void * p_retval; /* placeholder for return value */
146 int p_retcode; /* placeholder for return code */
147 pthread_descr p_joining; /* thread joining on that thread or NULL */
148 struct _pthread_cleanup_buffer * p_cleanup; /* cleanup functions */
149 char p_cancelstate; /* cancellation state */
150 char p_canceltype; /* cancellation type (deferred/async) */
151 char p_canceled; /* cancellation request pending */
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 char * p_in_sighandler; /* stack address of sighandler, or NULL */
157 char p_sigwaiting; /* true if a sigwait() is in progress */
158 struct pthread_start_args p_start_args; /* arguments for thread creation */
159 void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */
160 void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */
161 int p_userstack; /* nonzero if the user provided the stack */
162 void *p_guardaddr; /* address of guard area or NULL */
163 size_t p_guardsize; /* size of guard area */
164 int p_nr; /* Index of descriptor in __pthread_handles */
165 int p_report_events; /* Nonzero if events must be reported. */
166 td_eventbuf_t p_eventbuf; /* Data for event. */
167 struct pthread_atomic p_resume_count; /* number of times restart() was
168 called on thread */
169 char p_woken_by_cancel; /* cancellation performed wakeup */
170 char p_condvar_avail; /* flag if conditional variable became avail */
171 char p_sem_avail; /* flag if semaphore became available */
172 pthread_extricate_if *p_extricate; /* See above */
173 pthread_readlock_info *p_readlock_list; /* List of readlock info structs */
174 pthread_readlock_info *p_readlock_free; /* Free list of structs */
175 int p_untracked_readlock_count; /* Readlocks not tracked by list */
176 struct __res_state *p_resp; /* Pointer to resolver state */
177 struct __res_state p_res; /* per-thread resolver state */
178 /* New elements must be added at the end. */
179 } __attribute__ ((aligned(32))); /* We need to align the structure so that
180 doubles are aligned properly. This is 8
181 bytes on MIPS and 16 bytes on MIPS64.
182 32 bytes might give better cache
183 utilization. */
186 /* The type of thread handles. */
188 typedef struct pthread_handle_struct * pthread_handle;
190 struct pthread_handle_struct {
191 struct _pthread_fastlock h_lock; /* Fast lock for sychronized access */
192 pthread_descr h_descr; /* Thread descriptor or NULL if invalid */
193 char * h_bottom; /* Lowest address in the stack thread */
196 /* The type of messages sent to the thread manager thread */
198 struct pthread_request {
199 pthread_descr req_thread; /* Thread doing the request */
200 enum { /* Request kind */
201 REQ_CREATE, REQ_FREE, REQ_PROCESS_EXIT, REQ_MAIN_THREAD_EXIT,
202 REQ_POST, REQ_DEBUG, REQ_KICK
203 } req_kind;
204 union { /* Arguments for request */
205 struct { /* For REQ_CREATE: */
206 const pthread_attr_t * attr; /* thread attributes */
207 void * (*fn)(void *); /* start function */
208 void * arg; /* argument to start function */
209 sigset_t mask; /* signal mask */
210 } create;
211 struct { /* For REQ_FREE: */
212 pthread_t thread_id; /* identifier of thread to free */
213 } free;
214 struct { /* For REQ_PROCESS_EXIT: */
215 int code; /* exit status */
216 } exit;
217 void * post; /* For REQ_POST: the semaphore */
218 } req_args;
222 /* Signals used for suspend/restart and for cancellation notification. */
224 extern int __pthread_sig_restart;
225 extern int __pthread_sig_cancel;
227 /* Signal used for interfacing with gdb */
229 extern int __pthread_sig_debug;
231 /* Global array of thread handles, used for validating a thread id
232 and retrieving the corresponding thread descriptor. Also used for
233 mapping the available stack segments. */
235 extern struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX];
237 /* Descriptor of the initial thread */
239 extern struct _pthread_descr_struct __pthread_initial_thread;
241 /* Descriptor of the manager thread */
243 extern struct _pthread_descr_struct __pthread_manager_thread;
245 /* Descriptor of the main thread */
247 extern pthread_descr __pthread_main_thread;
249 /* Limit between the stack of the initial thread (above) and the
250 stacks of other threads (below). Aligned on a STACK_SIZE boundary.
251 Initially 0, meaning that the current thread is (by definition)
252 the initial thread. */
254 extern char *__pthread_initial_thread_bos;
256 /* Indicate whether at least one thread has a user-defined stack (if 1),
257 or all threads have stacks supplied by LinuxThreads (if 0). */
259 extern int __pthread_nonstandard_stacks;
261 /* File descriptor for sending requests to the thread manager.
262 Initially -1, meaning that __pthread_initialize_manager must be called. */
264 extern int __pthread_manager_request;
266 /* Other end of the pipe for sending requests to the thread manager. */
268 extern int __pthread_manager_reader;
270 /* Limits of the thread manager stack. */
272 extern char *__pthread_manager_thread_bos;
273 extern char *__pthread_manager_thread_tos;
275 /* Pending request for a process-wide exit */
277 extern int __pthread_exit_requested, __pthread_exit_code;
279 /* Set to 1 by gdb if we're debugging */
281 extern volatile int __pthread_threads_debug;
283 /* Globally enabled events. */
284 extern volatile td_thr_events_t __pthread_threads_events;
286 /* Pointer to descriptor of thread with last event. */
287 extern volatile pthread_descr __pthread_last_event;
289 /* Flag which tells whether we are executing on SMP kernel. */
290 extern int __pthread_smp_kernel;
292 /* Return the handle corresponding to a thread id */
294 static inline pthread_handle thread_handle(pthread_t id)
296 return &__pthread_handles[id % PTHREAD_THREADS_MAX];
299 /* Validate a thread handle. Must have acquired h->h_spinlock before. */
301 static inline int invalid_handle(pthread_handle h, pthread_t id)
303 return h->h_descr == NULL || h->h_descr->p_tid != id || h->h_descr->p_terminated;
306 static inline int nonexisting_handle(pthread_handle h, pthread_t id)
308 return h->h_descr == NULL || h->h_descr->p_tid != id;
311 /* Fill in defaults left unspecified by pt-machine.h. */
313 /* We round up a value with page size. */
314 #ifndef page_roundup
315 #define page_roundup(v,p) ((((size_t) (v)) + (p) - 1) & ~((p) - 1))
316 #endif
318 /* The page size we can get from the system. This should likely not be
319 changed by the machine file but, you never know. */
320 #ifndef PAGE_SIZE
321 #define PAGE_SIZE (sysconf (_SC_PAGE_SIZE))
322 #endif
324 /* The max size of the thread stack segments. If the default
325 THREAD_SELF implementation is used, this must be a power of two and
326 a multiple of PAGE_SIZE. */
327 #ifndef STACK_SIZE
328 #define STACK_SIZE (2 * 1024 * 1024)
329 #endif
331 /* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */
332 #ifndef INITIAL_STACK_SIZE
333 #define INITIAL_STACK_SIZE (4 * PAGE_SIZE)
334 #endif
336 /* Size of the thread manager stack. The "- 32" avoids wasting space
337 with some malloc() implementations. */
338 #ifndef THREAD_MANAGER_STACK_SIZE
339 #define THREAD_MANAGER_STACK_SIZE (2 * PAGE_SIZE - 32)
340 #endif
342 /* The base of the "array" of thread stacks. The array will grow down from
343 here. Defaults to the calculated bottom of the initial application
344 stack. */
345 #ifndef THREAD_STACK_START_ADDRESS
346 #define THREAD_STACK_START_ADDRESS __pthread_initial_thread_bos
347 #endif
349 /* Get some notion of the current stack. Need not be exactly the top
350 of the stack, just something somewhere in the current frame. */
351 #ifndef CURRENT_STACK_FRAME
352 #define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
353 #endif
355 /* Recover thread descriptor for the current thread */
357 extern pthread_descr __pthread_find_self (void) __attribute__ ((const));
359 static inline pthread_descr thread_self (void) __attribute__ ((const));
360 static inline pthread_descr thread_self (void)
362 #ifdef THREAD_SELF
363 return THREAD_SELF;
364 #else
365 char *sp = CURRENT_STACK_FRAME;
366 if (sp >= __pthread_initial_thread_bos)
367 return &__pthread_initial_thread;
368 else if (sp >= __pthread_manager_thread_bos
369 && sp < __pthread_manager_thread_tos)
370 return &__pthread_manager_thread;
371 else if (__pthread_nonstandard_stacks)
372 return __pthread_find_self();
373 else
374 return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
375 #endif
378 /* If MEMORY_BARRIER isn't defined in pt-machine.h, assume the architecture
379 doesn't need a memory barrier instruction (e.g. Intel x86). Some
380 architectures distinguish between full, read and write barriers. */
382 #ifndef MEMORY_BARRIER
383 #define MEMORY_BARRIER()
384 #endif
385 #ifndef READ_MEMORY_BARRIER
386 #define READ_MEMORY_BARRIER() MEMORY_BARRIER()
387 #endif
388 #ifndef WRITE_MEMORY_BARRIER
389 #define WRITE_MEMORY_BARRIER() MEMORY_BARRIER()
390 #endif
392 /* Max number of times we must spin on a spinlock calling sched_yield().
393 After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */
395 #ifndef MAX_SPIN_COUNT
396 #define MAX_SPIN_COUNT 50
397 #endif
399 /* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
400 after MAX_SPIN_COUNT iterations of sched_yield().
401 With the 2.0 and 2.1 kernels, this MUST BE > 2ms.
402 (Otherwise the kernel does busy-waiting for realtime threads,
403 giving other threads no chance to run.) */
405 #ifndef SPIN_SLEEP_DURATION
406 #define SPIN_SLEEP_DURATION 2000001
407 #endif
409 /* Debugging */
411 #ifdef DEBUG
412 #include <assert.h>
413 #define ASSERT assert
414 #define MSG __pthread_message
415 #else
416 #define ASSERT(x)
417 #define MSG(msg,arg...)
418 #endif
420 /* Internal global functions */
422 void __pthread_destroy_specifics(void);
423 void __pthread_perform_cleanup(void);
424 int __pthread_initialize_manager(void);
425 void __pthread_message(char * fmt, ...);
426 int __pthread_manager(void *reqfd);
427 int __pthread_manager_event(void *reqfd);
428 void __pthread_manager_sighandler(int sig);
429 void __pthread_reset_main_thread(void);
430 void __pthread_once_fork_prepare(void);
431 void __pthread_once_fork_parent(void);
432 void __pthread_once_fork_child(void);
433 void __flockfilelist(void);
434 void __funlockfilelist(void);
435 void __fresetlockfiles(void);
436 void __pthread_manager_adjust_prio(int thread_prio);
437 void __pthread_set_own_extricate_if(pthread_descr self, pthread_extricate_if *peif);
439 extern int __pthread_attr_setguardsize (pthread_attr_t *__attr,
440 size_t __guardsize);
441 extern int __pthread_attr_getguardsize (const pthread_attr_t *__attr,
442 size_t *__guardsize);
443 extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr,
444 void *__stackaddr);
445 extern int __pthread_attr_getstackaddr (const pthread_attr_t *__attr,
446 void **__stackaddr);
447 extern int __pthread_attr_setstacksize (pthread_attr_t *__attr,
448 size_t __stacksize);
449 extern int __pthread_attr_getstacksize (const pthread_attr_t *__attr,
450 size_t *__stacksize);
451 extern int __pthread_getconcurrency (void);
452 extern int __pthread_setconcurrency (int __level);
453 extern int __pthread_mutexattr_gettype (const pthread_mutexattr_t *__attr,
454 int *__kind);
455 extern void __pthread_kill_other_threads_np (void);
457 void __pthread_restart_old(pthread_descr th);
458 void __pthread_suspend_old(pthread_descr self);
459 int __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abs);
461 void __pthread_restart_new(pthread_descr th);
462 void __pthread_suspend_new(pthread_descr self);
463 int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abs);
465 void __pthread_wait_for_restart_signal(pthread_descr self);
467 int __pthread_yield (void);
469 /* Global pointers to old or new suspend functions */
471 extern void (*__pthread_restart)(pthread_descr);
472 extern void (*__pthread_suspend)(pthread_descr);
473 extern int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *);
475 /* Prototypes for the function without cancelation support when the
476 normal version has it. */
477 extern int __libc_close (int fd);
478 extern int __libc_nanosleep (const struct timespec *requested_time,
479 struct timespec *remaining);
480 extern pid_t __libc_waitpid (pid_t pid, int *stat_loc, int options);
482 /* Prototypes for some of the new semaphore functions. */
483 extern int __new_sem_post (sem_t * sem);
485 /* The functions called the signal events. */
486 extern void __linuxthreads_create_event (void);
487 extern void __linuxthreads_death_event (void);
488 extern void __linuxthreads_reap_event (void);
490 #endif /* internals.h */