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