Remove K&R compatibility.
[kopensolaris-gnu/glibc.git] / linuxthreads / 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 #include <errno.h>
18 #include <stddef.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #ifdef __i386__
25 # include <ucontext.h>
26 #endif
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
34 /* Descriptor of the initial thread */
35
36 struct _pthread_descr_struct __pthread_initial_thread = {
37   &__pthread_initial_thread,  /* pthread_descr p_nextlive */
38   &__pthread_initial_thread,  /* pthread_descr p_prevlive */
39   NULL,                       /* pthread_descr p_nextwaiting */
40   NULL,                       /* pthread_descr p_nextlock */
41   PTHREAD_THREADS_MAX,        /* pthread_t p_tid */
42   0,                          /* int p_pid */
43   0,                          /* int p_priority */
44   &__pthread_handles[0].h_lock, /* struct _pthread_fastlock * p_lock */
45   0,                          /* int p_signal */
46   NULL,                       /* sigjmp_buf * p_signal_buf */
47   NULL,                       /* sigjmp_buf * p_cancel_buf */
48   0,                          /* char p_terminated */
49   0,                          /* char p_detached */
50   0,                          /* char p_exited */
51   NULL,                       /* void * p_retval */
52   0,                          /* int p_retval */
53   NULL,                       /* pthread_descr p_joining */
54   NULL,                       /* struct _pthread_cleanup_buffer * p_cleanup */
55   0,                          /* char p_cancelstate */
56   0,                          /* char p_canceltype */
57   0,                          /* char p_canceled */
58   NULL,                       /* int *p_errnop */
59   0,                          /* int p_errno */
60   NULL,                       /* int *p_h_errnop */
61   0,                          /* int p_h_errno */
62   NULL,                       /* char * p_in_sighandler */
63   0,                          /* char p_sigwaiting */
64   PTHREAD_START_ARGS_INITIALIZER(NULL),
65                               /* struct pthread_start_args p_start_args */
66   {NULL},                     /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */
67   {NULL},                     /* void * p_libc_specific[_LIBC_TSD_KEY_N] */
68   0,                          /* int p_userstack */
69   NULL,                       /* void * p_guardaddr */
70   0,                          /* size_t p_guardsize */
71   &__pthread_initial_thread,  /* pthread_descr p_self */
72   0                           /* Always index 0 */
73 };
74
75 /* Descriptor of the manager thread; none of this is used but the error
76    variables, the p_pid and p_priority fields,
77    and the address for identification.  */
78
79 struct _pthread_descr_struct __pthread_manager_thread = {
80   NULL,                       /* pthread_descr p_nextlive */
81   NULL,                       /* pthread_descr p_prevlive */
82   NULL,                       /* pthread_descr p_nextwaiting */
83   NULL,                       /* pthread_descr p_nextlock */
84   0,                          /* int p_tid */
85   0,                          /* int p_pid */
86   0,                          /* int p_priority */
87   NULL,                       /* struct _pthread_fastlock * p_lock */
88   0,                          /* int p_signal */
89   NULL,                       /* sigjmp_buf * p_signal_buf */
90   NULL,                       /* sigjmp_buf * p_cancel_buf */
91   0,                          /* char p_terminated */
92   0,                          /* char p_detached */
93   0,                          /* char p_exited */
94   NULL,                       /* void * p_retval */
95   0,                          /* int p_retval */
96   NULL,                       /* pthread_descr p_joining */
97   NULL,                       /* struct _pthread_cleanup_buffer * p_cleanup */
98   0,                          /* char p_cancelstate */
99   0,                          /* char p_canceltype */
100   0,                          /* char p_canceled */
101   &__pthread_manager_thread.p_errno, /* int *p_errnop */
102   0,                          /* int p_errno */
103   NULL,                       /* int *p_h_errnop */
104   0,                          /* int p_h_errno */
105   NULL,                       /* char * p_in_sighandler */
106   0,                          /* char p_sigwaiting */
107   PTHREAD_START_ARGS_INITIALIZER(__pthread_manager),
108                               /* struct pthread_start_args p_start_args */
109   {NULL},                     /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */
110   {NULL},                     /* void * p_libc_specific[_LIBC_TSD_KEY_N] */
111   0,                          /* int p_userstack */
112   NULL,                       /* void * p_guardaddr */
113   0,                          /* size_t p_guardsize */
114   &__pthread_manager_thread,  /* pthread_descr p_self */
115   1                           /* Always index 1 */
116 };
117
118 /* Pointer to the main thread (the father of the thread manager thread) */
119 /* Originally, this is the initial thread, but this changes after fork() */
120
121 pthread_descr __pthread_main_thread = &__pthread_initial_thread;
122
123 /* Limit between the stack of the initial thread (above) and the
124    stacks of other threads (below). Aligned on a STACK_SIZE boundary. */
125
126 char *__pthread_initial_thread_bos = NULL;
127
128 /* File descriptor for sending requests to the thread manager. */
129 /* Initially -1, meaning that the thread manager is not running. */
130
131 int __pthread_manager_request = -1;
132
133 /* Other end of the pipe for sending requests to the thread manager. */
134
135 int __pthread_manager_reader;
136
137 /* Limits of the thread manager stack */
138
139 char *__pthread_manager_thread_bos = NULL;
140 char *__pthread_manager_thread_tos = NULL;
141
142 /* For process-wide exit() */
143
144 int __pthread_exit_requested = 0;
145 int __pthread_exit_code = 0;
146
147 /* Communicate relevant LinuxThreads constants to gdb */
148
149 const int __pthread_threads_max = PTHREAD_THREADS_MAX;
150 const int __pthread_sizeof_handle = sizeof(struct pthread_handle_struct);
151 const int __pthread_offsetof_descr = offsetof(struct pthread_handle_struct,
152                                               h_descr);
153 const int __pthread_offsetof_pid = offsetof(struct _pthread_descr_struct,
154                                             p_pid);
155 const int __linuxthread_pthread_sizeof_descr
156   = sizeof(struct _pthread_descr_struct);
157
158 /* These variables are used by the setup code.  */
159 extern int _errno;
160 extern int _h_errno;
161
162 /* Forward declarations */
163
164 static void pthread_exit_process(int retcode, void *arg);
165 static void pthread_handle_sigcancel(int sig);
166 static void pthread_handle_sigrestart(int sig);
167 #ifdef __i386__
168 static void pthread_handle_sigrestart_nonrt(int sig, struct sigcontext ctx);
169 static void pthread_handle_sigrestart_rt(int sig, struct siginfo *si,
170                                          struct ucontext *uc);
171 static void pthread_handle_sigcancel_nonrt(int sig, struct sigcontext ctx);
172 static void pthread_handle_sigcancel_rt(int sig, struct siginfo *si,
173                                          struct ucontext *uc);
174 #endif
175 static void pthread_handle_sigdebug(int sig);
176
177 /* Signal numbers used for the communication.
178    In these variables we keep track of the used variables.  If the
179    platform does not support any real-time signals we will define the
180    values to some unreasonable value which will signal failing of all
181    the functions below.  */
182 #ifndef __SIGRTMIN
183 static int current_rtmin = -1;
184 static int current_rtmax = -1;
185 int __pthread_sig_restart = SIGUSR1;
186 int __pthread_sig_cancel = SIGUSR2;
187 int __pthread_sig_debug = 0;
188 #else
189 static int current_rtmin;
190 static int current_rtmax;
191
192 #if __SIGRTMAX - __SIGRTMIN >= 3
193 int __pthread_sig_restart = __SIGRTMIN;
194 int __pthread_sig_cancel = __SIGRTMIN + 1;
195 int __pthread_sig_debug = __SIGRTMIN + 2;
196 #else
197 int __pthread_sig_restart = SIGUSR1;
198 int __pthread_sig_cancel = SIGUSR2;
199 int __pthread_sig_debug = 0;
200 #endif
201
202 static int rtsigs_initialized;
203
204 #include "testrtsig.h"
205
206 static void
207 init_rtsigs (void)
208 {
209   if (!kernel_has_rtsig ())
210     {
211       current_rtmin = -1;
212       current_rtmax = -1;
213 #if __SIGRTMAX - __SIGRTMIN >= 3
214       __pthread_sig_restart = SIGUSR1;
215       __pthread_sig_cancel = SIGUSR2;
216       __pthread_sig_debug = 0;
217 #endif
218     }
219   else
220     {
221 #if __SIGRTMAX - __SIGRTMIN >= 3
222       current_rtmin = __SIGRTMIN + 3;
223 #else
224       current_rtmin = __SIGRTMIN;
225 #endif
226
227       current_rtmax = __SIGRTMAX;
228     }
229
230   rtsigs_initialized = 1;
231 }
232 #endif
233
234 /* Return number of available real-time signal with highest priority.  */
235 int
236 __libc_current_sigrtmin (void)
237 {
238 #ifdef __SIGRTMIN
239   if (!rtsigs_initialized)
240     init_rtsigs ();
241 #endif
242   return current_rtmin;
243 }
244
245 /* Return number of available real-time signal with lowest priority.  */
246 int
247 __libc_current_sigrtmax (void)
248 {
249 #ifdef __SIGRTMIN
250   if (!rtsigs_initialized)
251     init_rtsigs ();
252 #endif
253   return current_rtmax;
254 }
255
256 /* Allocate real-time signal with highest/lowest available
257    priority.  Please note that we don't use a lock since we assume
258    this function to be called at program start.  */
259 int
260 __libc_allocate_rtsig (int high)
261 {
262 #ifndef __SIGRTMIN
263   return -1;
264 #else
265   if (!rtsigs_initialized)
266     init_rtsigs ();
267   if (current_rtmin == -1 || current_rtmin > current_rtmax)
268     /* We don't have anymore signal available.  */
269     return -1;
270
271   return high ? current_rtmin++ : current_rtmax--;
272 #endif
273 }
274
275 /* Initialize the pthread library.
276    Initialization is split in two functions:
277    - a constructor function that blocks the __pthread_sig_restart signal
278      (must do this very early, since the program could capture the signal
279       mask with e.g. sigsetjmp before creating the first thread);
280    - a regular function called from pthread_create when needed. */
281
282 static void pthread_initialize(void) __attribute__((constructor));
283
284 static void pthread_initialize(void)
285 {
286   struct sigaction sa;
287   sigset_t mask;
288   struct rlimit limit;
289   int max_stack;
290
291   /* If already done (e.g. by a constructor called earlier!), bail out */
292   if (__pthread_initial_thread_bos != NULL) return;
293 #ifdef TEST_FOR_COMPARE_AND_SWAP
294   /* Test if compare-and-swap is available */
295   __pthread_has_cas = compare_and_swap_is_available();
296 #endif
297   /* For the initial stack, reserve at least STACK_SIZE bytes of stack
298      below the current stack address, and align that on a
299      STACK_SIZE boundary. */
300   __pthread_initial_thread_bos =
301     (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
302   /* Play with the stack size limit to make sure that no stack ever grows
303      beyond STACK_SIZE minus two pages (one page for the thread descriptor
304      immediately beyond, and one page to act as a guard page). */
305   getrlimit(RLIMIT_STACK, &limit);
306   max_stack = STACK_SIZE - 2 * __getpagesize();
307   if (limit.rlim_cur > max_stack) {
308     limit.rlim_cur = max_stack;
309     setrlimit(RLIMIT_STACK, &limit);
310   }
311   /* Update the descriptor for the initial thread. */
312   __pthread_initial_thread.p_pid = __getpid();
313   /* If we have special thread_self processing, initialize that for the
314      main thread now.  */
315 #ifdef INIT_THREAD_SELF
316   INIT_THREAD_SELF(&__pthread_initial_thread, 0);
317 #endif
318   /* The errno/h_errno variable of the main thread are the global ones.  */
319   __pthread_initial_thread.p_errnop = &_errno;
320   __pthread_initial_thread.p_h_errnop = &_h_errno;
321 #ifdef __SIGRTMIN
322   /* Initialize real-time signals. */
323   init_rtsigs ();
324 #endif
325   /* Setup signal handlers for the initial thread.
326      Since signal handlers are shared between threads, these settings
327      will be inherited by all other threads. */
328 #ifndef __i386__
329   sa.sa_handler = pthread_handle_sigrestart;
330 #else
331   if (__pthread_sig_restart >= SIGRTMIN)
332     sa.sa_handler = (__sighandler_t) pthread_handle_sigrestart_rt;
333   else
334     sa.sa_handler = (__sighandler_t) pthread_handle_sigrestart_nonrt;
335 #endif
336   sigemptyset(&sa.sa_mask);
337   sa.sa_flags = 0;
338   __sigaction(__pthread_sig_restart, &sa, NULL);
339 #ifndef __i386__
340   sa.sa_handler = pthread_handle_sigcancel;
341 #else
342   if (__pthread_sig_restart >= SIGRTMIN)
343     sa.sa_handler = (__sighandler_t) pthread_handle_sigcancel_rt;
344   else
345     sa.sa_handler = (__sighandler_t) pthread_handle_sigcancel_nonrt;
346 #endif
347   sa.sa_flags = 0;
348   __sigaction(__pthread_sig_cancel, &sa, NULL);
349   if (__pthread_sig_debug > 0) {
350     sa.sa_handler = pthread_handle_sigdebug;
351     sigemptyset(&sa.sa_mask);
352     sa.sa_flags = 0;
353     __sigaction(__pthread_sig_debug, &sa, NULL);
354   }
355   /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */
356   sigemptyset(&mask);
357   sigaddset(&mask, __pthread_sig_restart);
358   sigprocmask(SIG_BLOCK, &mask, NULL);
359   /* Register an exit function to kill all other threads. */
360   /* Do it early so that user-registered atexit functions are called
361      before pthread_exit_process. */
362   __on_exit(pthread_exit_process, NULL);
363 }
364
365 void __pthread_initialize(void)
366 {
367   pthread_initialize();
368 }
369
370 int __pthread_initialize_manager(void)
371 {
372   int manager_pipe[2];
373   int pid;
374   struct pthread_request request;
375
376   /* If basic initialization not done yet (e.g. we're called from a
377      constructor run before our constructor), do it now */
378   if (__pthread_initial_thread_bos == NULL) pthread_initialize();
379   /* Setup stack for thread manager */
380   __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
381   if (__pthread_manager_thread_bos == NULL) return -1;
382   __pthread_manager_thread_tos =
383     __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
384   /* Setup pipe to communicate with thread manager */
385   if (pipe(manager_pipe) == -1) {
386     free(__pthread_manager_thread_bos);
387     return -1;
388   }
389   /* Start the thread manager */
390   pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
391                 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
392                 , (void *)(long)manager_pipe[0]);
393   if (pid == -1) {
394     free(__pthread_manager_thread_bos);
395     __libc_close(manager_pipe[0]);
396     __libc_close(manager_pipe[1]);
397     return -1;
398   }
399   __pthread_manager_request = manager_pipe[1]; /* writing end */
400   __pthread_manager_reader = manager_pipe[0]; /* reading end */
401   __pthread_manager_thread.p_pid = pid;
402   /* Make gdb aware of new thread manager */
403   if (__pthread_threads_debug && __pthread_sig_debug > 0)
404     {
405       raise(__pthread_sig_debug);
406       /* We suspend ourself and gdb will wake us up when it is
407          ready to handle us. */
408       suspend(thread_self());
409     }
410   /* Synchronize debugging of the thread manager */
411   request.req_kind = REQ_DEBUG;
412   __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
413   return 0;
414 }
415
416 /* Thread creation */
417
418 int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
419                          void * (*start_routine)(void *), void *arg)
420 {
421   pthread_descr self = thread_self();
422   struct pthread_request request;
423   if (__pthread_manager_request < 0) {
424     if (__pthread_initialize_manager() < 0) return EAGAIN;
425   }
426   request.req_thread = self;
427   request.req_kind = REQ_CREATE;
428   request.req_args.create.attr = attr;
429   request.req_args.create.fn = start_routine;
430   request.req_args.create.arg = arg;
431   sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
432               &request.req_args.create.mask);
433   __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
434   suspend(self);
435   if (THREAD_GETMEM(self, p_retcode) == 0)
436     *thread = (pthread_t) THREAD_GETMEM(self, p_retval);
437   return THREAD_GETMEM(self, p_retcode);
438 }
439
440 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
441 default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
442
443 int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
444                          void * (*start_routine)(void *), void *arg)
445 {
446   /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
447      the old size and access to the new members might crash the program.
448      We convert the struct now.  */
449   pthread_attr_t new_attr;
450
451   if (attr != NULL)
452     {
453       size_t ps = __getpagesize ();
454
455       memcpy (&new_attr, attr,
456               (size_t) &(((pthread_attr_t*)NULL)->__guardsize));
457       new_attr.__guardsize = ps;
458       new_attr.__stackaddr_set = 0;
459       new_attr.__stackaddr = NULL;
460       new_attr.__stacksize = STACK_SIZE - ps;
461       attr = &new_attr;
462     }
463   return __pthread_create_2_1 (thread, attr, start_routine, arg);
464 }
465 symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
466 #else
467 strong_alias (__pthread_create_2_1, pthread_create)
468 #endif
469
470 /* Simple operations on thread identifiers */
471
472 pthread_t pthread_self(void)
473 {
474   pthread_descr self = thread_self();
475   return THREAD_GETMEM(self, p_tid);
476 }
477
478 int pthread_equal(pthread_t thread1, pthread_t thread2)
479 {
480   return thread1 == thread2;
481 }
482
483 /* Helper function for thread_self in the case of user-provided stacks */
484
485 #ifndef THREAD_SELF
486
487 pthread_descr __pthread_find_self()
488 {
489   char * sp = CURRENT_STACK_FRAME;
490   pthread_handle h;
491
492   /* __pthread_handles[0] is the initial thread, __pthread_handles[1] is
493      the manager threads handled specially in thread_self(), so start at 2 */
494   h = __pthread_handles + 2;
495   while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) h++;
496   return h->h_descr;
497 }
498
499 #endif
500
501 /* Thread scheduling */
502
503 int pthread_setschedparam(pthread_t thread, int policy,
504                           const struct sched_param *param)
505 {
506   pthread_handle handle = thread_handle(thread);
507   pthread_descr th;
508
509   __pthread_lock(&handle->h_lock, NULL);
510   if (invalid_handle(handle, thread)) {
511     __pthread_unlock(&handle->h_lock);
512     return ESRCH;
513   }
514   th = handle->h_descr;
515   if (__sched_setscheduler(th->p_pid, policy, param) == -1) {
516     __pthread_unlock(&handle->h_lock);
517     return errno;
518   }
519   th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
520   __pthread_unlock(&handle->h_lock);
521   if (__pthread_manager_request >= 0)
522     __pthread_manager_adjust_prio(th->p_priority);
523   return 0;
524 }
525
526 int pthread_getschedparam(pthread_t thread, int *policy,
527                           struct sched_param *param)
528 {
529   pthread_handle handle = thread_handle(thread);
530   int pid, pol;
531
532   __pthread_lock(&handle->h_lock, NULL);
533   if (invalid_handle(handle, thread)) {
534     __pthread_unlock(&handle->h_lock);
535     return ESRCH;
536   }
537   pid = handle->h_descr->p_pid;
538   __pthread_unlock(&handle->h_lock);
539   pol = __sched_getscheduler(pid);
540   if (pol == -1) return errno;
541   if (__sched_getparam(pid, param) == -1) return errno;
542   *policy = pol;
543   return 0;
544 }
545
546 /* Process-wide exit() request */
547
548 static void pthread_exit_process(int retcode, void *arg)
549 {
550   struct pthread_request request;
551   pthread_descr self = thread_self();
552
553   if (__pthread_manager_request >= 0) {
554     request.req_thread = self;
555     request.req_kind = REQ_PROCESS_EXIT;
556     request.req_args.exit.code = retcode;
557     __libc_write(__pthread_manager_request,
558                  (char *) &request, sizeof(request));
559     suspend(self);
560     /* Main thread should accumulate times for thread manager and its
561        children, so that timings for main thread account for all threads. */
562     if (self == __pthread_main_thread)
563       waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
564   }
565 }
566
567 /* The handler for the RESTART signal just records the signal received
568    in the thread descriptor, and optionally performs a siglongjmp
569    (for pthread_cond_timedwait). */
570
571 static void pthread_handle_sigrestart(int sig)
572 {
573   pthread_descr self = thread_self();
574   THREAD_SETMEM(self, p_signal, sig);
575   if (THREAD_GETMEM(self, p_signal_jmp) != NULL)
576     siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1);
577 }
578
579 #ifdef __i386__
580 static void pthread_handle_sigrestart_nonrt(int sig, struct sigcontext ctx)
581 {
582   asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
583   pthread_handle_sigrestart(sig);
584 }
585
586 static void pthread_handle_sigrestart_rt(int sig, struct siginfo *si,
587                                          struct ucontext *uc)
588 {
589   asm volatile ("movw %w0,%%gs" : : "r" (uc->uc_mcontext.gregs[GS]));
590   pthread_handle_sigrestart(sig);
591 }
592 #endif
593
594 /* The handler for the CANCEL signal checks for cancellation
595    (in asynchronous mode), for process-wide exit and exec requests.
596    For the thread manager thread, redirect the signal to
597    __pthread_manager_sighandler. */
598
599 static void pthread_handle_sigcancel(int sig)
600 {
601   pthread_descr self = thread_self();
602   sigjmp_buf * jmpbuf;
603
604   if (self == &__pthread_manager_thread)
605     {
606       __pthread_manager_sighandler(sig);
607       return;
608     }
609   if (__pthread_exit_requested) {
610     /* Main thread should accumulate times for thread manager and its
611        children, so that timings for main thread account for all threads. */
612     if (self == __pthread_main_thread)
613       waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
614     _exit(__pthread_exit_code);
615   }
616   if (THREAD_GETMEM(self, p_canceled)
617       && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
618     if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
619       pthread_exit(PTHREAD_CANCELED);
620     jmpbuf = THREAD_GETMEM(self, p_cancel_jmp);
621     if (jmpbuf != NULL) {
622       THREAD_SETMEM(self, p_cancel_jmp, NULL);
623       siglongjmp(*jmpbuf, 1);
624     }
625   }
626 }
627
628 #ifdef __i386__
629 static void pthread_handle_sigcancel_nonrt(int sig, struct sigcontext ctx)
630 {
631   asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
632   pthread_handle_sigcancel(sig);
633 }
634
635 static void pthread_handle_sigcancel_rt(int sig, struct siginfo *si,
636                                          struct ucontext *uc)
637 {
638   asm volatile ("movw %w0,%%gs" : : "r" (uc->uc_mcontext.gregs[GS]));
639   pthread_handle_sigcancel(sig);
640 }
641 #endif
642
643 /* Handler for the DEBUG signal.
644    The debugging strategy is as follows:
645    On reception of a REQ_DEBUG request (sent by new threads created to
646    the thread manager under debugging mode), the thread manager throws
647    __pthread_sig_debug to itself. The debugger (if active) intercepts
648    this signal, takes into account new threads and continue execution
649    of the thread manager by propagating the signal because it doesn't
650    know what it is specifically done for. In the current implementation,
651    the thread manager simply discards it. */
652
653 static void pthread_handle_sigdebug(int sig)
654 {
655   /* Nothing */
656 }
657
658 /* Reset the state of the thread machinery after a fork().
659    Close the pipe used for requests and set the main thread to the forked
660    thread.
661    Notice that we can't free the stack segments, as the forked thread
662    may hold pointers into them. */
663
664 void __pthread_reset_main_thread()
665 {
666   pthread_descr self = thread_self();
667
668   if (__pthread_manager_request != -1) {
669     /* Free the thread manager stack */
670     free(__pthread_manager_thread_bos);
671     __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
672     /* Close the two ends of the pipe */
673     __libc_close(__pthread_manager_request);
674     __libc_close(__pthread_manager_reader);
675     __pthread_manager_request = __pthread_manager_reader = -1;
676   }
677
678   /* Update the pid of the main thread */
679   THREAD_SETMEM(self, p_pid, __getpid());
680   /* Make the forked thread the main thread */
681   __pthread_main_thread = self;
682   THREAD_SETMEM(self, p_nextlive, self);
683   THREAD_SETMEM(self, p_prevlive, self);
684   /* Now this thread modifies the global variables.  */
685   THREAD_SETMEM(self, p_errnop, &_errno);
686   THREAD_SETMEM(self, p_h_errnop, &_h_errno);
687 }
688
689 /* Process-wide exec() request */
690
691 void __pthread_kill_other_threads_np(void)
692 {
693   struct sigaction sa;
694   /* Terminate all other threads and thread manager */
695   pthread_exit_process(0, NULL);
696   /* Make current thread the main thread in case the calling thread
697      changes its mind, does not exec(), and creates new threads instead. */
698   __pthread_reset_main_thread();
699
700   /* Reset the signal handlers behaviour for the signals the
701      implementation uses since this would be passed to the new
702      process.  */
703   sigemptyset(&sa.sa_mask);
704   sa.sa_flags = 0;
705   sa.sa_handler = SIG_DFL;
706   __sigaction(__pthread_sig_restart, &sa, NULL);
707   __sigaction(__pthread_sig_cancel, &sa, NULL);
708   if (__pthread_sig_debug > 0)
709     __sigaction(__pthread_sig_debug, &sa, NULL);
710 }
711 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
712
713 /* Concurrency symbol level.  */
714 static int current_level;
715
716 int __pthread_setconcurrency(int level)
717 {
718   /* We don't do anything unless we have found a useful interpretation.  */
719   current_level = level;
720   return 0;
721 }
722 weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
723
724 int __pthread_getconcurrency(void)
725 {
726   return current_level;
727 }
728 weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
729
730 /* Debugging aid */
731
732 #ifdef DEBUG
733 #include <stdarg.h>
734
735 void __pthread_message(char * fmt, ...)
736 {
737   char buffer[1024];
738   va_list args;
739   sprintf(buffer, "%05d : ", __getpid());
740   va_start(args, fmt);
741   vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
742   va_end(args);
743   __libc_write(2, buffer, strlen(buffer));
744 }
745
746 #endif
747
748
749 #ifndef PIC
750 /* We need a hook to force the cancelation wrappers to be linked in when
751    static libpthread is used.  */
752 extern const int __pthread_provide_wrappers;
753 static const int *const __pthread_require_wrappers =
754   &__pthread_provide_wrappers;
755 #endif