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