Update.
[glibc.git] / linuxthreads / manager.c
blob033e5adc5fe0a6fbcba13f1fe1dd66ca789d36b1
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 if (__pthread_sig_debug > 0)
108 sigdelset(&mask, __pthread_sig_debug); /* for debugging purposes */
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);
122 /* Check for termination of the main thread */
123 if (getppid() == 1) {
124 pthread_kill_all_threads(SIGKILL, 0);
125 _exit(0);
127 /* Check for dead children */
128 if (terminated_children) {
129 terminated_children = 0;
130 pthread_reap_children();
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;
160 break;
161 case REQ_POST:
162 sem_post(request.req_args.post);
163 break;
164 case REQ_DEBUG:
165 /* Make gdb aware of new thread */
166 if (__pthread_threads_debug && __pthread_sig_debug > 0)
167 raise(__pthread_sig_debug);
168 restart(request.req_thread);
169 break;
175 /* Process creation */
177 static int pthread_start_thread(void *arg)
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 __sched_setscheduler(THREAD_GETMEM(self, p_pid),
195 THREAD_GETMEM(self, p_start_args.schedpolicy),
196 &self->p_start_args.schedparam);
197 /* Make gdb aware of new thread */
198 if (__pthread_threads_debug) {
199 request.req_thread = self;
200 request.req_kind = REQ_DEBUG;
201 __libc_write(__pthread_manager_request,
202 (char *) &request, sizeof(request));
203 suspend(self);
205 /* Run the thread code */
206 outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
207 p_start_args.arg));
208 /* Exit with the given return value */
209 pthread_exit(outcome);
210 return 0;
213 static int pthread_allocate_stack(const pthread_attr_t *attr,
214 pthread_descr default_new_thread,
215 int pagesize,
216 pthread_descr * out_new_thread,
217 char ** out_new_thread_bottom,
218 char ** out_guardaddr,
219 size_t * out_guardsize)
221 pthread_descr new_thread;
222 char * new_thread_bottom;
223 char * guardaddr;
224 size_t stacksize, guardsize;
226 if (attr != NULL && attr->__stackaddr_set)
228 /* The user provided a stack. */
229 new_thread =
230 (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
231 new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
232 guardaddr = NULL;
233 guardsize = 0;
234 __pthread_nonstandard_stacks = 1;
236 else
238 /* Allocate space for stack and thread descriptor at default address */
239 new_thread = default_new_thread;
240 new_thread_bottom = (char *) new_thread - STACK_SIZE;
241 if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
242 INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
243 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
244 -1, 0) == MAP_FAILED)
245 /* Bad luck, this segment is already mapped. */
246 return -1;
247 /* We manage to get a stack. Now see whether we need a guard
248 and allocate it if necessary. Notice that the default
249 attributes (stack_size = STACK_SIZE - pagesize and
250 guardsize = pagesize) do not need a guard page, since
251 the RLIMIT_STACK soft limit prevents stacks from
252 running into one another. */
253 if (attr == NULL ||
254 attr->__guardsize == 0 ||
255 (attr->__guardsize == pagesize &&
256 attr->__stacksize == STACK_SIZE - pagesize))
258 /* We don't need a guard page. */
259 guardaddr = NULL;
260 guardsize = 0;
262 else
264 /* Put a bad page at the bottom of the stack */
265 stacksize = roundup(attr->__stacksize, pagesize);
266 if (stacksize >= STACK_SIZE - pagesize)
267 stacksize = STACK_SIZE - pagesize;
268 guardaddr = (void *)new_thread - stacksize;
269 guardsize = attr->__guardsize;
270 if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
271 == MAP_FAILED)
273 /* We don't make this an error. */
274 guardaddr = NULL;
275 guardsize = 0;
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 */
322 new_thread->p_nextwaiting = NULL;
323 new_thread->p_tid = new_thread_id;
324 new_thread->p_priority = 0;
325 new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
326 new_thread->p_signal = 0;
327 new_thread->p_signal_jmp = NULL;
328 new_thread->p_cancel_jmp = NULL;
329 new_thread->p_terminated = 0;
330 new_thread->p_detached = attr == NULL ? 0 : attr->__detachstate;
331 new_thread->p_exited = 0;
332 new_thread->p_retval = NULL;
333 new_thread->p_joining = NULL;
334 new_thread->p_cleanup = NULL;
335 new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
336 new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
337 new_thread->p_canceled = 0;
338 new_thread->p_errnop = &new_thread->p_errno;
339 new_thread->p_errno = 0;
340 new_thread->p_h_errnop = &new_thread->p_h_errno;
341 new_thread->p_h_errno = 0;
342 new_thread->p_in_sighandler = NULL;
343 new_thread->p_sigwaiting = 0;
344 new_thread->p_guardaddr = guardaddr;
345 new_thread->p_guardsize = guardsize;
346 new_thread->p_userstack = attr != NULL && attr->__stackaddr_set;
347 memset (new_thread->p_specific, '\0',
348 PTHREAD_KEY_1STLEVEL_SIZE * sizeof (new_thread->p_specific[0]));
349 new_thread->p_self = new_thread;
350 new_thread->p_nr = sseg;
351 /* Initialize the thread handle */
352 __pthread_init_lock(&__pthread_handles[sseg].h_lock);
353 __pthread_handles[sseg].h_descr = new_thread;
354 __pthread_handles[sseg].h_bottom = new_thread_bottom;
355 /* Determine scheduling parameters for the thread */
356 new_thread->p_start_args.schedpolicy = -1;
357 if (attr != NULL) {
358 switch(attr->__inheritsched) {
359 case PTHREAD_EXPLICIT_SCHED:
360 new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
361 memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam,
362 sizeof (struct sched_param));
363 break;
364 case PTHREAD_INHERIT_SCHED:
365 /* schedpolicy doesn't need to be set, only get priority */
366 __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
367 break;
369 new_thread->p_priority =
370 new_thread->p_start_args.schedparam.sched_priority;
372 /* Finish setting up arguments to pthread_start_thread */
373 new_thread->p_start_args.start_routine = start_routine;
374 new_thread->p_start_args.arg = arg;
375 new_thread->p_start_args.mask = *mask;
376 /* Raise priority of thread manager if needed */
377 __pthread_manager_adjust_prio(new_thread->p_priority);
378 /* Do the cloning */
379 pid = __clone(pthread_start_thread, (void **) new_thread,
380 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
381 __pthread_sig_cancel, new_thread);
382 /* Check if cloning succeeded */
383 if (pid == -1) {
384 /* Free the stack if we allocated it */
385 if (attr == NULL || !attr->__stackaddr_set)
387 munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
388 INITIAL_STACK_SIZE);
389 if (new_thread->p_guardsize != 0)
390 munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
392 __pthread_handles[sseg].h_descr = NULL;
393 __pthread_handles[sseg].h_bottom = NULL;
394 __pthread_handles_num--;
395 return errno;
397 /* Insert new thread in doubly linked list of active threads */
398 new_thread->p_prevlive = __pthread_main_thread;
399 new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
400 __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
401 __pthread_main_thread->p_nextlive = new_thread;
402 /* Set pid field of the new thread, in case we get there before the
403 child starts. */
404 new_thread->p_pid = pid;
405 /* We're all set */
406 *thread = new_thread_id;
407 return 0;
411 /* Try to free the resources of a thread when requested by pthread_join
412 or pthread_detach on a terminated thread. */
414 static void pthread_free(pthread_descr th)
416 pthread_handle handle;
417 ASSERT(th->p_exited);
418 /* Make the handle invalid */
419 handle = thread_handle(th->p_tid);
420 __pthread_lock(&handle->h_lock, NULL);
421 handle->h_descr = NULL;
422 handle->h_bottom = (char *)(-1L);
423 __pthread_unlock(&handle->h_lock);
424 #ifdef FREE_THREAD_SELF
425 FREE_THREAD_SELF(th, th->p_nr);
426 #endif
427 /* One fewer threads in __pthread_handles */
428 __pthread_handles_num--;
429 /* If initial thread, nothing to free */
430 if (th == &__pthread_initial_thread) return;
431 if (!th->p_userstack)
433 /* Free the stack and thread descriptor area */
434 if (th->p_guardsize != 0)
435 munmap(th->p_guardaddr, th->p_guardsize);
436 munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
440 /* Handle threads that have exited */
442 static void pthread_exited(pid_t pid)
444 pthread_descr th;
445 int detached;
446 /* Find thread with that pid */
447 for (th = __pthread_main_thread->p_nextlive;
448 th != __pthread_main_thread;
449 th = th->p_nextlive) {
450 if (th->p_pid == pid) {
451 /* Remove thread from list of active threads */
452 th->p_nextlive->p_prevlive = th->p_prevlive;
453 th->p_prevlive->p_nextlive = th->p_nextlive;
454 /* Mark thread as exited, and if detached, free its resources */
455 __pthread_lock(th->p_lock, NULL);
456 th->p_exited = 1;
457 detached = th->p_detached;
458 __pthread_unlock(th->p_lock);
459 if (detached)
460 pthread_free(th);
461 break;
464 /* If all threads have exited and the main thread is pending on a
465 pthread_exit, wake up the main thread and terminate ourselves. */
466 if (main_thread_exiting &&
467 __pthread_main_thread->p_nextlive == __pthread_main_thread) {
468 restart(__pthread_main_thread);
469 _exit(0);
473 static void pthread_reap_children(void)
475 pid_t pid;
476 int status;
478 while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
479 pthread_exited(pid);
480 if (WIFSIGNALED(status)) {
481 /* If a thread died due to a signal, send the same signal to
482 all other threads, including the main thread. */
483 pthread_kill_all_threads(WTERMSIG(status), 1);
484 _exit(0);
489 /* Try to free the resources of a thread when requested by pthread_join
490 or pthread_detach on a terminated thread. */
492 static void pthread_handle_free(pthread_t th_id)
494 pthread_handle handle = thread_handle(th_id);
495 pthread_descr th;
497 __pthread_lock(&handle->h_lock, NULL);
498 if (invalid_handle(handle, th_id)) {
499 /* pthread_reap_children has deallocated the thread already,
500 nothing needs to be done */
501 __pthread_unlock(&handle->h_lock);
502 return;
504 th = handle->h_descr;
505 if (th->p_exited) {
506 __pthread_unlock(&handle->h_lock);
507 pthread_free(th);
508 } else {
509 /* The Unix process of the thread is still running.
510 Mark the thread as detached so that the thread manager will
511 deallocate its resources when the Unix process exits. */
512 th->p_detached = 1;
513 __pthread_unlock(&handle->h_lock);
517 /* Send a signal to all running threads */
519 static void pthread_kill_all_threads(int sig, int main_thread_also)
521 pthread_descr th;
522 for (th = __pthread_main_thread->p_nextlive;
523 th != __pthread_main_thread;
524 th = th->p_nextlive) {
525 kill(th->p_pid, sig);
527 if (main_thread_also) {
528 kill(__pthread_main_thread->p_pid, sig);
532 /* Process-wide exit() */
534 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
536 pthread_descr th;
537 __pthread_exit_requested = 1;
538 __pthread_exit_code = exitcode;
539 /* Send the CANCEL signal to all running threads, including the main
540 thread, but excluding the thread from which the exit request originated
541 (that thread must complete the exit, e.g. calling atexit functions
542 and flushing stdio buffers). */
543 for (th = issuing_thread->p_nextlive;
544 th != issuing_thread;
545 th = th->p_nextlive) {
546 kill(th->p_pid, __pthread_sig_cancel);
548 /* Now, wait for all these threads, so that they don't become zombies
549 and their times are properly added to the thread manager's times. */
550 for (th = issuing_thread->p_nextlive;
551 th != issuing_thread;
552 th = th->p_nextlive) {
553 waitpid(th->p_pid, NULL, __WCLONE);
555 restart(issuing_thread);
556 _exit(0);
559 /* Handler for __pthread_sig_cancel in thread manager thread */
561 void __pthread_manager_sighandler(int sig)
563 terminated_children = 1;
566 /* Adjust priority of thread manager so that it always run at a priority
567 higher than all threads */
569 void __pthread_manager_adjust_prio(int thread_prio)
571 struct sched_param param;
573 if (thread_prio <= __pthread_manager_thread.p_priority) return;
574 param.sched_priority =
575 thread_prio < __sched_get_priority_max(SCHED_FIFO)
576 ? thread_prio + 1 : thread_prio;
577 __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
578 __pthread_manager_thread.p_priority = thread_prio;