Update.
[glibc.git] / linuxthreads / manager.c
blob7d48489f76c1f64b7f4c74e54d9f212cb9534bff
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/time.h>
27 #include <sys/wait.h> /* for waitpid macros */
28 #include <linux/tasks.h>
30 #include "pthread.h"
31 #include "internals.h"
32 #include "spinlock.h"
33 #include "restart.h"
34 #include "semaphore.h"
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 */ };
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;
44 /* Number of active entries in __pthread_handles (used by gdb) */
45 volatile int __pthread_handles_num = 1;
47 /* Whether to use debugger additional actions for thread creation
48 (set to 1 by gdb) */
49 volatile int __pthread_threads_debug = 0;
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. */
55 static inline pthread_descr thread_segment(int seg)
57 return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE)
58 - 1;
61 /* Flag set in signal handler to record child termination */
63 static volatile int terminated_children = 0;
65 /* Flag set when the initial thread is blocked on pthread_exit waiting
66 for all other threads to terminate */
68 static int main_thread_exiting = 0;
70 /* Counter used to generate unique thread identifier.
71 Thread identifier is pthread_threads_counter + segment. */
73 static pthread_t pthread_threads_counter = 0;
75 /* Forward declarations */
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);
85 /* The server thread managing requests for thread creation and termination */
87 int __pthread_manager(void *arg)
89 int reqfd = (int)arg;
90 struct pollfd ufd;
91 sigset_t mask;
92 int n;
93 struct pthread_request request;
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);
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 */
164 if (__pthread_threads_debug) raise(PTHREAD_SIG_CANCEL);
165 restart(request.req_thread);
166 break;
172 /* Process creation */
174 static int pthread_start_thread(void *arg)
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);
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;
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)
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;
220 /* Find a free stack segment for the current stack */
221 for (sseg = 1; ; sseg++)
223 if (sseg >= PTHREAD_THREADS_MAX)
224 return EAGAIN;
225 if (__pthread_handles[sseg].h_descr != NULL)
226 continue;
228 if (attr == NULL || !attr->stackaddr_set)
230 new_thread = thread_segment(sseg);
231 new_thread_bottom = (char *) new_thread - STACK_SIZE;
232 /* Allocate space for stack and thread descriptor. */
233 if (mmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
234 INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
235 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
236 -1, 0) != MAP_FAILED)
238 /* We manage to get a stack. Now see whether we need a guard
239 and allocate it if necessary. */
240 if (attr == NULL || attr->guardsize != 0)
242 guardsize = attr ? attr->guardsize : __getpagesize ();
243 guardaddr = mmap ((caddr_t)((char *)(new_thread+1)
244 - STACK_SIZE),
245 guardsize, 0, MAP_FIXED, -1, 0);
246 if (guardaddr == MAP_FAILED)
248 /* We don't make this an error. */
249 guardaddr = NULL;
250 guardsize = 0;
253 break;
255 /* It seems part of this segment is already mapped. Try the next. */
257 else
259 new_thread = (pthread_descr) ((long) attr->stackaddr
260 & -sizeof(void *)) - 1;
261 new_thread_bottom = (char *) attr->stackaddr - attr->stacksize;
262 break;
265 /* Allocate new thread identifier */
266 pthread_threads_counter += PTHREAD_THREADS_MAX;
267 new_thread_id = sseg + pthread_threads_counter;
268 /* Initialize the thread descriptor */
269 new_thread->p_nextwaiting = NULL;
270 new_thread->p_tid = new_thread_id;
271 new_thread->p_priority = 0;
272 new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
273 new_thread->p_signal = 0;
274 new_thread->p_signal_jmp = NULL;
275 new_thread->p_cancel_jmp = NULL;
276 new_thread->p_terminated = 0;
277 new_thread->p_detached = attr == NULL ? 0 : attr->detachstate;
278 new_thread->p_exited = 0;
279 new_thread->p_retval = NULL;
280 new_thread->p_joining = NULL;
281 new_thread->p_cleanup = NULL;
282 new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
283 new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
284 new_thread->p_canceled = 0;
285 new_thread->p_errnop = &new_thread->p_errno;
286 new_thread->p_errno = 0;
287 new_thread->p_h_errnop = &new_thread->p_h_errno;
288 new_thread->p_h_errno = 0;
289 new_thread->p_in_sighandler = NULL;
290 new_thread->p_sigwaiting = 0;
291 new_thread->p_guardaddr = guardaddr;
292 new_thread->p_guardsize = guardsize;
293 new_thread->p_userstack = attr != NULL && attr->stackaddr_set;
294 memset (new_thread->p_specific, '\0',
295 PTHREAD_KEY_1STLEVEL_SIZE * sizeof (new_thread->p_specific[0]));
296 /* Initialize the thread handle */
297 __pthread_init_lock(&__pthread_handles[sseg].h_lock);
298 __pthread_handles[sseg].h_descr = new_thread;
299 __pthread_handles[sseg].h_bottom = new_thread_bottom;
300 /* Determine scheduling parameters for the thread */
301 new_thread->p_start_args.schedpolicy = -1;
302 if (attr != NULL) {
303 switch(attr->inheritsched) {
304 case PTHREAD_EXPLICIT_SCHED:
305 new_thread->p_start_args.schedpolicy = attr->schedpolicy;
306 memcpy (&new_thread->p_start_args.schedparam, &attr->schedparam,
307 sizeof (struct sched_param));
308 break;
309 case PTHREAD_INHERIT_SCHED:
310 /* schedpolicy doesn't need to be set, only get priority */
311 __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
312 break;
314 new_thread->p_priority =
315 new_thread->p_start_args.schedparam.sched_priority;
317 /* Finish setting up arguments to pthread_start_thread */
318 new_thread->p_start_args.start_routine = start_routine;
319 new_thread->p_start_args.arg = arg;
320 new_thread->p_start_args.mask = *mask;
321 /* Raise priority of thread manager if needed */
322 __pthread_manager_adjust_prio(new_thread->p_priority);
323 /* Do the cloning */
324 pid = __clone(pthread_start_thread, (void **) new_thread,
325 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
326 PTHREAD_SIG_RESTART,
327 new_thread);
328 /* Check if cloning succeeded */
329 if (pid == -1) {
330 /* Free the stack if we allocated it */
331 if (attr == NULL || !attr->stackaddr_set)
333 munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
334 INITIAL_STACK_SIZE);
335 if (new_thread->p_guardsize != 0)
336 munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
338 __pthread_handles[sseg].h_descr = NULL;
339 __pthread_handles[sseg].h_bottom = NULL;
340 __pthread_handles_num--;
341 return errno;
343 /* Insert new thread in doubly linked list of active threads */
344 new_thread->p_prevlive = __pthread_main_thread;
345 new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
346 __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
347 __pthread_main_thread->p_nextlive = new_thread;
348 /* Set pid field of the new thread, in case we get there before the
349 child starts. */
350 new_thread->p_pid = pid;
351 /* We're all set */
352 *thread = new_thread_id;
353 return 0;
357 /* Try to free the resources of a thread when requested by pthread_join
358 or pthread_detach on a terminated thread. */
360 static void pthread_free(pthread_descr th)
362 pthread_handle handle;
363 ASSERT(th->p_exited);
364 /* Make the handle invalid */
365 handle = thread_handle(th->p_tid);
366 __pthread_lock(&handle->h_lock);
367 handle->h_descr = NULL;
368 handle->h_bottom = (char *)(-1L);
369 __pthread_unlock(&handle->h_lock);
370 /* One fewer threads in __pthread_handles */
371 __pthread_handles_num--;
372 /* If initial thread, nothing to free */
373 if (th == &__pthread_initial_thread) return;
374 if (!th->p_userstack)
376 /* Free the stack and thread descriptor area */
377 if (th->p_guardsize != 0)
378 munmap(th->p_guardaddr, th->p_guardsize);
379 munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
383 /* Handle threads that have exited */
385 static void pthread_exited(pid_t pid)
387 pthread_descr th;
388 int detached;
389 /* Find thread with that pid */
390 for (th = __pthread_main_thread->p_nextlive;
391 th != __pthread_main_thread;
392 th = th->p_nextlive) {
393 if (th->p_pid == pid) {
394 /* Remove thread from list of active threads */
395 th->p_nextlive->p_prevlive = th->p_prevlive;
396 th->p_prevlive->p_nextlive = th->p_nextlive;
397 /* Mark thread as exited, and if detached, free its resources */
398 __pthread_lock(th->p_lock);
399 th->p_exited = 1;
400 detached = th->p_detached;
401 __pthread_unlock(th->p_lock);
402 if (detached)
403 pthread_free(th);
404 break;
407 /* If all threads have exited and the main thread is pending on a
408 pthread_exit, wake up the main thread and terminate ourselves. */
409 if (main_thread_exiting &&
410 __pthread_main_thread->p_nextlive == __pthread_main_thread) {
411 restart(__pthread_main_thread);
412 _exit(0);
416 static void pthread_reap_children(void)
418 pid_t pid;
419 int status;
421 while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
422 pthread_exited(pid);
423 if (WIFSIGNALED(status)) {
424 /* If a thread died due to a signal, send the same signal to
425 all other threads, including the main thread. */
426 pthread_kill_all_threads(WTERMSIG(status), 1);
427 _exit(0);
432 /* Try to free the resources of a thread when requested by pthread_join
433 or pthread_detach on a terminated thread. */
435 static void pthread_handle_free(pthread_t th_id)
437 pthread_handle handle = thread_handle(th_id);
438 pthread_descr th;
440 __pthread_lock(&handle->h_lock);
441 if (invalid_handle(handle, th_id)) {
442 /* pthread_reap_children has deallocated the thread already,
443 nothing needs to be done */
444 __pthread_unlock(&handle->h_lock);
445 return;
447 th = handle->h_descr;
448 if (th->p_exited) {
449 __pthread_unlock(&handle->h_lock);
450 pthread_free(th);
451 } else {
452 /* The Unix process of the thread is still running.
453 Mark the thread as detached so that the thread manager will
454 deallocate its resources when the Unix process exits. */
455 th->p_detached = 1;
456 __pthread_unlock(&handle->h_lock);
460 /* Send a signal to all running threads */
462 static void pthread_kill_all_threads(int sig, int main_thread_also)
464 pthread_descr th;
465 for (th = __pthread_main_thread->p_nextlive;
466 th != __pthread_main_thread;
467 th = th->p_nextlive) {
468 kill(th->p_pid, sig);
470 if (main_thread_also) {
471 kill(__pthread_main_thread->p_pid, sig);
475 /* Process-wide exit() */
477 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
479 pthread_descr th;
480 __pthread_exit_requested = 1;
481 __pthread_exit_code = exitcode;
482 /* Send the CANCEL signal to all running threads, including the main
483 thread, but excluding the thread from which the exit request originated
484 (that thread must complete the exit, e.g. calling atexit functions
485 and flushing stdio buffers). */
486 for (th = issuing_thread->p_nextlive;
487 th != issuing_thread;
488 th = th->p_nextlive) {
489 kill(th->p_pid, PTHREAD_SIG_CANCEL);
491 /* Now, wait for all these threads, so that they don't become zombies
492 and their times are properly added to the thread manager's times. */
493 for (th = issuing_thread->p_nextlive;
494 th != issuing_thread;
495 th = th->p_nextlive) {
496 waitpid(th->p_pid, NULL, __WCLONE);
498 restart(issuing_thread);
499 _exit(0);
502 /* Handler for PTHREAD_SIG_RESTART in thread manager thread */
504 void __pthread_manager_sighandler(int sig)
506 terminated_children = 1;
509 /* Adjust priority of thread manager so that it always run at a priority
510 higher than all threads */
512 void __pthread_manager_adjust_prio(int thread_prio)
514 struct sched_param param;
516 if (thread_prio <= __pthread_manager_thread.p_priority) return;
517 param.sched_priority =
518 thread_prio < __sched_get_priority_max(SCHED_FIFO)
519 ? thread_prio + 1 : thread_prio;
520 __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
521 __pthread_manager_thread.p_priority = thread_prio;