OSDN Git Service

- remove old-style definitions. No object-code changes.
[uclinux-h8/uClibc.git] / libpthread / linuxthreads.old / pthread.c
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 /* Thread creation, initialization, and basic low-level routines */
16
17 #define __FORCE_GLIBC
18 #include <features.h>
19 #include <errno.h>
20 #include <netdb.h>      /* for h_errno */
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/wait.h>
28 #include <sys/resource.h>
29 #include "pthread.h"
30 #include "internals.h"
31 #include "spinlock.h"
32 #include "restart.h"
33 #include "debug.h"      /* added to linuxthreads -StS */
34
35
36 /* Mods for uClibc: Some includes */
37 #include <signal.h>
38 #include <sys/types.h>
39 #include <sys/syscall.h>
40
41 /* mods for uClibc: __libc_sigaction is not in any standard headers */
42 extern __typeof(sigaction) __libc_sigaction;
43 libpthread_hidden_proto(waitpid)
44 libpthread_hidden_proto(raise)
45
46 /* These variables are used by the setup code.  */
47 extern int _errno;
48 extern int _h_errno;
49
50
51 /* Descriptor of the initial thread */
52
53 struct _pthread_descr_struct __pthread_initial_thread = {
54   &__pthread_initial_thread,  /* pthread_descr p_nextlive */
55   &__pthread_initial_thread,  /* pthread_descr p_prevlive */
56   NULL,                       /* pthread_descr p_nextwaiting */
57   NULL,                       /* pthread_descr p_nextlock */
58   PTHREAD_THREADS_MAX,        /* pthread_t p_tid */
59   0,                          /* int p_pid */
60   0,                          /* int p_priority */
61   &__pthread_handles[0].h_lock, /* struct _pthread_fastlock * p_lock */
62   0,                          /* int p_signal */
63   NULL,                       /* sigjmp_buf * p_signal_buf */
64   NULL,                       /* sigjmp_buf * p_cancel_buf */
65   0,                          /* char p_terminated */
66   0,                          /* char p_detached */
67   0,                          /* char p_exited */
68   NULL,                       /* void * p_retval */
69   0,                          /* int p_retval */
70   NULL,                       /* pthread_descr p_joining */
71   NULL,                       /* struct _pthread_cleanup_buffer * p_cleanup */
72   0,                          /* char p_cancelstate */
73   0,                          /* char p_canceltype */
74   0,                          /* char p_canceled */
75   &_errno,                       /* int *p_errnop */
76   0,                          /* int p_errno */
77   &_h_errno,                       /* int *p_h_errnop */
78   0,                          /* int p_h_errno */
79   NULL,                       /* char * p_in_sighandler */
80   0,                          /* char p_sigwaiting */
81   PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
82   {NULL},                     /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */
83   {NULL},                     /* void * p_libc_specific[_LIBC_TSD_KEY_N] */
84   0,                          /* int p_userstack */
85   NULL,                       /* void * p_guardaddr */
86   0,                          /* size_t p_guardsize */
87   &__pthread_initial_thread,  /* pthread_descr p_self */
88   0,                          /* Always index 0 */
89   0,                          /* int p_report_events */
90   {{{0, }}, 0, NULL},         /* td_eventbuf_t p_eventbuf */
91   __ATOMIC_INITIALIZER,         /* struct pthread_atomic p_resume_count */
92   0,                          /* char p_woken_by_cancel */
93   0,                          /* char p_condvar_avail */
94   0,                          /* char p_sem_avail */
95   NULL,                       /* struct pthread_extricate_if *p_extricate */
96   NULL,                       /* pthread_readlock_info *p_readlock_list; */
97   NULL,                       /* pthread_readlock_info *p_readlock_free; */
98   0                           /* int p_untracked_readlock_count; */
99 #ifdef __UCLIBC_HAS_XLOCALE__
100   ,
101   &__global_locale_data,      /* __locale_t locale; */
102 #endif /* __UCLIBC_HAS_XLOCALE__ */
103 };
104
105 /* Descriptor of the manager thread; none of this is used but the error
106    variables, the p_pid and p_priority fields,
107    and the address for identification.  */
108 #define manager_thread (&__pthread_manager_thread)
109 struct _pthread_descr_struct __pthread_manager_thread = {
110   NULL,                       /* pthread_descr p_nextlive */
111   NULL,                       /* pthread_descr p_prevlive */
112   NULL,                       /* pthread_descr p_nextwaiting */
113   NULL,                       /* pthread_descr p_nextlock */
114   0,                          /* int p_tid */
115   0,                          /* int p_pid */
116   0,                          /* int p_priority */
117   &__pthread_handles[1].h_lock, /* struct _pthread_fastlock * p_lock */
118   0,                          /* int p_signal */
119   NULL,                       /* sigjmp_buf * p_signal_buf */
120   NULL,                       /* sigjmp_buf * p_cancel_buf */
121   0,                          /* char p_terminated */
122   0,                          /* char p_detached */
123   0,                          /* char p_exited */
124   NULL,                       /* void * p_retval */
125   0,                          /* int p_retval */
126   NULL,                       /* pthread_descr p_joining */
127   NULL,                       /* struct _pthread_cleanup_buffer * p_cleanup */
128   0,                          /* char p_cancelstate */
129   0,                          /* char p_canceltype */
130   0,                          /* char p_canceled */
131   &__pthread_manager_thread.p_errno, /* int *p_errnop */
132   0,                          /* int p_errno */
133   NULL,                       /* int *p_h_errnop */
134   0,                          /* int p_h_errno */
135   NULL,                       /* char * p_in_sighandler */
136   0,                          /* char p_sigwaiting */
137   PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
138   {NULL},                     /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */
139   {NULL},                     /* void * p_libc_specific[_LIBC_TSD_KEY_N] */
140   0,                          /* int p_userstack */
141   NULL,                       /* void * p_guardaddr */
142   0,                          /* size_t p_guardsize */
143   &__pthread_manager_thread,  /* pthread_descr p_self */
144   1,                          /* Always index 1 */
145   0,                          /* int p_report_events */
146   {{{0, }}, 0, NULL},         /* td_eventbuf_t p_eventbuf */
147   __ATOMIC_INITIALIZER,         /* struct pthread_atomic p_resume_count */
148   0,                          /* char p_woken_by_cancel */
149   0,                          /* char p_condvar_avail */
150   0,                          /* char p_sem_avail */
151   NULL,                       /* struct pthread_extricate_if *p_extricate */
152   NULL,                       /* pthread_readlock_info *p_readlock_list; */
153   NULL,                       /* pthread_readlock_info *p_readlock_free; */
154   0                           /* int p_untracked_readlock_count; */
155 #ifdef __UCLIBC_HAS_XLOCALE__
156   ,
157   &__global_locale_data,      /* __locale_t locale; */
158 #endif /* __UCLIBC_HAS_XLOCALE__ */
159 };
160
161 /* Pointer to the main thread (the father of the thread manager thread) */
162 /* Originally, this is the initial thread, but this changes after fork() */
163
164 pthread_descr __pthread_main_thread = &__pthread_initial_thread;
165
166 /* Limit between the stack of the initial thread (above) and the
167    stacks of other threads (below). Aligned on a STACK_SIZE boundary. */
168
169 char *__pthread_initial_thread_bos = NULL;
170
171 /* For non-MMU systems also remember to stack top of the initial thread.
172  * This is adapted when other stacks are malloc'ed since we don't know
173  * the bounds a-priori. -StS */
174
175 #ifndef __ARCH_USE_MMU__
176 char *__pthread_initial_thread_tos = NULL;
177 #endif /* __ARCH_USE_MMU__ */
178
179 /* File descriptor for sending requests to the thread manager. */
180 /* Initially -1, meaning that the thread manager is not running. */
181
182 int __pthread_manager_request = -1;
183
184 /* Other end of the pipe for sending requests to the thread manager. */
185
186 int __pthread_manager_reader;
187
188 /* Limits of the thread manager stack */
189
190 char *__pthread_manager_thread_bos = NULL;
191 char *__pthread_manager_thread_tos = NULL;
192
193 /* For process-wide exit() */
194
195 int __pthread_exit_requested = 0;
196 int __pthread_exit_code = 0;
197
198 /* Communicate relevant LinuxThreads constants to gdb */
199
200 const int __pthread_threads_max = PTHREAD_THREADS_MAX;
201 const int __pthread_sizeof_handle = sizeof(struct pthread_handle_struct);
202 const int __pthread_offsetof_descr = offsetof(struct pthread_handle_struct, h_descr);
203 const int __pthread_offsetof_pid = offsetof(struct _pthread_descr_struct,
204                                             p_pid);
205 const int __linuxthreads_pthread_sizeof_descr
206   = sizeof(struct _pthread_descr_struct);
207
208 const int __linuxthreads_initial_report_events;
209
210 const char __linuxthreads_version[] = VERSION;
211
212 /* Forward declarations */
213 static void pthread_onexit_process(int retcode, void *arg);
214 static void pthread_handle_sigcancel(int sig);
215 static void pthread_handle_sigrestart(int sig);
216 static void pthread_handle_sigdebug(int sig);
217 int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstime);
218
219 /* Signal numbers used for the communication.
220    In these variables we keep track of the used variables.  If the
221    platform does not support any real-time signals we will define the
222    values to some unreasonable value which will signal failing of all
223    the functions below.  */
224 #ifndef __NR_rt_sigaction
225 static int current_rtmin = -1;
226 static int current_rtmax = -1;
227 int __pthread_sig_restart = SIGUSR1;
228 int __pthread_sig_cancel = SIGUSR2;
229 int __pthread_sig_debug;
230 #else
231
232 #if __SIGRTMAX - __SIGRTMIN >= 3
233 static int current_rtmin = __SIGRTMIN + 3;
234 static int current_rtmax = __SIGRTMAX;
235 int __pthread_sig_restart = __SIGRTMIN;
236 int __pthread_sig_cancel = __SIGRTMIN + 1;
237 int __pthread_sig_debug = __SIGRTMIN + 2;
238 void (*__pthread_restart)(pthread_descr) = __pthread_restart_new;
239 void (*__pthread_suspend)(pthread_descr) = __pthread_wait_for_restart_signal;
240 int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *) = __pthread_timedsuspend_new;
241 #else
242 static int current_rtmin = __SIGRTMIN;
243 static int current_rtmax = __SIGRTMAX;
244 int __pthread_sig_restart = SIGUSR1;
245 int __pthread_sig_cancel = SIGUSR2;
246 int __pthread_sig_debug;
247 void (*__pthread_restart)(pthread_descr) = __pthread_restart_old;
248 void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old;
249 int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *) = __pthread_timedsuspend_old;
250
251 #endif
252
253 /* Return number of available real-time signal with highest priority.  */
254 int __libc_current_sigrtmin (void)
255 {
256     return current_rtmin;
257 }
258
259 /* Return number of available real-time signal with lowest priority.  */
260 int __libc_current_sigrtmax (void)
261 {
262     return current_rtmax;
263 }
264
265 /* Allocate real-time signal with highest/lowest available
266    priority.  Please note that we don't use a lock since we assume
267    this function to be called at program start.  */
268 int __libc_allocate_rtsig (int high);
269 int __libc_allocate_rtsig (int high)
270 {
271     if (current_rtmin == -1 || current_rtmin > current_rtmax)
272         /* We don't have anymore signal available.  */
273         return -1;
274     return high ? current_rtmin++ : current_rtmax--;
275 }
276 #endif
277
278 /* Initialize the pthread library.
279    Initialization is split in two functions:
280    - a constructor function that blocks the __pthread_sig_restart signal
281      (must do this very early, since the program could capture the signal
282       mask with e.g. sigsetjmp before creating the first thread);
283    - a regular function called from pthread_create when needed. */
284
285 static void pthread_initialize(void) __attribute__((constructor));
286
287 libpthread_hidden_proto(pthread_attr_destroy)
288 libpthread_hidden_proto(pthread_attr_init)
289 libpthread_hidden_proto(pthread_attr_getdetachstate)
290 libpthread_hidden_proto(pthread_attr_setdetachstate)
291 libpthread_hidden_proto(pthread_attr_getinheritsched)
292 libpthread_hidden_proto(pthread_attr_setinheritsched)
293 libpthread_hidden_proto(pthread_attr_setschedparam)
294 libpthread_hidden_proto(pthread_attr_getschedparam)
295 libpthread_hidden_proto(pthread_attr_getschedpolicy)
296 libpthread_hidden_proto(pthread_attr_setschedpolicy)
297 libpthread_hidden_proto(pthread_attr_getscope)
298 libpthread_hidden_proto(pthread_attr_setscope)
299
300 libpthread_hidden_proto(pthread_exit)
301
302 libpthread_hidden_proto(pthread_equal)
303 libpthread_hidden_proto(pthread_self)
304 libpthread_hidden_proto(pthread_getschedparam)
305 libpthread_hidden_proto(pthread_setschedparam)
306
307 libpthread_hidden_proto(pthread_setcancelstate)
308 libpthread_hidden_proto(pthread_setcanceltype)
309 libpthread_hidden_proto(_pthread_cleanup_push_defer)
310 libpthread_hidden_proto(_pthread_cleanup_pop_restore)
311
312 libpthread_hidden_proto(pthread_cond_broadcast)
313 libpthread_hidden_proto(pthread_cond_destroy)
314 libpthread_hidden_proto(pthread_cond_init)
315 libpthread_hidden_proto(pthread_cond_signal)
316 libpthread_hidden_proto(pthread_cond_wait)
317 libpthread_hidden_proto(pthread_cond_timedwait)
318
319 libpthread_hidden_proto(pthread_condattr_destroy)
320 libpthread_hidden_proto(pthread_condattr_init)
321
322 struct pthread_functions __pthread_functions =
323   {
324 #if !(USE_TLS && HAVE___THREAD)
325     .ptr_pthread_internal_tsd_set = __pthread_internal_tsd_set,
326     .ptr_pthread_internal_tsd_get = __pthread_internal_tsd_get,
327     .ptr_pthread_internal_tsd_address = __pthread_internal_tsd_address,
328 #endif
329 /*
330     .ptr_pthread_fork = __pthread_fork,
331 */
332     .ptr_pthread_attr_destroy = pthread_attr_destroy,
333     .ptr_pthread_attr_init = pthread_attr_init,
334     .ptr_pthread_attr_getdetachstate = pthread_attr_getdetachstate,
335     .ptr_pthread_attr_setdetachstate = pthread_attr_setdetachstate,
336     .ptr_pthread_attr_getinheritsched = pthread_attr_getinheritsched,
337     .ptr_pthread_attr_setinheritsched = pthread_attr_setinheritsched,
338     .ptr_pthread_attr_getschedparam = pthread_attr_getschedparam,
339     .ptr_pthread_attr_setschedparam = pthread_attr_setschedparam,
340     .ptr_pthread_attr_getschedpolicy = pthread_attr_getschedpolicy,
341     .ptr_pthread_attr_setschedpolicy = pthread_attr_setschedpolicy,
342     .ptr_pthread_attr_getscope = pthread_attr_getscope,
343     .ptr_pthread_attr_setscope = pthread_attr_setscope,
344     .ptr_pthread_condattr_destroy = pthread_condattr_destroy,
345     .ptr_pthread_condattr_init = pthread_condattr_init,
346     .ptr_pthread_cond_broadcast = pthread_cond_broadcast,
347     .ptr_pthread_cond_destroy = pthread_cond_destroy,
348     .ptr_pthread_cond_init = pthread_cond_init,
349     .ptr_pthread_cond_signal = pthread_cond_signal,
350     .ptr_pthread_cond_wait = pthread_cond_wait,
351     .ptr_pthread_cond_timedwait = pthread_cond_timedwait,
352     .ptr_pthread_equal = pthread_equal,
353     .ptr___pthread_exit = pthread_exit,
354     .ptr_pthread_getschedparam = pthread_getschedparam,
355     .ptr_pthread_setschedparam = pthread_setschedparam,
356     .ptr_pthread_mutex_destroy = __pthread_mutex_destroy,
357     .ptr_pthread_mutex_init = __pthread_mutex_init,
358     .ptr_pthread_mutex_lock = __pthread_mutex_lock,
359     .ptr_pthread_mutex_trylock = __pthread_mutex_trylock,
360     .ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
361     .ptr_pthread_self = pthread_self,
362     .ptr_pthread_setcancelstate = pthread_setcancelstate,
363     .ptr_pthread_setcanceltype = pthread_setcanceltype,
364 /*
365     .ptr_pthread_do_exit = pthread_do_exit,
366     .ptr_pthread_thread_self = pthread_thread_self,
367     .ptr_pthread_cleanup_upto = pthread_cleanup_upto,
368     .ptr_pthread_sigaction = pthread_sigaction,
369     .ptr_pthread_sigwait = pthread_sigwait,
370     .ptr_pthread_raise = pthread_raise,
371     .ptr__pthread_cleanup_push = _pthread_cleanup_push,
372     .ptr__pthread_cleanup_pop = _pthread_cleanup_pop
373 */
374     .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer,
375     .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore,
376   };
377 #ifdef SHARED
378 # define ptr_pthread_functions &__pthread_functions
379 #else
380 # define ptr_pthread_functions NULL
381 #endif
382
383 static int *__libc_multiple_threads_ptr;
384
385  /* Do some minimal initialization which has to be done during the
386     startup of the C library.  */
387 void __pthread_initialize_minimal(void)
388 {
389     /* If we have special thread_self processing, initialize 
390      * that for the main thread now.  */
391 #ifdef INIT_THREAD_SELF
392     INIT_THREAD_SELF(&__pthread_initial_thread, 0);
393 #endif
394
395     __libc_multiple_threads_ptr = __libc_pthread_init (ptr_pthread_functions);
396 }
397
398
399 static void pthread_initialize(void)
400 {
401   struct sigaction sa;
402   sigset_t mask;
403 #ifdef __ARCH_USE_MMU__
404   struct rlimit limit;
405   rlim_t max_stack;
406 #endif
407
408   /* If already done (e.g. by a constructor called earlier!), bail out */
409   if (__pthread_initial_thread_bos != NULL) return;
410 #ifdef TEST_FOR_COMPARE_AND_SWAP
411   /* Test if compare-and-swap is available */
412   __pthread_has_cas = compare_and_swap_is_available();
413 #endif
414   /* For the initial stack, reserve at least STACK_SIZE bytes of stack
415      below the current stack address, and align that on a
416      STACK_SIZE boundary. */
417   __pthread_initial_thread_bos =
418     (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
419   /* Update the descriptor for the initial thread. */
420   __pthread_initial_thread.p_pid = getpid();
421   /* If we have special thread_self processing, initialize that for the
422      main thread now.  */
423 #ifdef INIT_THREAD_SELF
424   INIT_THREAD_SELF(&__pthread_initial_thread, 0);
425 #endif
426   /* The errno/h_errno variable of the main thread are the global ones.  */
427   __pthread_initial_thread.p_errnop = &_errno;
428   __pthread_initial_thread.p_h_errnop = &_h_errno;
429
430 #ifdef __UCLIBC_HAS_XLOCALE__
431   /* The locale of the main thread is the current locale in use. */
432   __pthread_initial_thread.locale = __curlocale_var;
433 #endif /* __UCLIBC_HAS_XLOCALE__ */
434
435  {                         /* uClibc-specific stdio initialization for threads. */
436          FILE *fp;
437          
438          _stdio_user_locking = 0;       /* 2 if threading not initialized */
439          for (fp = _stdio_openlist; fp != NULL; fp = fp->__nextopen) {
440                  if (fp->__user_locking != 1) {
441                          fp->__user_locking = 0;
442                  }
443          }
444  }
445
446   /* Play with the stack size limit to make sure that no stack ever grows
447      beyond STACK_SIZE minus two pages (one page for the thread descriptor
448      immediately beyond, and one page to act as a guard page). */
449
450 #ifdef __ARCH_USE_MMU__
451   /* We cannot allocate a huge chunk of memory to mmap all thread stacks later
452    * on a non-MMU system. Thus, we don't need the rlimit either. -StS */
453   getrlimit(RLIMIT_STACK, &limit);
454   max_stack = STACK_SIZE - 2 * getpagesize();
455   if (limit.rlim_cur > max_stack) {
456     limit.rlim_cur = max_stack;
457     setrlimit(RLIMIT_STACK, &limit);
458   }
459 #else
460   /* For non-MMU assume __pthread_initial_thread_tos at upper page boundary, and
461    * __pthread_initial_thread_bos at address 0. These bounds are refined as we 
462    * malloc other stack frames such that they don't overlap. -StS
463    */
464   __pthread_initial_thread_tos =
465     (char *)(((long)CURRENT_STACK_FRAME + getpagesize()) & ~(getpagesize() - 1));
466   __pthread_initial_thread_bos = (char *) 1; /* set it non-zero so we know we have been here */
467   PDEBUG("initial thread stack bounds: bos=%p, tos=%p\n",
468          __pthread_initial_thread_bos, __pthread_initial_thread_tos);
469 #endif /* __ARCH_USE_MMU__ */
470
471   /* Setup signal handlers for the initial thread.
472      Since signal handlers are shared between threads, these settings
473      will be inherited by all other threads. */
474   sa.sa_handler = pthread_handle_sigrestart;
475   sigemptyset(&sa.sa_mask);
476   sa.sa_flags = 0;
477   __libc_sigaction(__pthread_sig_restart, &sa, NULL);
478   sa.sa_handler = pthread_handle_sigcancel;
479   sigaddset(&sa.sa_mask, __pthread_sig_restart);
480   // sa.sa_flags = 0;
481   __libc_sigaction(__pthread_sig_cancel, &sa, NULL);
482   if (__pthread_sig_debug > 0) {
483       sa.sa_handler = pthread_handle_sigdebug;
484       sigemptyset(&sa.sa_mask);
485       // sa.sa_flags = 0;
486       __libc_sigaction(__pthread_sig_debug, &sa, NULL);
487   }
488   /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */
489   sigemptyset(&mask);
490   sigaddset(&mask, __pthread_sig_restart);
491   sigprocmask(SIG_BLOCK, &mask, NULL);
492   /* And unblock __pthread_sig_cancel if it has been blocked. */
493   sigdelset(&mask, __pthread_sig_restart);
494   sigaddset(&mask, __pthread_sig_cancel);
495   sigprocmask(SIG_UNBLOCK, &mask, NULL);
496   /* Register an exit function to kill all other threads. */
497   /* Do it early so that user-registered atexit functions are called
498      before pthread_onexit_process. */
499   on_exit(pthread_onexit_process, NULL);
500 }
501
502 void __pthread_initialize(void);
503 void __pthread_initialize(void)
504 {
505   pthread_initialize();
506 }
507
508 int __pthread_initialize_manager(void)
509 {
510   int manager_pipe[2];
511   int pid;
512   int report_events;
513   struct pthread_request request;
514
515   *__libc_multiple_threads_ptr = 1;
516
517   /* If basic initialization not done yet (e.g. we're called from a
518      constructor run before our constructor), do it now */
519   if (__pthread_initial_thread_bos == NULL) pthread_initialize();
520   /* Setup stack for thread manager */
521   __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
522   if (__pthread_manager_thread_bos == NULL) return -1;
523   __pthread_manager_thread_tos =
524     __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
525
526   /* On non-MMU systems we make sure that the initial thread bounds don't overlap
527    * with the manager stack frame */
528   NOMMU_INITIAL_THREAD_BOUNDS(__pthread_manager_thread_tos,__pthread_manager_thread_bos);
529   PDEBUG("manager stack: size=%d, bos=%p, tos=%p\n", THREAD_MANAGER_STACK_SIZE,
530          __pthread_manager_thread_bos, __pthread_manager_thread_tos);
531 #if 0
532   PDEBUG("initial stack: estimate bos=%p, tos=%p\n",
533          __pthread_initial_thread_bos, __pthread_initial_thread_tos);
534 #endif
535
536   /* Setup pipe to communicate with thread manager */
537   if (pipe(manager_pipe) == -1) {
538     free(__pthread_manager_thread_bos);
539     return -1;
540   }
541   /* Start the thread manager */
542   pid = 0;
543 #ifdef USE_TLS
544   if (__linuxthreads_initial_report_events != 0)
545     THREAD_SETMEM (((pthread_descr) NULL), p_report_events,
546                    __linuxthreads_initial_report_events);
547   report_events = THREAD_GETMEM (((pthread_descr) NULL), p_report_events);
548 #else
549   if (__linuxthreads_initial_report_events != 0)
550     __pthread_initial_thread.p_report_events
551       = __linuxthreads_initial_report_events;
552   report_events = __pthread_initial_thread.p_report_events;
553 #endif
554   if (__builtin_expect (report_events, 0))
555     {
556       /* It's a bit more complicated.  We have to report the creation of
557          the manager thread.  */
558       int idx = __td_eventword (TD_CREATE);
559       uint32_t mask = __td_eventmask (TD_CREATE);
560
561       if ((mask & (__pthread_threads_events.event_bits[idx]
562                    | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
563           != 0)
564         {
565
566          __pthread_lock(__pthread_manager_thread.p_lock, NULL);
567
568 #ifdef __ia64__
569           pid = __clone2(__pthread_manager_event,
570                         (void **) __pthread_manager_thread_tos,
571                         THREAD_MANAGER_STACK_SIZE,
572                         CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
573                         (void *)(long)manager_pipe[0]);
574 #else
575           pid = clone(__pthread_manager_event,
576                         (void **) __pthread_manager_thread_tos,
577                         CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
578                         (void *)(long)manager_pipe[0]);
579 #endif
580
581           if (pid != -1)
582             {
583               /* Now fill in the information about the new thread in
584                  the newly created thread's data structure.  We cannot let
585                  the new thread do this since we don't know whether it was
586                  already scheduled when we send the event.  */
587               __pthread_manager_thread.p_eventbuf.eventdata =
588                   &__pthread_manager_thread;
589               __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
590               __pthread_last_event = &__pthread_manager_thread;
591               __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
592               __pthread_manager_thread.p_pid = pid;
593
594               /* Now call the function which signals the event.  */
595               __linuxthreads_create_event ();
596             }
597           /* Now restart the thread.  */
598           __pthread_unlock(__pthread_manager_thread.p_lock);
599         }
600     }
601
602   if (pid == 0) {
603 #ifdef __ia64__
604     pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_tos,
605                   THREAD_MANAGER_STACK_SIZE,
606                   CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
607                   (void *)(long)manager_pipe[0]);
608 #else
609     pid = clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
610                   CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
611                   (void *)(long)manager_pipe[0]);
612 #endif
613   }
614   if (pid == -1) {
615     free(__pthread_manager_thread_bos);
616     __libc_close(manager_pipe[0]);
617     __libc_close(manager_pipe[1]);
618     return -1;
619   }
620   __pthread_manager_request = manager_pipe[1]; /* writing end */
621   __pthread_manager_reader = manager_pipe[0]; /* reading end */
622   __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
623   __pthread_manager_thread.p_pid = pid;
624
625   /* Make gdb aware of new thread manager */
626   if (__pthread_threads_debug && __pthread_sig_debug > 0)
627     {
628       raise(__pthread_sig_debug);
629       /* We suspend ourself and gdb will wake us up when it is
630          ready to handle us. */
631       __pthread_wait_for_restart_signal(thread_self());
632     }
633   /* Synchronize debugging of the thread manager */
634   PDEBUG("send REQ_DEBUG to manager thread\n");
635   request.req_kind = REQ_DEBUG;
636   TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
637               (char *) &request, sizeof(request)));
638   return 0;
639 }
640
641 /* Thread creation */
642
643 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
644                          void * (*start_routine)(void *), void *arg)
645 {
646   pthread_descr self = thread_self();
647   struct pthread_request request;
648   if (__pthread_manager_request < 0) {
649     if (__pthread_initialize_manager() < 0) return EAGAIN;
650   }
651   request.req_thread = self;
652   request.req_kind = REQ_CREATE;
653   request.req_args.create.attr = attr;
654   request.req_args.create.fn = start_routine;
655   request.req_args.create.arg = arg;
656   sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
657               &request.req_args.create.mask);
658   PDEBUG("write REQ_CREATE to manager thread\n");
659   TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
660               (char *) &request, sizeof(request)));
661   PDEBUG("before suspend(self)\n");
662   suspend(self);
663   PDEBUG("after suspend(self)\n");
664   if (THREAD_GETMEM(self, p_retcode) == 0)
665     *thread = (pthread_t) THREAD_GETMEM(self, p_retval);
666   return THREAD_GETMEM(self, p_retcode);
667 }
668
669 /* Simple operations on thread identifiers */
670
671 pthread_t pthread_self(void)
672 {
673   pthread_descr self = thread_self();
674   return THREAD_GETMEM(self, p_tid);
675 }
676 libpthread_hidden_def (pthread_self)
677     
678 int pthread_equal(pthread_t thread1, pthread_t thread2)
679 {
680   return thread1 == thread2;
681 }
682 libpthread_hidden_def (pthread_equal)
683
684 /* Helper function for thread_self in the case of user-provided stacks */
685
686 #ifndef THREAD_SELF
687
688 pthread_descr __pthread_find_self(void)
689 {
690   char * sp = CURRENT_STACK_FRAME;
691   pthread_handle h;
692
693   /* __pthread_handles[0] is the initial thread, __pthread_handles[1] is
694      the manager threads handled specially in thread_self(), so start at 2 */
695   h = __pthread_handles + 2;
696   while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) h++;
697
698 #ifdef DEBUG_PT
699   if (h->h_descr == NULL) {
700       printf("*** %s ERROR descriptor is NULL!!!!! ***\n\n", __FUNCTION__);
701       _exit(1);
702   }
703 #endif
704
705   return h->h_descr;
706 }
707 #else
708
709 static pthread_descr thread_self_stack(void)
710 {
711     char *sp = CURRENT_STACK_FRAME;
712     pthread_handle h;
713
714     if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos)
715         return manager_thread;
716     h = __pthread_handles + 2;
717 # ifdef USE_TLS
718     while (h->h_descr == NULL
719             || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= h->h_bottom))
720         h++;
721 # else
722     while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom))
723         h++;
724 # endif
725     return h->h_descr;
726 }
727
728 #endif
729
730 /* Thread scheduling */
731
732 int pthread_setschedparam(pthread_t thread, int policy,
733                           const struct sched_param *param)
734 {
735   pthread_handle handle = thread_handle(thread);
736   pthread_descr th;
737
738   __pthread_lock(&handle->h_lock, NULL);
739   if (invalid_handle(handle, thread)) {
740     __pthread_unlock(&handle->h_lock);
741     return ESRCH;
742   }
743   th = handle->h_descr;
744   if (sched_setscheduler(th->p_pid, policy, param) == -1) {
745     __pthread_unlock(&handle->h_lock);
746     return errno;
747   }
748   th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
749   __pthread_unlock(&handle->h_lock);
750   if (__pthread_manager_request >= 0)
751     __pthread_manager_adjust_prio(th->p_priority);
752   return 0;
753 }
754 libpthread_hidden_def(pthread_setschedparam)
755
756 int pthread_getschedparam(pthread_t thread, int *policy,
757                           struct sched_param *param)
758 {
759   pthread_handle handle = thread_handle(thread);
760   int pid, pol;
761
762   __pthread_lock(&handle->h_lock, NULL);
763   if (invalid_handle(handle, thread)) {
764     __pthread_unlock(&handle->h_lock);
765     return ESRCH;
766   }
767   pid = handle->h_descr->p_pid;
768   __pthread_unlock(&handle->h_lock);
769   pol = sched_getscheduler(pid);
770   if (pol == -1) return errno;
771   if (sched_getparam(pid, param) == -1) return errno;
772   *policy = pol;
773   return 0;
774 }
775 libpthread_hidden_def(pthread_getschedparam)
776
777 /* Process-wide exit() request */
778
779 static void pthread_onexit_process(int retcode, void *arg attribute_unused)
780 {
781     struct pthread_request request;
782     pthread_descr self = thread_self();
783
784     if (__pthread_manager_request >= 0) {
785         request.req_thread = self;
786         request.req_kind = REQ_PROCESS_EXIT;
787         request.req_args.exit.code = retcode;
788         TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request,
789                     (char *) &request, sizeof(request)));
790         suspend(self);
791         /* Main thread should accumulate times for thread manager and its
792            children, so that timings for main thread account for all threads. */
793         if (self == __pthread_main_thread) {
794             waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
795             /* Since all threads have been asynchronously terminated
796              * (possibly holding locks), free cannot be used any more.  */
797             __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
798         }
799     }
800 }
801
802 /* The handler for the RESTART signal just records the signal received
803    in the thread descriptor, and optionally performs a siglongjmp
804    (for pthread_cond_timedwait). */
805
806 static void pthread_handle_sigrestart(int sig)
807 {
808     pthread_descr self = thread_self();
809     THREAD_SETMEM(self, p_signal, sig);
810     if (THREAD_GETMEM(self, p_signal_jmp) != NULL)
811         siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1);
812 }
813
814 /* The handler for the CANCEL signal checks for cancellation
815    (in asynchronous mode), for process-wide exit and exec requests.
816    For the thread manager thread, redirect the signal to
817    __pthread_manager_sighandler. */
818
819 static void pthread_handle_sigcancel(int sig)
820 {
821   pthread_descr self = thread_self();
822   sigjmp_buf * jmpbuf;
823   
824
825   if (self == &__pthread_manager_thread)
826     {
827 #ifdef THREAD_SELF
828       /* A new thread might get a cancel signal before it is fully
829          initialized, so that the thread register might still point to the
830          manager thread.  Double check that this is really the manager
831          thread.  */
832       pthread_descr real_self = thread_self_stack();
833       if (real_self == &__pthread_manager_thread)
834         {
835           __pthread_manager_sighandler(sig);
836           return;
837         }
838       /* Oops, thread_self() isn't working yet..  */
839       self = real_self;
840 # ifdef INIT_THREAD_SELF
841       INIT_THREAD_SELF(self, self->p_nr);
842 # endif
843 #else
844       __pthread_manager_sighandler(sig);
845       return;
846 #endif
847     }
848   if (__builtin_expect (__pthread_exit_requested, 0)) {
849     /* Main thread should accumulate times for thread manager and its
850        children, so that timings for main thread account for all threads. */
851     if (self == __pthread_main_thread) {
852 #ifdef USE_TLS
853       waitpid(__pthread_manager_thread->p_pid, NULL, __WCLONE);
854 #else
855       waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
856 #endif
857     }
858     _exit(__pthread_exit_code);
859   }
860   if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0)
861       && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
862     if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
863       __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
864     jmpbuf = THREAD_GETMEM(self, p_cancel_jmp);
865     if (jmpbuf != NULL) {
866       THREAD_SETMEM(self, p_cancel_jmp, NULL);
867       siglongjmp(*jmpbuf, 1);
868     }
869   }
870 }
871
872 /* Handler for the DEBUG signal.
873    The debugging strategy is as follows:
874    On reception of a REQ_DEBUG request (sent by new threads created to
875    the thread manager under debugging mode), the thread manager throws
876    __pthread_sig_debug to itself. The debugger (if active) intercepts
877    this signal, takes into account new threads and continue execution
878    of the thread manager by propagating the signal because it doesn't
879    know what it is specifically done for. In the current implementation,
880    the thread manager simply discards it. */
881
882 static void pthread_handle_sigdebug(int sig attribute_unused)
883 {
884   /* Nothing */
885 }
886
887 /* Reset the state of the thread machinery after a fork().
888    Close the pipe used for requests and set the main thread to the forked
889    thread.
890    Notice that we can't free the stack segments, as the forked thread
891    may hold pointers into them. */
892
893 void __pthread_reset_main_thread(void)
894 {
895   pthread_descr self = thread_self();
896
897   if (__pthread_manager_request != -1) {
898     /* Free the thread manager stack */
899     free(__pthread_manager_thread_bos);
900     __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
901     /* Close the two ends of the pipe */
902     __libc_close(__pthread_manager_request);
903     __libc_close(__pthread_manager_reader);
904     __pthread_manager_request = __pthread_manager_reader = -1;
905   }
906
907   /* Update the pid of the main thread */
908   THREAD_SETMEM(self, p_pid, getpid());
909   /* Make the forked thread the main thread */
910   __pthread_main_thread = self;
911   THREAD_SETMEM(self, p_nextlive, self);
912   THREAD_SETMEM(self, p_prevlive, self);
913   /* Now this thread modifies the global variables.  */
914   THREAD_SETMEM(self, p_errnop, &_errno);
915   THREAD_SETMEM(self, p_h_errnop, &_h_errno);
916 }
917
918 /* Process-wide exec() request */
919
920 void __pthread_kill_other_threads_np(void)
921 {
922   struct sigaction sa;
923   /* Terminate all other threads and thread manager */
924   pthread_onexit_process(0, NULL);
925   /* Make current thread the main thread in case the calling thread
926      changes its mind, does not exec(), and creates new threads instead. */
927   __pthread_reset_main_thread();
928   /* Reset the signal handlers behaviour for the signals the
929      implementation uses since this would be passed to the new
930      process.  */
931   sigemptyset(&sa.sa_mask);
932   sa.sa_flags = 0;
933   sa.sa_handler = SIG_DFL;
934   __libc_sigaction(__pthread_sig_restart, &sa, NULL);
935   __libc_sigaction(__pthread_sig_cancel, &sa, NULL);
936   if (__pthread_sig_debug > 0)
937     __libc_sigaction(__pthread_sig_debug, &sa, NULL);
938 }
939 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
940
941 /* Concurrency symbol level.  */
942 static int current_level;
943
944 int __pthread_setconcurrency(int level)
945 {
946   /* We don't do anything unless we have found a useful interpretation.  */
947   current_level = level;
948   return 0;
949 }
950 weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
951
952 int __pthread_getconcurrency(void)
953 {
954   return current_level;
955 }
956 weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
957
958
959 /* Primitives for controlling thread execution */
960
961 void __pthread_wait_for_restart_signal(pthread_descr self)
962 {
963     sigset_t mask;
964
965     sigprocmask(SIG_SETMASK, NULL, &mask); /* Get current signal mask */
966     sigdelset(&mask, __pthread_sig_restart); /* Unblock the restart signal */
967     THREAD_SETMEM(self, p_signal, 0);
968     do {
969         sigsuspend(&mask);                   /* Wait for signal */
970     } while (THREAD_GETMEM(self, p_signal) !=__pthread_sig_restart);
971
972     READ_MEMORY_BARRIER(); /* See comment in __pthread_restart_new */
973 }
974
975 #ifndef __NR_rt_sigaction
976 /* The _old variants are for 2.0 and early 2.1 kernels which don't have RT
977    signals.
978    On these kernels, we use SIGUSR1 and SIGUSR2 for restart and cancellation.
979    Since the restart signal does not queue, we use an atomic counter to create
980    queuing semantics. This is needed to resolve a rare race condition in
981    pthread_cond_timedwait_relative. */
982
983 void __pthread_restart_old(pthread_descr th)
984 {
985     if (atomic_increment(&th->p_resume_count) == -1)
986         kill(th->p_pid, __pthread_sig_restart);
987 }
988
989 void __pthread_suspend_old(pthread_descr self)
990 {
991     if (atomic_decrement(&self->p_resume_count) <= 0)
992         __pthread_wait_for_restart_signal(self);
993 }
994
995 int
996 __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime)
997 {
998   sigset_t unblock, initial_mask;
999   int was_signalled = 0;
1000   sigjmp_buf jmpbuf;
1001
1002   if (atomic_decrement(&self->p_resume_count) == 0) {
1003     /* Set up a longjmp handler for the restart signal, unblock
1004        the signal and sleep. */
1005
1006     if (sigsetjmp(jmpbuf, 1) == 0) {
1007       THREAD_SETMEM(self, p_signal_jmp, &jmpbuf);
1008       THREAD_SETMEM(self, p_signal, 0);
1009       /* Unblock the restart signal */
1010       sigemptyset(&unblock);
1011       sigaddset(&unblock, __pthread_sig_restart);
1012       sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
1013
1014       while (1) {
1015         struct timeval now;
1016         struct timespec reltime;
1017
1018         /* Compute a time offset relative to now.  */
1019         gettimeofday (&now, NULL);
1020         reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
1021         reltime.tv_sec = abstime->tv_sec - now.tv_sec;
1022         if (reltime.tv_nsec < 0) {
1023           reltime.tv_nsec += 1000000000;
1024           reltime.tv_sec -= 1;
1025         }
1026
1027         /* Sleep for the required duration. If woken by a signal,
1028            resume waiting as required by Single Unix Specification.  */
1029         if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0)
1030           break;
1031       }
1032
1033       /* Block the restart signal again */
1034       sigprocmask(SIG_SETMASK, &initial_mask, NULL);
1035       was_signalled = 0;
1036     } else {
1037       was_signalled = 1;
1038     }
1039     THREAD_SETMEM(self, p_signal_jmp, NULL);
1040   }
1041
1042   /* Now was_signalled is true if we exited the above code
1043      due to the delivery of a restart signal.  In that case,
1044      we know we have been dequeued and resumed and that the
1045      resume count is balanced.  Otherwise, there are some
1046      cases to consider. First, try to bump up the resume count
1047      back to zero. If it goes to 1, it means restart() was
1048      invoked on this thread. The signal must be consumed
1049      and the count bumped down and everything is cool. We
1050      can return a 1 to the caller.
1051      Otherwise, no restart was delivered yet, so a potential
1052      race exists; we return a 0 to the caller which must deal
1053      with this race in an appropriate way; for example by
1054      atomically removing the thread from consideration for a
1055      wakeup---if such a thing fails, it means a restart is
1056      being delivered. */
1057
1058   if (!was_signalled) {
1059     if (atomic_increment(&self->p_resume_count) != -1) {
1060       __pthread_wait_for_restart_signal(self);
1061       atomic_decrement(&self->p_resume_count); /* should be zero now! */
1062       /* woke spontaneously and consumed restart signal */
1063       return 1;
1064     }
1065     /* woke spontaneously but did not consume restart---caller must resolve */
1066     return 0;
1067   }
1068   /* woken due to restart signal */
1069   return 1;
1070 }
1071 #endif /* __NR_rt_sigaction */
1072
1073
1074 #ifdef __NR_rt_sigaction
1075 void __pthread_restart_new(pthread_descr th)
1076 {
1077     /* The barrier is proabably not needed, in which case it still documents
1078        our assumptions. The intent is to commit previous writes to shared
1079        memory so the woken thread will have a consistent view.  Complementary
1080        read barriers are present to the suspend functions. */
1081     WRITE_MEMORY_BARRIER();
1082     kill(th->p_pid, __pthread_sig_restart);
1083 }
1084
1085 int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstime)
1086 {
1087     sigset_t unblock, initial_mask;
1088     int was_signalled = 0;
1089     sigjmp_buf jmpbuf;
1090
1091     if (sigsetjmp(jmpbuf, 1) == 0) {
1092         THREAD_SETMEM(self, p_signal_jmp, &jmpbuf);
1093         THREAD_SETMEM(self, p_signal, 0);
1094         /* Unblock the restart signal */
1095         sigemptyset(&unblock);
1096         sigaddset(&unblock, __pthread_sig_restart);
1097         sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
1098
1099         while (1) {
1100             struct timeval now;
1101             struct timespec reltime;
1102
1103             /* Compute a time offset relative to now.  */
1104             gettimeofday (&now, NULL);
1105             reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
1106             reltime.tv_sec = abstime->tv_sec - now.tv_sec;
1107             if (reltime.tv_nsec < 0) {
1108                 reltime.tv_nsec += 1000000000;
1109                 reltime.tv_sec -= 1;
1110             }
1111
1112             /* Sleep for the required duration. If woken by a signal,
1113                resume waiting as required by Single Unix Specification.  */
1114             if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0)
1115                 break;
1116         }
1117
1118         /* Block the restart signal again */
1119         sigprocmask(SIG_SETMASK, &initial_mask, NULL);
1120         was_signalled = 0;
1121     } else {
1122         was_signalled = 1;
1123     }
1124     THREAD_SETMEM(self, p_signal_jmp, NULL);
1125
1126     /* Now was_signalled is true if we exited the above code
1127        due to the delivery of a restart signal.  In that case,
1128        everything is cool. We have been removed from whatever
1129        we were waiting on by the other thread, and consumed its signal.
1130
1131        Otherwise we this thread woke up spontaneously, or due to a signal other
1132        than restart. This is an ambiguous case  that must be resolved by
1133        the caller; the thread is still eligible for a restart wakeup
1134        so there is a race. */
1135
1136     READ_MEMORY_BARRIER(); /* See comment in __pthread_restart_new */
1137     return was_signalled;
1138 }
1139 #endif
1140
1141 /* Debugging aid */
1142
1143 #ifdef DEBUG_PT
1144 #include <stdarg.h>
1145
1146 void __pthread_message(char * fmt, ...)
1147 {
1148   char buffer[1024];
1149   va_list args;
1150   sprintf(buffer, "%05d : ", getpid());
1151   va_start(args, fmt);
1152   vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
1153   va_end(args);
1154   TEMP_FAILURE_RETRY(__libc_write(2, buffer, strlen(buffer)));
1155 }
1156
1157 #endif
1158
1159
1160 #ifndef __PIC__
1161 /* We need a hook to force the cancelation wrappers to be linked in when
1162    static libpthread is used.  */
1163 extern const int __pthread_provide_wrappers;
1164 static const int *const __pthread_require_wrappers =
1165   &__pthread_provide_wrappers;
1166 #endif