(_dl_num_relocations): New variable. (do_lookup): Increment _dl_num_relocations for...
[glibc.git] / linuxthreads / manager.c
blob5a5420d9a9b0dac1f30f65473cad9cb88f31b8c6
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 */
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, self->p_nr);
182 #endif
183 /* Make sure our pid field is initialized, just in case we get there
184 before our father has initialized it. */
185 THREAD_SETMEM(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 (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
191 __sched_setscheduler(THREAD_GETMEM(self, p_pid),
192 THREAD_GETMEM(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(THREAD_GETMEM(self,
204 p_start_args.arg));
205 /* Exit with the given return value */
206 pthread_exit(outcome);
207 return 0;
210 static int pthread_allocate_stack(const pthread_attr_t *attr,
211 pthread_descr default_new_thread,
212 int pagesize,
213 pthread_descr * out_new_thread,
214 char ** out_new_thread_bottom,
215 char ** out_guardaddr,
216 size_t * out_guardsize)
218 pthread_descr new_thread;
219 char * new_thread_bottom;
220 char * guardaddr;
221 size_t stacksize, guardsize;
223 if (attr != NULL && attr->__stackaddr_set)
225 /* The user provided a stack. */
226 new_thread =
227 (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
228 new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
229 guardaddr = NULL;
230 guardsize = 0;
232 else
234 /* Allocate space for stack and thread descriptor at default address */
235 new_thread = default_new_thread;
236 new_thread_bottom = (char *) new_thread - STACK_SIZE;
237 if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
238 INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
239 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
240 -1, 0) == MAP_FAILED)
241 /* Bad luck, this segment is already mapped. */
242 return -1;
243 /* We manage to get a stack. Now see whether we need a guard
244 and allocate it if necessary. Notice that the default
245 attributes (stack_size = STACK_SIZE - pagesize and
246 guardsize = pagesize) do not need a guard page, since
247 the RLIMIT_STACK soft limit prevents stacks from
248 running into one another. */
249 if (attr == NULL ||
250 attr->__guardsize == 0 ||
251 (attr->__guardsize == pagesize &&
252 attr->__stacksize == STACK_SIZE - pagesize))
254 /* We don't need a guard page. */
255 guardaddr = NULL;
256 guardsize = 0;
258 else
260 /* Put a bad page at the bottom of the stack */
261 stacksize = roundup(attr->__stacksize, pagesize);
262 if (stacksize >= STACK_SIZE - pagesize)
263 stacksize = STACK_SIZE - pagesize;
264 guardaddr = (void *)new_thread - stacksize;
265 guardsize = attr->__guardsize;
266 if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
267 == MAP_FAILED)
269 /* We don't make this an error. */
270 guardaddr = NULL;
271 guardsize = 0;
275 *out_new_thread = new_thread;
276 *out_new_thread_bottom = new_thread_bottom;
277 *out_guardaddr = guardaddr;
278 *out_guardsize = guardsize;
279 return 0;
282 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
283 void * (*start_routine)(void *), void *arg,
284 sigset_t * mask, int father_pid)
286 size_t sseg;
287 int pid;
288 pthread_descr new_thread;
289 char * new_thread_bottom;
290 pthread_t new_thread_id;
291 char *guardaddr = NULL;
292 size_t guardsize = 0;
293 int pagesize = __getpagesize();
295 /* First check whether we have to change the policy and if yes, whether
296 we can do this. Normally this should be done by examining the
297 return value of the __sched_setscheduler call in pthread_start_thread
298 but this is hard to implement. FIXME */
299 if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
300 return EPERM;
301 /* Find a free segment for the thread, and allocate a stack if needed */
302 for (sseg = 2; ; sseg++)
304 if (sseg >= PTHREAD_THREADS_MAX)
305 return EAGAIN;
306 if (__pthread_handles[sseg].h_descr != NULL)
307 continue;
308 if (pthread_allocate_stack(attr, thread_segment(sseg), pagesize,
309 &new_thread, &new_thread_bottom,
310 &guardaddr, &guardsize) == 0)
311 break;
313 /* Allocate new thread identifier */
314 pthread_threads_counter += PTHREAD_THREADS_MAX;
315 new_thread_id = sseg + pthread_threads_counter;
316 /* Initialize the thread descriptor */
317 new_thread->p_nextwaiting = NULL;
318 new_thread->p_tid = new_thread_id;
319 new_thread->p_priority = 0;
320 new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
321 new_thread->p_signal = 0;
322 new_thread->p_signal_jmp = NULL;
323 new_thread->p_cancel_jmp = NULL;
324 new_thread->p_terminated = 0;
325 new_thread->p_detached = attr == NULL ? 0 : attr->__detachstate;
326 new_thread->p_exited = 0;
327 new_thread->p_retval = NULL;
328 new_thread->p_joining = NULL;
329 new_thread->p_cleanup = NULL;
330 new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
331 new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
332 new_thread->p_canceled = 0;
333 new_thread->p_errnop = &new_thread->p_errno;
334 new_thread->p_errno = 0;
335 new_thread->p_h_errnop = &new_thread->p_h_errno;
336 new_thread->p_h_errno = 0;
337 new_thread->p_in_sighandler = NULL;
338 new_thread->p_sigwaiting = 0;
339 new_thread->p_guardaddr = guardaddr;
340 new_thread->p_guardsize = guardsize;
341 new_thread->p_userstack = attr != NULL && attr->__stackaddr_set;
342 memset (new_thread->p_specific, '\0',
343 PTHREAD_KEY_1STLEVEL_SIZE * sizeof (new_thread->p_specific[0]));
344 new_thread->p_self = new_thread;
345 new_thread->p_nr = sseg;
346 /* Initialize the thread handle */
347 __pthread_init_lock(&__pthread_handles[sseg].h_lock);
348 __pthread_handles[sseg].h_descr = new_thread;
349 __pthread_handles[sseg].h_bottom = new_thread_bottom;
350 /* Determine scheduling parameters for the thread */
351 new_thread->p_start_args.schedpolicy = -1;
352 if (attr != NULL) {
353 switch(attr->__inheritsched) {
354 case PTHREAD_EXPLICIT_SCHED:
355 new_thread->p_start_args.schedpolicy = attr->__schedpolicy;
356 memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam,
357 sizeof (struct sched_param));
358 break;
359 case PTHREAD_INHERIT_SCHED:
360 /* schedpolicy doesn't need to be set, only get priority */
361 __sched_getparam(father_pid, &new_thread->p_start_args.schedparam);
362 break;
364 new_thread->p_priority =
365 new_thread->p_start_args.schedparam.sched_priority;
367 /* Finish setting up arguments to pthread_start_thread */
368 new_thread->p_start_args.start_routine = start_routine;
369 new_thread->p_start_args.arg = arg;
370 new_thread->p_start_args.mask = *mask;
371 /* Raise priority of thread manager if needed */
372 __pthread_manager_adjust_prio(new_thread->p_priority);
373 /* Do the cloning */
374 pid = __clone(pthread_start_thread, (void **) new_thread,
375 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
376 #ifdef CLONE_PTRACE
377 CLONE_PTRACE |
378 #endif
379 __pthread_sig_cancel, new_thread);
380 /* Check if cloning succeeded */
381 if (pid == -1) {
382 /* Free the stack if we allocated it */
383 if (attr == NULL || !attr->__stackaddr_set)
385 munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE),
386 INITIAL_STACK_SIZE);
387 if (new_thread->p_guardsize != 0)
388 munmap(new_thread->p_guardaddr, new_thread->p_guardsize);
390 __pthread_handles[sseg].h_descr = NULL;
391 __pthread_handles[sseg].h_bottom = NULL;
392 __pthread_handles_num--;
393 return errno;
395 /* Insert new thread in doubly linked list of active threads */
396 new_thread->p_prevlive = __pthread_main_thread;
397 new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
398 __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
399 __pthread_main_thread->p_nextlive = new_thread;
400 /* Set pid field of the new thread, in case we get there before the
401 child starts. */
402 new_thread->p_pid = pid;
403 /* We're all set */
404 *thread = new_thread_id;
405 return 0;
409 /* Try to free the resources of a thread when requested by pthread_join
410 or pthread_detach on a terminated thread. */
412 static void pthread_free(pthread_descr th)
414 pthread_handle handle;
415 ASSERT(th->p_exited);
416 /* Make the handle invalid */
417 handle = thread_handle(th->p_tid);
418 __pthread_lock(&handle->h_lock, NULL);
419 handle->h_descr = NULL;
420 handle->h_bottom = (char *)(-1L);
421 __pthread_unlock(&handle->h_lock);
422 #ifdef FREE_THREAD_SELF
423 FREE_THREAD_SELF(th, th->p_nr);
424 #endif
425 /* One fewer threads in __pthread_handles */
426 __pthread_handles_num--;
427 /* If initial thread, nothing to free */
428 if (th == &__pthread_initial_thread) return;
429 if (!th->p_userstack)
431 /* Free the stack and thread descriptor area */
432 if (th->p_guardsize != 0)
433 munmap(th->p_guardaddr, th->p_guardsize);
434 munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE);
438 /* Handle threads that have exited */
440 static void pthread_exited(pid_t pid)
442 pthread_descr th;
443 int detached;
444 /* Find thread with that pid */
445 for (th = __pthread_main_thread->p_nextlive;
446 th != __pthread_main_thread;
447 th = th->p_nextlive) {
448 if (th->p_pid == pid) {
449 /* Remove thread from list of active threads */
450 th->p_nextlive->p_prevlive = th->p_prevlive;
451 th->p_prevlive->p_nextlive = th->p_nextlive;
452 /* Mark thread as exited, and if detached, free its resources */
453 __pthread_lock(th->p_lock, NULL);
454 th->p_exited = 1;
455 detached = th->p_detached;
456 __pthread_unlock(th->p_lock);
457 if (detached)
458 pthread_free(th);
459 break;
462 /* If all threads have exited and the main thread is pending on a
463 pthread_exit, wake up the main thread and terminate ourselves. */
464 if (main_thread_exiting &&
465 __pthread_main_thread->p_nextlive == __pthread_main_thread) {
466 restart(__pthread_main_thread);
467 _exit(0);
471 static void pthread_reap_children(void)
473 pid_t pid;
474 int status;
476 while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) {
477 pthread_exited(pid);
478 if (WIFSIGNALED(status)) {
479 /* If a thread died due to a signal, send the same signal to
480 all other threads, including the main thread. */
481 pthread_kill_all_threads(WTERMSIG(status), 1);
482 _exit(0);
487 /* Try to free the resources of a thread when requested by pthread_join
488 or pthread_detach on a terminated thread. */
490 static void pthread_handle_free(pthread_t th_id)
492 pthread_handle handle = thread_handle(th_id);
493 pthread_descr th;
495 __pthread_lock(&handle->h_lock, NULL);
496 if (invalid_handle(handle, th_id)) {
497 /* pthread_reap_children has deallocated the thread already,
498 nothing needs to be done */
499 __pthread_unlock(&handle->h_lock);
500 return;
502 th = handle->h_descr;
503 if (th->p_exited) {
504 __pthread_unlock(&handle->h_lock);
505 pthread_free(th);
506 } else {
507 /* The Unix process of the thread is still running.
508 Mark the thread as detached so that the thread manager will
509 deallocate its resources when the Unix process exits. */
510 th->p_detached = 1;
511 __pthread_unlock(&handle->h_lock);
515 /* Send a signal to all running threads */
517 static void pthread_kill_all_threads(int sig, int main_thread_also)
519 pthread_descr th;
520 for (th = __pthread_main_thread->p_nextlive;
521 th != __pthread_main_thread;
522 th = th->p_nextlive) {
523 kill(th->p_pid, sig);
525 if (main_thread_also) {
526 kill(__pthread_main_thread->p_pid, sig);
530 /* Process-wide exit() */
532 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
534 pthread_descr th;
535 __pthread_exit_requested = 1;
536 __pthread_exit_code = exitcode;
537 /* Send the CANCEL signal to all running threads, including the main
538 thread, but excluding the thread from which the exit request originated
539 (that thread must complete the exit, e.g. calling atexit functions
540 and flushing stdio buffers). */
541 for (th = issuing_thread->p_nextlive;
542 th != issuing_thread;
543 th = th->p_nextlive) {
544 kill(th->p_pid, __pthread_sig_cancel);
546 /* Now, wait for all these threads, so that they don't become zombies
547 and their times are properly added to the thread manager's times. */
548 for (th = issuing_thread->p_nextlive;
549 th != issuing_thread;
550 th = th->p_nextlive) {
551 waitpid(th->p_pid, NULL, __WCLONE);
553 restart(issuing_thread);
554 _exit(0);
557 /* Handler for __pthread_sig_restart in thread manager thread */
559 void __pthread_manager_sighandler(int sig)
561 terminated_children = 1;
564 /* Adjust priority of thread manager so that it always run at a priority
565 higher than all threads */
567 void __pthread_manager_adjust_prio(int thread_prio)
569 struct sched_param param;
571 if (thread_prio <= __pthread_manager_thread.p_priority) return;
572 param.sched_priority =
573 thread_prio < __sched_get_priority_max(SCHED_FIFO)
574 ? thread_prio + 1 : thread_prio;
575 __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, &param);
576 __pthread_manager_thread.p_priority = thread_prio;