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