OSDN Git Service

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