Update.
[glibc.git] / linuxthreads / manager.c
blob6bafc868c15c89667becc1280750706b9f927fd6
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. */
15 /* The "thread manager" thread: manages creation and termination of threads */
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>
31 #include "pthread.h"
32 #include "internals.h"
33 #include "spinlock.h"
34 #include "restart.h"
35 #include "semaphore.h"
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 */ };
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;
46 /* Number of active entries in __pthread_handles (used by gdb) */
47 volatile int __pthread_handles_num = 2;
49 /* Whether to use debugger additional actions for thread creation
50 (set to 1 by gdb) */
51 volatile int __pthread_threads_debug = 0;
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. */
57 static inline pthread_descr thread_segment(int seg)
59 return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
60 - 1;
63 /* Flag set in signal handler to record child termination */
65 static volatile int terminated_children = 0;
67 /* Flag set when the initial thread is blocked on pthread_exit waiting
68 for all other threads to terminate */
70 static int main_thread_exiting = 0;
72 /* Counter used to generate unique thread identifier.
73 Thread identifier is pthread_threads_counter + segment. */
75 static pthread_t pthread_threads_counter = 0;
77 /* Forward declarations */
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);
87 /* The server thread managing requests for thread creation and termination */
89 int __pthread_manager(void *arg)
91 int reqfd = (int)arg;
92 struct pollfd ufd;
93 sigset_t mask;
94 int n;
95 struct pthread_request request;
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);
120 /* Check for termination of the main thread */
121 if (getppid() == 1) {
122 pthread_kill_all_threads(SIGKILL, 0);
123 _exit(0);
125 /* Check for dead children */
126 if (terminated_children) {
127 terminated_children = 0;
128 pthread_reap_children();
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;
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 and gdb will restart the
164 new thread when it is ready to handle the new thread. */
165 if (__pthread_threads_debug && __pthread_sig_debug > 0)
166 raise(__pthread_sig_debug);
167 break;
173 /* Process creation */
175 static int pthread_start_thread(void *arg)
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, self->p_nr);
183 #endif
184 /* Make sure our pid field is initialized, just in case we get there
185 before our father has initialized it. */
186 THREAD_SETMEM(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 (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
192 __sched_setscheduler(THREAD_GETMEM(self, p_pid),
193 THREAD_GETMEM(self, p_start_args.schedpolicy),
194 &self->p_start_args.schedparam);
195 /* Make gdb aware of new thread */
196 if (__pthread_threads_debug && __pthread_sig_debug > 0) {
197 request.req_thread = self;
198 request.req_kind = REQ_DEBUG;
199 __libc_write(__pthread_manager_request,
200 (char *) &request, sizeof(request));
201 suspend(self);
203 /* Run the thread code */
204 outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
205 p_start_args.arg));
206 /* Exit with the given return value */
207 pthread_exit(outcome);
208 return 0;
211 static int pthread_allocate_stack(const pthread_attr_t *attr,
212 pthread_descr default_new_thread,
213 int pagesize,
214 pthread_descr * out_new_thread,
215 char ** out_new_thread_bottom,
216 char ** out_guardaddr,
217 size_t * out_guardsize)
219 pthread_descr new_thread;
220 char * new_thread_bottom;
221 char * guardaddr;
222 size_t stacksize, guardsize;
224 if (attr != NULL && attr->__stackaddr_set)
226 /* The user provided a stack. */
227 new_thread =
228 (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
229 new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
230 guardaddr = NULL;
231 guardsize = 0;
232 __pthread_nonstandard_stacks = 1;
234 else
236 /* Allocate space for stack and thread descriptor at default address */
237 new_thread = default_new_thread;
238 new_thread_bottom = (char *) new_thread - STACK_SIZE;
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 /* Bad luck, this segment is already mapped. */
244 return -1;
245 /* We manage to get a stack. Now see whether we need a guard
246 and allocate it if necessary. Notice that the default
247 attributes (stack_size = STACK_SIZE - pagesize and
248 guardsize = pagesize) do not need a guard page, since
249 the RLIMIT_STACK soft limit prevents stacks from
250 running into one another. */
251 if (attr == NULL ||
252 attr->__guardsize == 0 ||
253 (attr->__guardsize == pagesize &&
254 attr->__stacksize == STACK_SIZE - pagesize))
256 /* We don't need a guard page. */
257 guardaddr = NULL;
258 guardsize = 0;
260 else
262 /* Put a bad page at the bottom of the stack */
263 stacksize = roundup(attr->__stacksize, pagesize);
264 if (stacksize >= STACK_SIZE - pagesize)
265 stacksize = STACK_SIZE - pagesize;
266 guardaddr = (void *)new_thread - stacksize;
267 guardsize = attr->__guardsize;
268 if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
269 == MAP_FAILED)
271 /* We don't make this an error. */
272 guardaddr = NULL;
273 guardsize = 0;
277 /* Clear the thread data structure. */
278 memset (new_thread, '\0', sizeof (*new_thread));
279 *out_new_thread = new_thread;
280 *out_new_thread_bottom = new_thread_bottom;
281 *out_guardaddr = guardaddr;
282 *out_guardsize = guardsize;
283 return 0;
286 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
287 void * (*start_routine)(void *), void *arg,
288 sigset_t * mask, int father_pid)
290 size_t sseg;
291 int pid;
292 pthread_descr new_thread;
293 char * new_thread_bottom;
294 pthread_t new_thread_id;
295 char *guardaddr = NULL;
296 size_t guardsize = 0;
297 int pagesize = __getpagesize();
299 /* First check whether we have to change the policy and if yes, whether
300 we can do this. Normally this should be done by examining the
301 return value of the __sched_setscheduler call in pthread_start_thread
302 but this is hard to implement. FIXME */
303 if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
304 return EPERM;
305 /* Find a free segment for the thread, and allocate a stack if needed */
306 for (sseg = 2; ; sseg++)
308 if (sseg >= PTHREAD_THREADS_MAX)
309 return EAGAIN;
310 if (__pthread_handles[sseg].h_descr != NULL)
311 continue;
312 if (pthread_allocate_stack(attr, thread_segment(sseg), pagesize,
313 &new_thread, &new_thread_bottom,
314 &guardaddr, &guardsize) == 0)
315 break;
317 __pthread_handles_num++;
318 /* Allocate new thread identifier */
319 pthread_threads_counter += PTHREAD_THREADS_MAX;
320 new_thread_id = sseg + pthread_threads_counter;
321 /* Initialize the thread descriptor. Elements which have to be
322 initialized to zero already have this value. */
323 new_thread->p_tid = new_thread_id;
324 new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
325 new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
326 new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
327 new_thread->p_errnop = &new_thread->p_errno;
328 new_thread->p_h_errnop = &new_thread->p_h_errno;
329 new_thread->p_guardaddr = guardaddr;
330 new_thread->p_guardsize = guardsize;
331 new_thread->p_self = new_thread;
332 new_thread->p_nr = sseg;
333 /* Initialize the thread handle */
334 __pthread_init_lock(&__pthread_handles[sseg].h_lock);
335 __pthread_handles[sseg].h_descr = new_thread;
336 __pthread_handles[sseg].h_bottom = new_thread_bottom;
337 /* Determine scheduling parameters for the thread */
338 new_thread->p_start_args.schedpolicy = -1;
339 if (attr != NULL) {
340 new_thread->p_detached = attr->__detachstate;
341 new_thread->p_userstack = attr->__stackaddr_set;
343 switch(attr->__inheritsched) {
344 case PTHREAD_EXPLICIT_SCHED:
345 new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
346 memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam,
347 sizeof (struct sched_param));
348 break;
349 case PTHREAD_INHERIT_SCHED:
350 /* schedpolicy doesn't need to be set, only get priority */
351 __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
352 break;
354 new_thread->p_priority =
355 new_thread->p_start_args.schedparam.sched_priority;
357 /* Finish setting up arguments to pthread_start_thread */
358 new_thread->p_start_args.start_routine = start_routine;
359 new_thread->p_start_args.arg = arg;
360 new_thread->p_start_args.mask = *mask;
361 /* Raise priority of thread manager if needed */
362 __pthread_manager_adjust_prio(new_thread->p_priority);
363 /* Do the cloning */
364 pid = __clone(pthread_start_thread, (void **) new_thread,
365 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
366 __pthread_sig_cancel, new_thread);
367 /* Check if cloning succeeded */
368 if (pid == -1) {
369 /* Free the stack if we allocated it */
370 if (attr == NULL || !attr->__stackaddr_set)
372 munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
373 INITIAL_STACK_SIZE);
374 if (new_thread->p_guardsize != 0)
375 munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
377 __pthread_handles[sseg].h_descr = NULL;
378 __pthread_handles[sseg].h_bottom = NULL;
379 __pthread_handles_num--;
380 return errno;
382 /* Insert new thread in doubly linked list of active threads */
383 new_thread->p_prevlive = __pthread_main_thread;
384 new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
385 __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
386 __pthread_main_thread->p_nextlive = new_thread;
387 /* Set pid field of the new thread, in case we get there before the
388 child starts. */
389 new_thread->p_pid = pid;
390 /* We're all set */
391 *thread = new_thread_id;
392 return 0;
396 /* Try to free the resources of a thread when requested by pthread_join
397 or pthread_detach on a terminated thread. */
399 static void pthread_free(pthread_descr th)
401 pthread_handle handle;
402 ASSERT(th->p_exited);
403 /* Make the handle invalid */
404 handle = thread_handle(th->p_tid);
405 __pthread_lock(&handle->h_lock, NULL);
406 handle->h_descr = NULL;
407 handle->h_bottom = (char *)(-1L);
408 __pthread_unlock(&handle->h_lock);
409 #ifdef FREE_THREAD_SELF
410 FREE_THREAD_SELF(th, th->p_nr);
411 #endif
412 /* One fewer threads in __pthread_handles */
413 __pthread_handles_num--;
414 /* If initial thread, nothing to free */
415 if (th == &__pthread_initial_thread) return;
416 if (!th->p_userstack)
418 /* Free the stack and thread descriptor area */
419 if (th->p_guardsize != 0)
420 munmap(th->p_guardaddr, th->p_guardsize);
421 munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
425 /* Handle threads that have exited */
427 static void pthread_exited(pid_t pid)
429 pthread_descr th;
430 int detached;
431 /* Find thread with that pid */
432 for (th = __pthread_main_thread->p_nextlive;
433 th != __pthread_main_thread;
434 th = th->p_nextlive) {
435 if (th->p_pid == pid) {
436 /* Remove thread from list of active threads */
437 th->p_nextlive->p_prevlive = th->p_prevlive;
438 th->p_prevlive->p_nextlive = th->p_nextlive;
439 /* Mark thread as exited, and if detached, free its resources */
440 __pthread_lock(th->p_lock, NULL);
441 th->p_exited = 1;
442 detached = th->p_detached;
443 __pthread_unlock(th->p_lock);
444 if (detached)
445 pthread_free(th);
446 break;
449 /* If all threads have exited and the main thread is pending on a
450 pthread_exit, wake up the main thread and terminate ourselves. */
451 if (main_thread_exiting &&
452 __pthread_main_thread->p_nextlive == __pthread_main_thread) {
453 restart(__pthread_main_thread);
454 _exit(0);
458 static void pthread_reap_children(void)
460 pid_t pid;
461 int status;
463 while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
464 pthread_exited(pid);
465 if (WIFSIGNALED(status)) {
466 /* If a thread died due to a signal, send the same signal to
467 all other threads, including the main thread. */
468 pthread_kill_all_threads(WTERMSIG(status), 1);
469 _exit(0);
474 /* Try to free the resources of a thread when requested by pthread_join
475 or pthread_detach on a terminated thread. */
477 static void pthread_handle_free(pthread_t th_id)
479 pthread_handle handle = thread_handle(th_id);
480 pthread_descr th;
482 __pthread_lock(&handle->h_lock, NULL);
483 if (invalid_handle(handle, th_id)) {
484 /* pthread_reap_children has deallocated the thread already,
485 nothing needs to be done */
486 __pthread_unlock(&handle->h_lock);
487 return;
489 th = handle->h_descr;
490 if (th->p_exited) {
491 __pthread_unlock(&handle->h_lock);
492 pthread_free(th);
493 } else {
494 /* The Unix process of the thread is still running.
495 Mark the thread as detached so that the thread manager will
496 deallocate its resources when the Unix process exits. */
497 th->p_detached = 1;
498 __pthread_unlock(&handle->h_lock);
502 /* Send a signal to all running threads */
504 static void pthread_kill_all_threads(int sig, int main_thread_also)
506 pthread_descr th;
507 for (th = __pthread_main_thread->p_nextlive;
508 th != __pthread_main_thread;
509 th = th->p_nextlive) {
510 kill(th->p_pid, sig);
512 if (main_thread_also) {
513 kill(__pthread_main_thread->p_pid, sig);
517 /* Process-wide exit() */
519 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
521 pthread_descr th;
522 __pthread_exit_requested = 1;
523 __pthread_exit_code = exitcode;
524 /* Send the CANCEL signal to all running threads, including the main
525 thread, but excluding the thread from which the exit request originated
526 (that thread must complete the exit, e.g. calling atexit functions
527 and flushing stdio buffers). */
528 for (th = issuing_thread->p_nextlive;
529 th != issuing_thread;
530 th = th->p_nextlive) {
531 kill(th->p_pid, __pthread_sig_cancel);
533 /* Now, wait for all these threads, so that they don't become zombies
534 and their times are properly added to the thread manager's times. */
535 for (th = issuing_thread->p_nextlive;
536 th != issuing_thread;
537 th = th->p_nextlive) {
538 waitpid(th->p_pid, NULL, __WCLONE);
540 restart(issuing_thread);
541 _exit(0);
544 /* Handler for __pthread_sig_cancel in thread manager thread */
546 void __pthread_manager_sighandler(int sig)
548 terminated_children = 1;
551 /* Adjust priority of thread manager so that it always run at a priority
552 higher than all threads */
554 void __pthread_manager_adjust_prio(int thread_prio)
556 struct sched_param param;
558 if (thread_prio <= __pthread_manager_thread.p_priority) return;
559 param.sched_priority =
560 thread_prio < __sched_get_priority_max(SCHED_FIFO)
561 ? thread_prio + 1 : thread_prio;
562 __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
563 __pthread_manager_thread.p_priority = thread_prio;