dfde08f432c96f144c59d35c8c40bd711cfd9a71
[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   &__pthread_handles[1].h_lock, /* 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   /* Update the descriptor for the initial thread. */
303   __pthread_initial_thread.p_pid = __getpid();
304   /* If we have special thread_self processing, initialize that for the
305      main thread now.  */
306 #ifdef INIT_THREAD_SELF
307   INIT_THREAD_SELF(&__pthread_initial_thread, 0);
308 #endif
309   /* The errno/h_errno variable of the main thread are the global ones.  */
310   __pthread_initial_thread.p_errnop = &_errno;
311   __pthread_initial_thread.p_h_errnop = &_h_errno;
312   /* Play with the stack size limit to make sure that no stack ever grows
313      beyond STACK_SIZE minus one page (to act as a guard page). */
314   getrlimit(RLIMIT_STACK, &limit);
315   max_stack = STACK_SIZE - __getpagesize();
316   if (limit.rlim_cur > max_stack) {
317     limit.rlim_cur = max_stack;
318     setrlimit(RLIMIT_STACK, &limit);
319   }
320   /* Likewise for the resolver state _res.  */
321   __pthread_initial_thread.p_resp = &_res;
322 #ifdef __SIGRTMIN
323   /* Initialize real-time signals. */
324   init_rtsigs ();
325 #endif
326   /* Setup signal handlers for the initial thread.
327      Since signal handlers are shared between threads, these settings
328      will be inherited by all other threads. */
329 #ifndef __i386__
330   sa.sa_handler = pthread_handle_sigrestart;
331 #else
332   if (__pthread_sig_restart >= SIGRTMIN)
333     sa.sa_handler = (__sighandler_t) pthread_handle_sigrestart_rt;
334   else
335     sa.sa_handler = (__sighandler_t) pthread_handle_sigrestart_nonrt;
336 #endif
337   sigemptyset(&sa.sa_mask);
338   sa.sa_flags = 0;
339   __sigaction(__pthread_sig_restart, &sa, NULL);
340 #ifndef __i386__
341   sa.sa_handler = pthread_handle_sigcancel;
342 #else
343   if (__pthread_sig_restart >= SIGRTMIN)
344     sa.sa_handler = (__sighandler_t) pthread_handle_sigcancel_rt;
345   else
346     sa.sa_handler = (__sighandler_t) pthread_handle_sigcancel_nonrt;
347 #endif
348   sa.sa_flags = 0;
349   __sigaction(__pthread_sig_cancel, &sa, NULL);
350   if (__pthread_sig_debug > 0) {
351     sa.sa_handler = pthread_handle_sigdebug;
352     sigemptyset(&sa.sa_mask);
353     sa.sa_flags = 0;
354     __sigaction(__pthread_sig_debug, &sa, NULL);
355   }
356   /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */
357   sigemptyset(&mask);
358   sigaddset(&mask, __pthread_sig_restart);
359   sigprocmask(SIG_BLOCK, &mask, NULL);
360   /* Register an exit function to kill all other threads. */
361   /* Do it early so that user-registered atexit functions are called
362      before pthread_exit_process. */
363   __on_exit(pthread_exit_process, NULL);
364 }
365
366 void __pthread_initialize(void)
367 {
368   pthread_initialize();
369 }
370
371 int __pthread_initialize_manager(void)
372 {
373   int manager_pipe[2];
374   int pid;
375   struct pthread_request request;
376
377   /* If basic initialization not done yet (e.g. we're called from a
378      constructor run before our constructor), do it now */
379   if (__pthread_initial_thread_bos == NULL) pthread_initialize();
380   /* Setup stack for thread manager */
381   __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
382   if (__pthread_manager_thread_bos == NULL) return -1;
383   __pthread_manager_thread_tos =
384     __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
385   /* Setup pipe to communicate with thread manager */
386   if (pipe(manager_pipe) == -1) {
387     free(__pthread_manager_thread_bos);
388     return -1;
389   }
390   /* Start the thread manager */
391   pid = 0;
392   if (__pthread_initial_thread.p_report_events)
393     {
394       /* It's a bit more complicated.  We have to report the creation of
395          the manager thread.  */
396       int idx = __td_eventword (TD_CREATE);
397       uint32_t mask = __td_eventmask (TD_CREATE);
398
399       if ((mask & (__pthread_threads_events.event_bits[idx]
400                    | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx]))
401           != 0)
402         {
403           pid = __clone(__pthread_manager_event,
404                         (void **) __pthread_manager_thread_tos,
405                         CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
406                         (void *)(long)manager_pipe[0]);
407
408           if (pid != -1)
409             {
410               /* Now fill in the information about the new thread in
411                  the newly created thread's data structure.  We cannot let
412                  the new thread do this since we don't know whether it was
413                  already scheduled when we send the event.  */
414               __pthread_manager_thread.p_eventbuf.eventdata =
415                 &__pthread_manager_thread;
416               __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE;
417               __pthread_last_event = &__pthread_manager_thread;
418               __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
419               __pthread_manager_thread.p_pid = pid;
420
421               /* Now call the function which signals the event.  */
422               __linuxthreads_create_event ();
423
424               /* Now restart the thread.  */
425               __pthread_unlock(__pthread_manager_thread.p_lock);
426             }
427         }
428     }
429
430   if (pid == 0)
431     pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
432                   CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
433                   (void *)(long)manager_pipe[0]);
434   if (pid == -1) {
435     free(__pthread_manager_thread_bos);
436     __libc_close(manager_pipe[0]);
437     __libc_close(manager_pipe[1]);
438     return -1;
439   }
440   __pthread_manager_request = manager_pipe[1]; /* writing end */
441   __pthread_manager_reader = manager_pipe[0]; /* reading end */
442   __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1;
443   __pthread_manager_thread.p_pid = pid;
444   /* Make gdb aware of new thread manager */
445   if (__pthread_threads_debug && __pthread_sig_debug > 0)
446     {
447       raise(__pthread_sig_debug);
448       /* We suspend ourself and gdb will wake us up when it is
449          ready to handle us. */
450       suspend(thread_self());
451     }
452   /* Synchronize debugging of the thread manager */
453   request.req_kind = REQ_DEBUG;
454   __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
455   return 0;
456 }
457
458 /* Thread creation */
459
460 int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
461                          void * (*start_routine)(void *), void *arg)
462 {
463   pthread_descr self = thread_self();
464   struct pthread_request request;
465   if (__pthread_manager_request < 0) {
466     if (__pthread_initialize_manager() < 0) return EAGAIN;
467   }
468   request.req_thread = self;
469   request.req_kind = REQ_CREATE;
470   request.req_args.create.attr = attr;
471   request.req_args.create.fn = start_routine;
472   request.req_args.create.arg = arg;
473   sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
474               &request.req_args.create.mask);
475   __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
476   suspend(self);
477   if (THREAD_GETMEM(self, p_retcode) == 0)
478     *thread = (pthread_t) THREAD_GETMEM(self, p_retval);
479   return THREAD_GETMEM(self, p_retcode);
480 }
481
482 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
483 default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
484
485 int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
486                          void * (*start_routine)(void *), void *arg)
487 {
488   /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
489      the old size and access to the new members might crash the program.
490      We convert the struct now.  */
491   pthread_attr_t new_attr;
492
493   if (attr != NULL)
494     {
495       size_t ps = __getpagesize ();
496
497       memcpy (&new_attr, attr,
498               (size_t) &(((pthread_attr_t*)NULL)->__guardsize));
499       new_attr.__guardsize = ps;
500       new_attr.__stackaddr_set = 0;
501       new_attr.__stackaddr = NULL;
502       new_attr.__stacksize = STACK_SIZE - ps;
503       attr = &new_attr;
504     }
505   return __pthread_create_2_1 (thread, attr, start_routine, arg);
506 }
507 symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
508 #else
509 strong_alias (__pthread_create_2_1, pthread_create)
510 #endif
511
512 /* Simple operations on thread identifiers */
513
514 pthread_t pthread_self(void)
515 {
516   pthread_descr self = thread_self();
517   return THREAD_GETMEM(self, p_tid);
518 }
519
520 int pthread_equal(pthread_t thread1, pthread_t thread2)
521 {
522   return thread1 == thread2;
523 }
524
525 /* Helper function for thread_self in the case of user-provided stacks */
526
527 #ifndef THREAD_SELF
528
529 pthread_descr __pthread_find_self()
530 {
531   char * sp = CURRENT_STACK_FRAME;
532   pthread_handle h;
533
534   /* __pthread_handles[0] is the initial thread, __pthread_handles[1] is
535      the manager threads handled specially in thread_self(), so start at 2 */
536   h = __pthread_handles + 2;
537   while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) h++;
538   return h->h_descr;
539 }
540
541 #endif
542
543 /* Thread scheduling */
544
545 int pthread_setschedparam(pthread_t thread, int policy,
546                           const struct sched_param *param)
547 {
548   pthread_handle handle = thread_handle(thread);
549   pthread_descr th;
550
551   __pthread_lock(&handle->h_lock, NULL);
552   if (invalid_handle(handle, thread)) {
553     __pthread_unlock(&handle->h_lock);
554     return ESRCH;
555   }
556   th = handle->h_descr;
557   if (__sched_setscheduler(th->p_pid, policy, param) == -1) {
558     __pthread_unlock(&handle->h_lock);
559     return errno;
560   }
561   th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
562   __pthread_unlock(&handle->h_lock);
563   if (__pthread_manager_request >= 0)
564     __pthread_manager_adjust_prio(th->p_priority);
565   return 0;
566 }
567
568 int pthread_getschedparam(pthread_t thread, int *policy,
569                           struct sched_param *param)
570 {
571   pthread_handle handle = thread_handle(thread);
572   int pid, pol;
573
574   __pthread_lock(&handle->h_lock, NULL);
575   if (invalid_handle(handle, thread)) {
576     __pthread_unlock(&handle->h_lock);
577     return ESRCH;
578   }
579   pid = handle->h_descr->p_pid;
580   __pthread_unlock(&handle->h_lock);
581   pol = __sched_getscheduler(pid);
582   if (pol == -1) return errno;
583   if (__sched_getparam(pid, param) == -1) return errno;
584   *policy = pol;
585   return 0;
586 }
587
588 /* Process-wide exit() request */
589
590 static void pthread_exit_process(int retcode, void *arg)
591 {
592   struct pthread_request request;
593   pthread_descr self = thread_self();
594
595   if (__pthread_manager_request >= 0) {
596     request.req_thread = self;
597     request.req_kind = REQ_PROCESS_EXIT;
598     request.req_args.exit.code = retcode;
599     __libc_write(__pthread_manager_request,
600                  (char *) &request, sizeof(request));
601     suspend(self);
602     /* Main thread should accumulate times for thread manager and its
603        children, so that timings for main thread account for all threads. */
604     if (self == __pthread_main_thread)
605       waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
606   }
607 }
608
609 /* The handler for the RESTART signal just records the signal received
610    in the thread descriptor, and optionally performs a siglongjmp
611    (for pthread_cond_timedwait). */
612
613 static void pthread_handle_sigrestart(int sig)
614 {
615   pthread_descr self = thread_self();
616   THREAD_SETMEM(self, p_signal, sig);
617   if (THREAD_GETMEM(self, p_signal_jmp) != NULL)
618     siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1);
619 }
620
621 #ifdef __i386__
622 static void pthread_handle_sigrestart_nonrt(int sig, struct sigcontext ctx)
623 {
624   asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
625   pthread_handle_sigrestart(sig);
626 }
627
628 static void pthread_handle_sigrestart_rt(int sig, struct siginfo *si,
629                                          struct ucontext *uc)
630 {
631   asm volatile ("movw %w0,%%gs" : : "r" (uc->uc_mcontext.gregs[GS]));
632   pthread_handle_sigrestart(sig);
633 }
634 #endif
635
636 /* The handler for the CANCEL signal checks for cancellation
637    (in asynchronous mode), for process-wide exit and exec requests.
638    For the thread manager thread, redirect the signal to
639    __pthread_manager_sighandler. */
640
641 static void pthread_handle_sigcancel(int sig)
642 {
643   pthread_descr self = thread_self();
644   sigjmp_buf * jmpbuf;
645
646   if (self == &__pthread_manager_thread)
647     {
648       __pthread_manager_sighandler(sig);
649       return;
650     }
651   if (__pthread_exit_requested) {
652     /* Main thread should accumulate times for thread manager and its
653        children, so that timings for main thread account for all threads. */
654     if (self == __pthread_main_thread)
655       waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE);
656     _exit(__pthread_exit_code);
657   }
658   if (THREAD_GETMEM(self, p_canceled)
659       && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
660     if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
661       pthread_exit(PTHREAD_CANCELED);
662     jmpbuf = THREAD_GETMEM(self, p_cancel_jmp);
663     if (jmpbuf != NULL) {
664       THREAD_SETMEM(self, p_cancel_jmp, NULL);
665       siglongjmp(*jmpbuf, 1);
666     }
667   }
668 }
669
670 #ifdef __i386__
671 static void pthread_handle_sigcancel_nonrt(int sig, struct sigcontext ctx)
672 {
673   asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
674   pthread_handle_sigcancel(sig);
675 }
676
677 static void pthread_handle_sigcancel_rt(int sig, struct siginfo *si,
678                                          struct ucontext *uc)
679 {
680   asm volatile ("movw %w0,%%gs" : : "r" (uc->uc_mcontext.gregs[GS]));
681   pthread_handle_sigcancel(sig);
682 }
683 #endif
684
685 /* Handler for the DEBUG signal.
686    The debugging strategy is as follows:
687    On reception of a REQ_DEBUG request (sent by new threads created to
688    the thread manager under debugging mode), the thread manager throws
689    __pthread_sig_debug to itself. The debugger (if active) intercepts
690    this signal, takes into account new threads and continue execution
691    of the thread manager by propagating the signal because it doesn't
692    know what it is specifically done for. In the current implementation,
693    the thread manager simply discards it. */
694
695 static void pthread_handle_sigdebug(int sig)
696 {
697   /* Nothing */
698 }
699
700 /* Reset the state of the thread machinery after a fork().
701    Close the pipe used for requests and set the main thread to the forked
702    thread.
703    Notice that we can't free the stack segments, as the forked thread
704    may hold pointers into them. */
705
706 void __pthread_reset_main_thread()
707 {
708   pthread_descr self = thread_self();
709
710   if (__pthread_manager_request != -1) {
711     /* Free the thread manager stack */
712     free(__pthread_manager_thread_bos);
713     __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
714     /* Close the two ends of the pipe */
715     __libc_close(__pthread_manager_request);
716     __libc_close(__pthread_manager_reader);
717     __pthread_manager_request = __pthread_manager_reader = -1;
718   }
719
720   /* Update the pid of the main thread */
721   THREAD_SETMEM(self, p_pid, __getpid());
722   /* Make the forked thread the main thread */
723   __pthread_main_thread = self;
724   THREAD_SETMEM(self, p_nextlive, self);
725   THREAD_SETMEM(self, p_prevlive, self);
726   /* Now this thread modifies the global variables.  */
727   THREAD_SETMEM(self, p_errnop, &_errno);
728   THREAD_SETMEM(self, p_h_errnop, &_h_errno);
729   THREAD_SETMEM(self, p_resp, &_res);
730 }
731
732 /* Process-wide exec() request */
733
734 void __pthread_kill_other_threads_np(void)
735 {
736   struct sigaction sa;
737   /* Terminate all other threads and thread manager */
738   pthread_exit_process(0, NULL);
739   /* Make current thread the main thread in case the calling thread
740      changes its mind, does not exec(), and creates new threads instead. */
741   __pthread_reset_main_thread();
742
743   /* Reset the signal handlers behaviour for the signals the
744      implementation uses since this would be passed to the new
745      process.  */
746   sigemptyset(&sa.sa_mask);
747   sa.sa_flags = 0;
748   sa.sa_handler = SIG_DFL;
749   __sigaction(__pthread_sig_restart, &sa, NULL);
750   __sigaction(__pthread_sig_cancel, &sa, NULL);
751   if (__pthread_sig_debug > 0)
752     __sigaction(__pthread_sig_debug, &sa, NULL);
753 }
754 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
755
756 /* Concurrency symbol level.  */
757 static int current_level;
758
759 int __pthread_setconcurrency(int level)
760 {
761   /* We don't do anything unless we have found a useful interpretation.  */
762   current_level = level;
763   return 0;
764 }
765 weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
766
767 int __pthread_getconcurrency(void)
768 {
769   return current_level;
770 }
771 weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
772
773 /* Debugging aid */
774
775 #ifdef DEBUG
776 #include <stdarg.h>
777
778 void __pthread_message(char * fmt, ...)
779 {
780   char buffer[1024];
781   va_list args;
782   sprintf(buffer, "%05d : ", __getpid());
783   va_start(args, fmt);
784   vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
785   va_end(args);
786   __libc_write(2, buffer, strlen(buffer));
787 }
788
789 #endif
790
791
792 #ifndef PIC
793 /* We need a hook to force the cancelation wrappers to be linked in when
794    static libpthread is used.  */
795 extern const int __pthread_provide_wrappers;
796 static const int *const __pthread_require_wrappers =
797   &__pthread_provide_wrappers;
798 #endif