Update.
[glibc.git] / linuxthreads / manager.c
blob41acf01b2921e13635a7fc9187ad85e0c69d67b1
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}, /* All NULLs */ };
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;
45 /* Number of active entries in __pthread_handles (used by gdb) */
46 volatile int __pthread_handles_num = 1;
48 /* Whether to use debugger additional actions for thread creation
49 (set to 1 by gdb) */
50 volatile int __pthread_threads_debug = 0;
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. */
56 static inline pthread_descr thread_segment(int seg)
58 return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
59 - 1;
62 /* Flag set in signal handler to record child termination */
64 static volatile int terminated_children = 0;
66 /* Flag set when the initial thread is blocked on pthread_exit waiting
67 for all other threads to terminate */
69 static int main_thread_exiting = 0;
71 /* Counter used to generate unique thread identifier.
72 Thread identifier is pthread_threads_counter + segment. */
74 static pthread_t pthread_threads_counter = 0;
76 /* Forward declarations */
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);
86 /* The server thread managing requests for thread creation and termination */
88 int __pthread_manager(void *arg)
90 int reqfd = (int)arg;
91 struct pollfd ufd;
92 sigset_t mask;
93 int n;
94 struct pthread_request request;
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);
121 /* Check for termination of the main thread */
122 if (getppid() == 1) {
123 pthread_kill_all_threads(SIGKILL, 0);
124 _exit(0);
126 /* Check for dead children */
127 if (terminated_children) {
128 terminated_children = 0;
129 pthread_reap_children();
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;
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;
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);
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);
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;
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)
217 pthread_descr new_thread;
218 char * new_thread_bottom;
219 char * guardaddr;
220 size_t stacksize, guardsize;
222 if (attr != NULL && attr->stackaddr_set)
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;
231 else
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))
253 /* We don't need a guard page. */
254 guardaddr = NULL;
255 guardsize = 0;
257 else
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)
268 /* We don't make this an error. */
269 guardaddr = NULL;
270 guardsize = 0;
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;
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)
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();
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++)
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;
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;
361 new_thread->p_priority =
362 new_thread->p_start_args.schedparam.sched_priority;
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)
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);
385 __pthread_handles[sseg].h_descr = NULL;
386 __pthread_handles[sseg].h_bottom = NULL;
387 __pthread_handles_num--;
388 return errno;
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;
404 /* Try to free the resources of a thread when requested by pthread_join
405 or pthread_detach on a terminated thread. */
407 static void pthread_free(pthread_descr th)
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)
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);
430 /* Handle threads that have exited */
432 static void pthread_exited(pid_t pid)
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;
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);
463 static void pthread_reap_children(void)
465 pid_t pid;
466 int status;
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);
479 /* Try to free the resources of a thread when requested by pthread_join
480 or pthread_detach on a terminated thread. */
482 static void pthread_handle_free(pthread_t th_id)
484 pthread_handle handle = thread_handle(th_id);
485 pthread_descr th;
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;
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);
507 /* Send a signal to all running threads */
509 static void pthread_kill_all_threads(int sig, int main_thread_also)
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);
517 if (main_thread_also) {
518 kill(__pthread_main_thread->p_pid, sig);
522 /* Process-wide exit() */
524 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
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);
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);
545 restart(issuing_thread);
546 _exit(0);
549 /* Handler for __pthread_sig_restart in thread manager thread */
551 void __pthread_manager_sighandler(int sig)
553 terminated_children = 1;
556 /* Adjust priority of thread manager so that it always run at a priority
557 higher than all threads */
559 void __pthread_manager_adjust_prio(int thread_prio)
561 struct sched_param param;
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;