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