d14a57ccd7b5821b619b6a6721c7c7b4df9cf980
[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/time.h>
27 #include <sys/wait.h>           /* for waitpid macros */
28 #include <linux/tasks.h>
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}, /* All NULLs */ };
39
40 /* Indicate whether at least one thread has a user-defined stack (if 1),
41    or if all threads have stacks supplied by LinuxThreads (if 0). */
42 int __pthread_nonstandard_stacks = 0;
43
44 /* Number of active entries in __pthread_handles (used by gdb) */
45 volatile int __pthread_handles_num = 1;
46
47 /* Whether to use debugger additional actions for thread creation
48    (set to 1 by gdb) */
49 volatile int __pthread_threads_debug = 0;
50
51 /* Mapping from stack segment to thread descriptor. */
52 /* Stack segment numbers are also indices into the __pthread_handles array. */
53 /* Stack segment number 0 is reserved for the initial thread. */
54
55 static inline pthread_descr thread_segment(int seg)
56 {
57   return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
58          - 1;
59 }
60
61 /* Flag set in signal handler to record child termination */
62
63 static volatile int terminated_children = 0;
64
65 /* Flag set when the initial thread is blocked on pthread_exit waiting
66    for all other threads to terminate */
67
68 static int main_thread_exiting = 0;
69
70 /* Counter used to generate unique thread identifier.
71    Thread identifier is pthread_threads_counter + segment. */
72
73 static pthread_t pthread_threads_counter = 0;
74
75 /* Forward declarations */
76
77 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
78                                  void * (*start_routine)(void *), void *arg,
79                                  sigset_t *mask, int father_pid);
80 static void pthread_handle_free(pthread_t th_id);
81 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode);
82 static void pthread_reap_children(void);
83 static void pthread_kill_all_threads(int sig, int main_thread_also);
84
85 /* The server thread managing requests for thread creation and termination */
86
87 int __pthread_manager(void *arg)
88 {
89   int reqfd = (int)arg;
90   struct pollfd ufd;
91   sigset_t mask;
92   int n;
93   struct pthread_request request;
94
95   /* If we have special thread_self processing, initialize it.  */
96 #ifdef INIT_THREAD_SELF
97   INIT_THREAD_SELF(&__pthread_manager_thread);
98 #endif
99   /* Set the error variable.  */
100   __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
101   __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;
102   /* Block all signals except PTHREAD_SIG_RESTART, PTHREAD_SIG_CANCEL
103      and SIGTRAP */
104   sigfillset(&mask);
105   sigdelset(&mask, PTHREAD_SIG_RESTART);
106   sigdelset(&mask, PTHREAD_SIG_CANCEL); /* for debugging new threads */
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);
182 #endif
183   /* Make sure our pid field is initialized, just in case we get there
184      before our father has initialized it. */
185   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 (self->p_start_args.schedpolicy >= 0)
191     __sched_setscheduler(self->p_pid, self->p_start_args.schedpolicy,
192                          &self->p_start_args.schedparam);
193   /* Make gdb aware of new thread */
194   if (__pthread_threads_debug) {
195     request.req_thread = self;
196     request.req_kind = REQ_DEBUG;
197     __libc_write(__pthread_manager_request,
198                  (char *) &request, sizeof(request));
199     suspend(self);
200   }
201   /* Run the thread code */
202   outcome = self->p_start_args.start_routine(self->p_start_args.arg);
203   /* Exit with the given return value */
204   pthread_exit(outcome);
205   return 0;
206 }
207
208 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
209                                  void * (*start_routine)(void *), void *arg,
210                                  sigset_t * mask, int father_pid)
211 {
212   size_t sseg;
213   int pid;
214   pthread_descr new_thread;
215   char * new_thread_bottom;
216   pthread_t new_thread_id;
217   void *guardaddr = NULL;
218   size_t guardsize = 0;
219
220   /* First check whether we have to change the policy and if yes, whether
221      we can  do this.  Normally this should be done by examining the
222      return value of the __sched_setscheduler call in pthread_start_thread
223      but this is hard to implement.  FIXME  */
224   if (attr != NULL && attr->schedpolicy != SCHED_OTHER && geteuid () != 0)
225     return EPERM;
226   /* Find a free stack segment for the current stack */
227   for (sseg = 1; ; sseg++)
228     {
229       if (sseg >= PTHREAD_THREADS_MAX)
230         return EAGAIN;
231       if (__pthread_handles[sseg].h_descr != NULL)
232         continue;
233
234       if (attr == NULL || !attr->stackaddr_set)
235         {
236           new_thread = thread_segment(sseg);
237           new_thread_bottom = (char *) new_thread - STACK_SIZE;
238           /* Allocate space for stack and thread descriptor. */
239           if (mmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
240                    INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
241                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
242                    -1, 0) != MAP_FAILED)
243             {
244               /* We manage to get a stack.  Now see whether we need a guard
245                  and allocate it if necessary.  */
246               if (attr == NULL || attr->guardsize != 0)
247                 {
248                   guardsize = attr ? attr->guardsize : __getpagesize ();
249                   guardaddr = mmap ((caddr_t)((char *)(new_thread+1)
250                                               - STACK_SIZE),
251                                     guardsize, 0, MAP_FIXED, -1, 0);
252                   if (guardaddr == MAP_FAILED)
253                     {
254                       /* We don't make this an error.  */
255                       guardaddr = NULL;
256                       guardsize = 0;
257                     }
258                 }
259               break;
260             }
261           /* It seems part of this segment is already mapped. Try the next. */
262         }
263       else
264         {
265           new_thread = (pthread_descr) ((long) attr->stackaddr
266                                         & -sizeof(void *)) - 1;
267           new_thread_bottom = (char *) attr->stackaddr - attr->stacksize;
268           break;
269         }
270     }
271   /* Allocate new thread identifier */
272   pthread_threads_counter += PTHREAD_THREADS_MAX;
273   new_thread_id = sseg + pthread_threads_counter;
274   /* Initialize the thread descriptor */
275   new_thread->p_nextwaiting = NULL;
276   new_thread->p_tid = new_thread_id;
277   new_thread->p_priority = 0;
278   new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
279   new_thread->p_signal = 0;
280   new_thread->p_signal_jmp = NULL;
281   new_thread->p_cancel_jmp = NULL;
282   new_thread->p_terminated = 0;
283   new_thread->p_detached = attr == NULL ? 0 : attr->detachstate;
284   new_thread->p_exited = 0;
285   new_thread->p_retval = NULL;
286   new_thread->p_joining = NULL;
287   new_thread->p_cleanup = NULL;
288   new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
289   new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
290   new_thread->p_canceled = 0;
291   new_thread->p_errnop = &new_thread->p_errno;
292   new_thread->p_errno = 0;
293   new_thread->p_h_errnop = &new_thread->p_h_errno;
294   new_thread->p_h_errno = 0;
295   new_thread->p_in_sighandler = NULL;
296   new_thread->p_sigwaiting = 0;
297   new_thread->p_guardaddr = guardaddr;
298   new_thread->p_guardsize = guardsize;
299   new_thread->p_userstack = attr != NULL && attr->stackaddr_set;
300   memset (new_thread->p_specific, '\0',
301           PTHREAD_KEY_1STLEVEL_SIZE * sizeof (new_thread->p_specific[0]));
302   /* Initialize the thread handle */
303   __pthread_init_lock(&__pthread_handles[sseg].h_lock);
304   __pthread_handles[sseg].h_descr = new_thread;
305   __pthread_handles[sseg].h_bottom = new_thread_bottom;
306   /* Determine scheduling parameters for the thread */
307   new_thread->p_start_args.schedpolicy = -1;
308   if (attr != NULL) {
309     switch(attr->inheritsched) {
310     case PTHREAD_EXPLICIT_SCHED:
311       new_thread->p_start_args.schedpolicy = attr->schedpolicy;
312       memcpy (&new_thread->p_start_args.schedparam, &attr->schedparam,
313               sizeof (struct sched_param));
314       break;
315     case PTHREAD_INHERIT_SCHED:
316       /* schedpolicy doesn't need to be set, only get priority */
317       __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
318       break;
319     }
320     new_thread->p_priority =
321       new_thread->p_start_args.schedparam.sched_priority;
322   }
323   /* Finish setting up arguments to pthread_start_thread */
324   new_thread->p_start_args.start_routine = start_routine;
325   new_thread->p_start_args.arg = arg;
326   new_thread->p_start_args.mask = *mask;
327   /* Raise priority of thread manager if needed */
328   __pthread_manager_adjust_prio(new_thread->p_priority);
329   /* Do the cloning */
330   pid = __clone(pthread_start_thread, (void **) new_thread,
331                 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
332                 PTHREAD_SIG_RESTART,
333                 new_thread);
334   /* Check if cloning succeeded */
335   if (pid == -1) {
336     /* Free the stack if we allocated it */
337     if (attr == NULL || !attr->stackaddr_set)
338       {
339         munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
340                INITIAL_STACK_SIZE);
341         if (new_thread->p_guardsize != 0)
342           munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
343       }
344     __pthread_handles[sseg].h_descr = NULL;
345     __pthread_handles[sseg].h_bottom = NULL;
346     __pthread_handles_num--;
347     return errno;
348   }
349   /* Insert new thread in doubly linked list of active threads */
350   new_thread->p_prevlive = __pthread_main_thread;
351   new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
352   __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
353   __pthread_main_thread->p_nextlive = new_thread;
354   /* Set pid field of the new thread, in case we get there before the
355      child starts. */
356   new_thread->p_pid = pid;
357   /* We're all set */
358   *thread = new_thread_id;
359   return 0;
360 }
361
362
363 /* Try to free the resources of a thread when requested by pthread_join
364    or pthread_detach on a terminated thread. */
365
366 static void pthread_free(pthread_descr th)
367 {
368   pthread_handle handle;
369   ASSERT(th->p_exited);
370   /* Make the handle invalid */
371   handle =  thread_handle(th->p_tid);
372   __pthread_lock(&handle->h_lock);
373   handle->h_descr = NULL;
374   handle->h_bottom = (char *)(-1L);
375   __pthread_unlock(&handle->h_lock);
376   /* One fewer threads in __pthread_handles */
377   __pthread_handles_num--;
378   /* If initial thread, nothing to free */
379   if (th == &__pthread_initial_thread) return;
380   if (!th->p_userstack)
381     {
382       /* Free the stack and thread descriptor area */
383       if (th->p_guardsize != 0)
384         munmap(th->p_guardaddr, th->p_guardsize);
385       munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
386     }
387 }
388
389 /* Handle threads that have exited */
390
391 static void pthread_exited(pid_t pid)
392 {
393   pthread_descr th;
394   int detached;
395   /* Find thread with that pid */
396   for (th = __pthread_main_thread->p_nextlive;
397        th != __pthread_main_thread;
398        th = th->p_nextlive) {
399     if (th->p_pid == pid) {
400       /* Remove thread from list of active threads */
401       th->p_nextlive->p_prevlive = th->p_prevlive;
402       th->p_prevlive->p_nextlive = th->p_nextlive;
403       /* Mark thread as exited, and if detached, free its resources */
404       __pthread_lock(th->p_lock);
405       th->p_exited = 1;
406       detached = th->p_detached;
407       __pthread_unlock(th->p_lock);
408       if (detached)
409         pthread_free(th);
410       break;
411     }
412   }
413   /* If all threads have exited and the main thread is pending on a
414      pthread_exit, wake up the main thread and terminate ourselves. */
415   if (main_thread_exiting &&
416       __pthread_main_thread->p_nextlive == __pthread_main_thread) {
417     restart(__pthread_main_thread);
418     _exit(0);
419   }
420 }
421
422 static void pthread_reap_children(void)
423 {
424   pid_t pid;
425   int status;
426
427   while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
428     pthread_exited(pid);
429     if (WIFSIGNALED(status)) {
430       /* If a thread died due to a signal, send the same signal to
431          all other threads, including the main thread. */
432       pthread_kill_all_threads(WTERMSIG(status), 1);
433       _exit(0);
434     }
435   }
436 }
437
438 /* Try to free the resources of a thread when requested by pthread_join
439    or pthread_detach on a terminated thread. */
440
441 static void pthread_handle_free(pthread_t th_id)
442 {
443   pthread_handle handle = thread_handle(th_id);
444   pthread_descr th;
445
446   __pthread_lock(&handle->h_lock);
447   if (invalid_handle(handle, th_id)) {
448     /* pthread_reap_children has deallocated the thread already,
449        nothing needs to be done */
450     __pthread_unlock(&handle->h_lock);
451     return;
452   }
453   th = handle->h_descr;
454   if (th->p_exited) {
455     __pthread_unlock(&handle->h_lock);
456     pthread_free(th);
457   } else {
458     /* The Unix process of the thread is still running.
459        Mark the thread as detached so that the thread manager will
460        deallocate its resources when the Unix process exits. */
461     th->p_detached = 1;
462     __pthread_unlock(&handle->h_lock);
463   }
464 }
465
466 /* Send a signal to all running threads */
467
468 static void pthread_kill_all_threads(int sig, int main_thread_also)
469 {
470   pthread_descr th;
471   for (th = __pthread_main_thread->p_nextlive;
472        th != __pthread_main_thread;
473        th = th->p_nextlive) {
474     kill(th->p_pid, sig);
475   }
476   if (main_thread_also) {
477     kill(__pthread_main_thread->p_pid, sig);
478   }
479 }
480
481 /* Process-wide exit() */
482
483 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
484 {
485   pthread_descr th;
486   __pthread_exit_requested = 1;
487   __pthread_exit_code = exitcode;
488   /* Send the CANCEL signal to all running threads, including the main
489      thread, but excluding the thread from which the exit request originated
490      (that thread must complete the exit, e.g. calling atexit functions
491      and flushing stdio buffers). */
492   for (th = issuing_thread->p_nextlive;
493        th != issuing_thread;
494        th = th->p_nextlive) {
495     kill(th->p_pid, PTHREAD_SIG_CANCEL);
496   }
497   /* Now, wait for all these threads, so that they don't become zombies
498      and their times are properly added to the thread manager's times. */
499   for (th = issuing_thread->p_nextlive;
500        th != issuing_thread;
501        th = th->p_nextlive) {
502     waitpid(th->p_pid, NULL, __WCLONE);
503   }
504   restart(issuing_thread);
505   _exit(0);
506 }
507
508 /* Handler for PTHREAD_SIG_RESTART in thread manager thread */
509
510 void __pthread_manager_sighandler(int sig)
511 {
512   terminated_children = 1;
513 }
514
515 /* Adjust priority of thread manager so that it always run at a priority
516    higher than all threads */
517
518 void __pthread_manager_adjust_prio(int thread_prio)
519 {
520   struct sched_param param;
521
522   if (thread_prio <= __pthread_manager_thread.p_priority) return;
523   param.sched_priority =
524     thread_prio < __sched_get_priority_max(SCHED_FIFO)
525     ? thread_prio + 1 : thread_prio;
526   __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
527   __pthread_manager_thread.p_priority = thread_prio;
528 }