307ce637219705f7104fe9c06db99b53e8fdceed
[kopensolaris-gnu/glibc.git] / linuxthreads / manager.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 /* The "thread manager" thread: manages creation and termination of threads */
16
17 #include <errno.h>
18 #include <sched.h>
19 #include <stddef.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/poll.h>           /* for poll */
25 #include <sys/mman.h>           /* for mmap */
26 #include <sys/param.h>
27 #include <sys/time.h>
28 #include <sys/wait.h>           /* for waitpid macros */
29
30 #include "pthread.h"
31 #include "internals.h"
32 #include "spinlock.h"
33 #include "restart.h"
34 #include "semaphore.h"
35
36 /* Array of active threads. Entry 0 is reserved for the initial thread. */
37 struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] =
38 { { LOCK_INITIALIZER, &__pthread_initial_thread, 0},
39   { LOCK_INITIALIZER, &__pthread_manager_thread, 0}, /* All NULLs */ };
40
41 /* For debugging purposes put the maximum number of threads in a variable.  */
42 const int __linuxthreads_pthread_threads_max = PTHREAD_THREADS_MAX;
43
44 /* Indicate whether at least one thread has a user-defined stack (if 1),
45    or if all threads have stacks supplied by LinuxThreads (if 0). */
46 int __pthread_nonstandard_stacks;
47
48 /* Number of active entries in __pthread_handles (used by gdb) */
49 volatile int __pthread_handles_num = 2;
50
51 /* Whether to use debugger additional actions for thread creation
52    (set to 1 by gdb) */
53 volatile int __pthread_threads_debug;
54
55 /* Globally enabled events.  */
56 volatile td_thr_events_t __pthread_threads_events;
57
58 /* Pointer to thread descriptor with last event.  */
59 volatile pthread_descr __pthread_last_event;
60
61 /* Mapping from stack segment to thread descriptor. */
62 /* Stack segment numbers are also indices into the __pthread_handles array. */
63 /* Stack segment number 0 is reserved for the initial thread. */
64
65 static inline pthread_descr thread_segment(int seg)
66 {
67   return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
68          - 1;
69 }
70
71 /* Flag set in signal handler to record child termination */
72
73 static volatile int terminated_children = 0;
74
75 /* Flag set when the initial thread is blocked on pthread_exit waiting
76    for all other threads to terminate */
77
78 static int main_thread_exiting = 0;
79
80 /* Counter used to generate unique thread identifier.
81    Thread identifier is pthread_threads_counter + segment. */
82
83 static pthread_t pthread_threads_counter = 0;
84
85 /* Forward declarations */
86
87 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
88                                  void * (*start_routine)(void *), void *arg,
89                                  sigset_t *mask, int father_pid,
90                                  int report_events,
91                                  td_thr_events_t *event_maskp);
92 static void pthread_handle_free(pthread_t th_id);
93 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode);
94 static void pthread_reap_children(void);
95 static void pthread_kill_all_threads(int sig, int main_thread_also);
96
97 /* The server thread managing requests for thread creation and termination */
98
99 int __pthread_manager(void *arg)
100 {
101   int reqfd = (int)arg;
102   struct pollfd ufd;
103   sigset_t mask;
104   int n;
105   struct pthread_request request;
106
107   /* If we have special thread_self processing, initialize it.  */
108 #ifdef INIT_THREAD_SELF
109   INIT_THREAD_SELF(&__pthread_manager_thread, 1);
110 #endif
111   /* Set the error variable.  */
112   __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
113   __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;
114   /* Block all signals except __pthread_sig_cancel and SIGTRAP */
115   sigfillset(&mask);
116   sigdelset(&mask, __pthread_sig_cancel); /* for thread termination */
117   sigdelset(&mask, SIGTRAP);            /* for debugging purposes */
118   sigprocmask(SIG_SETMASK, &mask, NULL);
119   /* Raise our priority to match that of main thread */
120   __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
121   /* Synchronize debugging of the thread manager */
122   n = __libc_read(reqfd, (char *)&request, sizeof(request));
123   ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
124   ufd.fd = reqfd;
125   ufd.events = POLLIN;
126   /* Enter server loop */
127   while(1) {
128     n = __poll(&ufd, 1, 2000);
129
130     /* Check for termination of the main thread */
131     if (getppid() == 1) {
132       pthread_kill_all_threads(SIGKILL, 0);
133       _exit(0);
134     }
135     /* Check for dead children */
136     if (terminated_children) {
137       terminated_children = 0;
138       pthread_reap_children();
139     }
140     /* Read and execute request */
141     if (n == 1 && (ufd.revents & POLLIN)) {
142       n = __libc_read(reqfd, (char *)&request, sizeof(request));
143       ASSERT(n == sizeof(request));
144       switch(request.req_kind) {
145       case REQ_CREATE:
146         request.req_thread->p_retcode =
147           pthread_handle_create((pthread_t *) &request.req_thread->p_retval,
148                                 request.req_args.create.attr,
149                                 request.req_args.create.fn,
150                                 request.req_args.create.arg,
151                                 &request.req_args.create.mask,
152                                 request.req_thread->p_pid,
153                                 request.req_thread->p_report_events,
154                                 &request.req_thread->p_eventbuf.eventmask);
155         restart(request.req_thread);
156         break;
157       case REQ_FREE:
158         pthread_handle_free(request.req_args.free.thread_id);
159         break;
160       case REQ_PROCESS_EXIT:
161         pthread_handle_exit(request.req_thread,
162                             request.req_args.exit.code);
163         break;
164       case REQ_MAIN_THREAD_EXIT:
165         main_thread_exiting = 1;
166         if (__pthread_main_thread->p_nextlive == __pthread_main_thread) {
167           restart(__pthread_main_thread);
168           return 0;
169         }
170         break;
171       case REQ_POST:
172         __new_sem_post(request.req_args.post);
173         break;
174       case REQ_DEBUG:
175         /* Make gdb aware of new thread and gdb will restart the
176            new thread when it is ready to handle the new thread. */
177         if (__pthread_threads_debug && __pthread_sig_debug > 0)
178           raise(__pthread_sig_debug);
179         break;
180       }
181     }
182   }
183 }
184
185 int __pthread_manager_event(void *arg)
186 {
187   /* If we have special thread_self processing, initialize it.  */
188 #ifdef INIT_THREAD_SELF
189   INIT_THREAD_SELF(&__pthread_manager_thread, 1);
190 #endif
191
192   /* Get the lock the manager will free once all is correctly set up.  */
193   __pthread_lock (THREAD_GETMEM((&__pthread_manager_thread), p_lock), NULL);
194   /* Free it immediately.  */
195   __pthread_unlock (THREAD_GETMEM((&__pthread_manager_thread), p_lock));
196
197   return __pthread_manager(arg);
198 }
199
200 /* Process creation */
201
202 static int pthread_start_thread(void *arg)
203 {
204   pthread_descr self = (pthread_descr) arg;
205   struct pthread_request request;
206   void * outcome;
207   /* Initialize special thread_self processing, if any.  */
208 #ifdef INIT_THREAD_SELF
209   INIT_THREAD_SELF(self, self->p_nr);
210 #endif
211   /* Make sure our pid field is initialized, just in case we get there
212      before our father has initialized it. */
213   THREAD_SETMEM(self, p_pid, __getpid());
214   /* Initial signal mask is that of the creating thread. (Otherwise,
215      we'd just inherit the mask of the thread manager.) */
216   sigprocmask(SIG_SETMASK, &self->p_start_args.mask, NULL);
217   /* Set the scheduling policy and priority for the new thread, if needed */
218   if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
219     /* Explicit scheduling attributes were provided: apply them */
220     __sched_setscheduler(THREAD_GETMEM(self, p_pid),
221                          THREAD_GETMEM(self, p_start_args.schedpolicy),
222                          &self->p_start_args.schedparam);
223   else if (__pthread_manager_thread.p_priority > 0)
224     /* Default scheduling required, but thread manager runs in realtime
225        scheduling: switch new thread to SCHED_OTHER policy */
226     {
227       struct sched_param default_params;
228       default_params.sched_priority = 0;
229       __sched_setscheduler(THREAD_GETMEM(self, p_pid),
230                            SCHED_OTHER, &default_params);
231     }
232   /* Make gdb aware of new thread */
233   if (__pthread_threads_debug && __pthread_sig_debug > 0) {
234     request.req_thread = self;
235     request.req_kind = REQ_DEBUG;
236     __libc_write(__pthread_manager_request,
237                  (char *) &request, sizeof(request));
238     suspend(self);
239   }
240   /* Run the thread code */
241   outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
242                                                            p_start_args.arg));
243   /* Exit with the given return value */
244   pthread_exit(outcome);
245   return 0;
246 }
247
248 static int pthread_start_thread_event(void *arg)
249 {
250   pthread_descr self = (pthread_descr) arg;
251
252 #ifdef INIT_THREAD_SELF
253   INIT_THREAD_SELF(self, self->p_nr);
254 #endif
255   /* Make sure our pid field is initialized, just in case we get there
256      before our father has initialized it. */
257   THREAD_SETMEM(self, p_pid, __getpid());
258   /* Get the lock the manager will free once all is correctly set up.  */
259   __pthread_lock (THREAD_GETMEM(self, p_lock), NULL);
260   /* Free it immediately.  */
261   __pthread_unlock (THREAD_GETMEM(self, p_lock));
262
263   /* Continue with the real function.  */
264   return pthread_start_thread (arg);
265 }
266
267 static int pthread_allocate_stack(const pthread_attr_t *attr,
268                                   pthread_descr default_new_thread,
269                                   int pagesize,
270                                   pthread_descr * out_new_thread,
271                                   char ** out_new_thread_bottom,
272                                   char ** out_guardaddr,
273                                   size_t * out_guardsize)
274 {
275   pthread_descr new_thread;
276   char * new_thread_bottom;
277   char * guardaddr;
278   size_t stacksize, guardsize;
279
280   if (attr != NULL && attr->__stackaddr_set)
281     {
282       /* The user provided a stack. */
283       new_thread =
284         (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
285       new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
286       guardaddr = NULL;
287       guardsize = 0;
288       __pthread_nonstandard_stacks = 1;
289     }
290   else
291     {
292       /* Allocate space for stack and thread descriptor at default address */
293       new_thread = default_new_thread;
294       new_thread_bottom = (char *) new_thread - STACK_SIZE;
295       if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
296                INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
297                MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
298                -1, 0) == MAP_FAILED)
299         /* Bad luck, this segment is already mapped. */
300         return -1;
301       /* We manage to get a stack.  Now see whether we need a guard
302          and allocate it if necessary.  Notice that the default
303          attributes (stack_size = STACK_SIZE - pagesize and
304          guardsize = pagesize) do not need a guard page, since
305          the RLIMIT_STACK soft limit prevents stacks from
306          running into one another. */
307       if (attr == NULL ||
308           attr->__guardsize == 0 ||
309           (attr->__guardsize == pagesize &&
310            attr->__stacksize == STACK_SIZE - pagesize))
311         {
312           /* We don't need a guard page. */
313           guardaddr = NULL;
314           guardsize = 0;
315         }
316       else
317         {
318           /* Put a bad page at the bottom of the stack */
319           stacksize = roundup(attr->__stacksize, pagesize);
320           if (stacksize >= STACK_SIZE - pagesize)
321             stacksize = STACK_SIZE - pagesize;
322           guardaddr = (void *)new_thread - stacksize;
323           guardsize = attr->__guardsize;
324           if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
325               == MAP_FAILED)
326             {
327               /* We don't make this an error.  */
328               guardaddr = NULL;
329               guardsize = 0;
330             }
331         }
332     }
333   /* Clear the thread data structure.  */
334   memset (new_thread, '\0', sizeof (*new_thread));
335   *out_new_thread = new_thread;
336   *out_new_thread_bottom = new_thread_bottom;
337   *out_guardaddr = guardaddr;
338   *out_guardsize = guardsize;
339   return 0;
340 }
341
342 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
343                                  void * (*start_routine)(void *), void *arg,
344                                  sigset_t * mask, int father_pid,
345                                  int report_events,
346                                  td_thr_events_t *event_maskp)
347 {
348   size_t sseg;
349   int pid;
350   pthread_descr new_thread;
351   char * new_thread_bottom;
352   pthread_t new_thread_id;
353   char *guardaddr = NULL;
354   size_t guardsize = 0;
355   int pagesize = __getpagesize();
356
357   /* First check whether we have to change the policy and if yes, whether
358      we can  do this.  Normally this should be done by examining the
359      return value of the __sched_setscheduler call in pthread_start_thread
360      but this is hard to implement.  FIXME  */
361   if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
362     return EPERM;
363   /* Find a free segment for the thread, and allocate a stack if needed */
364   for (sseg = 2; ; sseg++)
365     {
366       if (sseg >= PTHREAD_THREADS_MAX)
367         return EAGAIN;
368       if (__pthread_handles[sseg].h_descr != NULL)
369         continue;
370       if (pthread_allocate_stack(attr, thread_segment(sseg), pagesize,
371                                  &new_thread, &new_thread_bottom,
372                                  &guardaddr, &guardsize) == 0)
373         break;
374     }
375   __pthread_handles_num++;
376   /* Allocate new thread identifier */
377   pthread_threads_counter += PTHREAD_THREADS_MAX;
378   new_thread_id = sseg + pthread_threads_counter;
379   /* Initialize the thread descriptor.  Elements which have to be
380      initialized to zero already have this value.  */
381   new_thread->p_tid = new_thread_id;
382   new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
383   new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
384   new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
385   new_thread->p_errnop = &new_thread->p_errno;
386   new_thread->p_h_errnop = &new_thread->p_h_errno;
387   new_thread->p_resp = &new_thread->p_res;
388   new_thread->p_guardaddr = guardaddr;
389   new_thread->p_guardsize = guardsize;
390   new_thread->p_self = new_thread;
391   new_thread->p_nr = sseg;
392   /* Initialize the thread handle */
393   __pthread_init_lock(&__pthread_handles[sseg].h_lock);
394   __pthread_handles[sseg].h_descr = new_thread;
395   __pthread_handles[sseg].h_bottom = new_thread_bottom;
396   /* Determine scheduling parameters for the thread */
397   new_thread->p_start_args.schedpolicy = -1;
398   if (attr != NULL) {
399     new_thread->p_detached = attr->__detachstate;
400     new_thread->p_userstack = attr->__stackaddr_set;
401
402     switch(attr->__inheritsched) {
403     case PTHREAD_EXPLICIT_SCHED:
404       new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
405       memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam,
406               sizeof (struct sched_param));
407       break;
408     case PTHREAD_INHERIT_SCHED:
409       new_thread->p_start_args.schedpolicy = __sched_getscheduler(father_pid);
410       __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
411       break;
412     }
413     new_thread->p_priority =
414       new_thread->p_start_args.schedparam.sched_priority;
415   }
416   /* Finish setting up arguments to pthread_start_thread */
417   new_thread->p_start_args.start_routine = start_routine;
418   new_thread->p_start_args.arg = arg;
419   new_thread->p_start_args.mask = *mask;
420   /* Raise priority of thread manager if needed */
421   __pthread_manager_adjust_prio(new_thread->p_priority);
422   /* Do the cloning.  We have to use two different functions depending
423      on whether we are debugging or not.  */
424   pid = 0;      /* Note that the thread never can have PID zero.  */
425   if (report_events)
426     {
427       /* See whether the TD_CREATE event bit is set in any of the
428          masks.  */
429       int idx = __td_eventword (TD_CREATE);
430       uint32_t mask = __td_eventmask (TD_CREATE);
431
432       if ((mask & (__pthread_threads_events.event_bits[idx]
433                    | event_maskp->event_bits[idx])) != 0)
434         {
435           /* Lock the mutex the child will use now so that it will stop.  */
436           __pthread_lock(new_thread->p_lock, NULL);
437
438           /* We have to report this event.  */
439           pid = __clone(pthread_start_thread_event, (void **) new_thread,
440                         CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
441                         __pthread_sig_cancel, new_thread);
442           if (pid != -1)
443             {
444               /* Now fill in the information about the new thread in
445                  the newly created thread's data structure.  We cannot let
446                  the new thread do this since we don't know whether it was
447                  already scheduled when we send the event.  */
448               new_thread->p_eventbuf.eventdata = new_thread;
449               new_thread->p_eventbuf.eventnum = TD_CREATE;
450               __pthread_last_event = new_thread;
451
452               /* Now call the function which signals the event.  */
453               __linuxthreads_create_event ();
454
455               /* Now restart the thread.  */
456               __pthread_unlock(new_thread->p_lock);
457             }
458         }
459     }
460   if (pid == 0)
461     pid = __clone(pthread_start_thread, (void **) new_thread,
462                   CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
463                   __pthread_sig_cancel, new_thread);
464   /* Check if cloning succeeded */
465   if (pid == -1) {
466     /* Free the stack if we allocated it */
467     if (attr == NULL || !attr->__stackaddr_set)
468       {
469         if (new_thread->p_guardsize != 0)
470           munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
471         munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
472                INITIAL_STACK_SIZE);
473       }
474     __pthread_handles[sseg].h_descr = NULL;
475     __pthread_handles[sseg].h_bottom = NULL;
476     __pthread_handles_num--;
477     return errno;
478   }
479   /* Insert new thread in doubly linked list of active threads */
480   new_thread->p_prevlive = __pthread_main_thread;
481   new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
482   __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
483   __pthread_main_thread->p_nextlive = new_thread;
484   /* Set pid field of the new thread, in case we get there before the
485      child starts. */
486   new_thread->p_pid = pid;
487   /* We're all set */
488   *thread = new_thread_id;
489   return 0;
490 }
491
492
493 /* Try to free the resources of a thread when requested by pthread_join
494    or pthread_detach on a terminated thread. */
495
496 static void pthread_free(pthread_descr th)
497 {
498   pthread_handle handle;
499   ASSERT(th->p_exited);
500   /* Make the handle invalid */
501   handle =  thread_handle(th->p_tid);
502   __pthread_lock(&handle->h_lock, NULL);
503   handle->h_descr = NULL;
504   handle->h_bottom = (char *)(-1L);
505   __pthread_unlock(&handle->h_lock);
506 #ifdef FREE_THREAD_SELF
507   FREE_THREAD_SELF(th, th->p_nr);
508 #endif
509   /* One fewer threads in __pthread_handles */
510   __pthread_handles_num--;
511   /* If initial thread, nothing to free */
512   if (th == &__pthread_initial_thread) return;
513   if (!th->p_userstack)
514     {
515       /* Free the stack and thread descriptor area */
516       if (th->p_guardsize != 0)
517         munmap(th->p_guardaddr, th->p_guardsize);
518       munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
519     }
520 }
521
522 /* Handle threads that have exited */
523
524 static void pthread_exited(pid_t pid)
525 {
526   pthread_descr th;
527   int detached;
528   /* Find thread with that pid */
529   for (th = __pthread_main_thread->p_nextlive;
530        th != __pthread_main_thread;
531        th = th->p_nextlive) {
532     if (th->p_pid == pid) {
533       /* Remove thread from list of active threads */
534       th->p_nextlive->p_prevlive = th->p_prevlive;
535       th->p_prevlive->p_nextlive = th->p_nextlive;
536       /* Mark thread as exited, and if detached, free its resources */
537       __pthread_lock(th->p_lock, NULL);
538       th->p_exited = 1;
539       /* If we have to signal this event do it now.  */
540       if (th->p_report_events)
541         {
542           /* See whether TD_DEATH is in any of the mask.  */
543           int idx = __td_eventword (TD_REAP);
544           uint32_t mask = __td_eventmask (TD_REAP);
545
546           if ((mask & (__pthread_threads_events.event_bits[idx]
547                        | th->p_eventbuf.eventmask.event_bits[idx])) != 0)
548             {
549               /* Yep, we have to signal the death.  */
550               th->p_eventbuf.eventnum = TD_DEATH;
551               th->p_eventbuf.eventdata = th;
552               __pthread_last_event = th;
553
554               /* Now call the function to signal the event.  */
555               __linuxthreads_reap_event();
556             }
557         }
558       detached = th->p_detached;
559       __pthread_unlock(th->p_lock);
560       if (detached)
561         pthread_free(th);
562       break;
563     }
564   }
565   /* If all threads have exited and the main thread is pending on a
566      pthread_exit, wake up the main thread and terminate ourselves. */
567   if (main_thread_exiting &&
568       __pthread_main_thread->p_nextlive == __pthread_main_thread) {
569     restart(__pthread_main_thread);
570     _exit(0);
571   }
572 }
573
574 static void pthread_reap_children(void)
575 {
576   pid_t pid;
577   int status;
578
579   while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
580     pthread_exited(pid);
581     if (WIFSIGNALED(status)) {
582       /* If a thread died due to a signal, send the same signal to
583          all other threads, including the main thread. */
584       pthread_kill_all_threads(WTERMSIG(status), 1);
585       _exit(0);
586     }
587   }
588 }
589
590 /* Try to free the resources of a thread when requested by pthread_join
591    or pthread_detach on a terminated thread. */
592
593 static void pthread_handle_free(pthread_t th_id)
594 {
595   pthread_handle handle = thread_handle(th_id);
596   pthread_descr th;
597
598   __pthread_lock(&handle->h_lock, NULL);
599   if (invalid_handle(handle, th_id)) {
600     /* pthread_reap_children has deallocated the thread already,
601        nothing needs to be done */
602     __pthread_unlock(&handle->h_lock);
603     return;
604   }
605   th = handle->h_descr;
606   if (th->p_exited) {
607     __pthread_unlock(&handle->h_lock);
608     pthread_free(th);
609   } else {
610     /* The Unix process of the thread is still running.
611        Mark the thread as detached so that the thread manager will
612        deallocate its resources when the Unix process exits. */
613     th->p_detached = 1;
614     __pthread_unlock(&handle->h_lock);
615   }
616 }
617
618 /* Send a signal to all running threads */
619
620 static void pthread_kill_all_threads(int sig, int main_thread_also)
621 {
622   pthread_descr th;
623   for (th = __pthread_main_thread->p_nextlive;
624        th != __pthread_main_thread;
625        th = th->p_nextlive) {
626     kill(th->p_pid, sig);
627   }
628   if (main_thread_also) {
629     kill(__pthread_main_thread->p_pid, sig);
630   }
631 }
632
633 /* Process-wide exit() */
634
635 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
636 {
637   pthread_descr th;
638   __pthread_exit_requested = 1;
639   __pthread_exit_code = exitcode;
640   /* Send the CANCEL signal to all running threads, including the main
641      thread, but excluding the thread from which the exit request originated
642      (that thread must complete the exit, e.g. calling atexit functions
643      and flushing stdio buffers). */
644   for (th = issuing_thread->p_nextlive;
645        th != issuing_thread;
646        th = th->p_nextlive) {
647     kill(th->p_pid, __pthread_sig_cancel);
648   }
649   /* Now, wait for all these threads, so that they don't become zombies
650      and their times are properly added to the thread manager's times. */
651   for (th = issuing_thread->p_nextlive;
652        th != issuing_thread;
653        th = th->p_nextlive) {
654     waitpid(th->p_pid, NULL, __WCLONE);
655   }
656   restart(issuing_thread);
657   _exit(0);
658 }
659
660 /* Handler for __pthread_sig_cancel in thread manager thread */
661
662 void __pthread_manager_sighandler(int sig)
663 {
664   terminated_children = 1;
665 }
666
667 /* Adjust priority of thread manager so that it always run at a priority
668    higher than all threads */
669
670 void __pthread_manager_adjust_prio(int thread_prio)
671 {
672   struct sched_param param;
673
674   if (thread_prio <= __pthread_manager_thread.p_priority) return;
675   param.sched_priority =
676     thread_prio < __sched_get_priority_max(SCHED_FIFO)
677     ? thread_prio + 1 : thread_prio;
678   __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
679   __pthread_manager_thread.p_priority = thread_prio;
680 }