1 /* Linuxthreads - a simple clone()-based implementation of Posix */
2 /* threads for Linux. */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
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. */
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 */
24 #include <sys/poll.h> /* for poll */
25 #include <sys/mman.h> /* for mmap */
26 #include <sys/param.h>
28 #include <sys/wait.h> /* for waitpid macros */
29 #include <linux/tasks.h>
32 #include "internals.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
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
)
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
)
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);
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 */
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
);
116 /* Enter server loop */
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);
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
) {
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
);
146 pthread_handle_free(request
.req_args
.free
.thread_id
);
148 case REQ_PROCESS_EXIT
:
149 pthread_handle_exit(request
.req_thread
,
150 request
.req_args
.exit
.code
);
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
);
160 sem_post(request
.req_args
.post
);
163 /* Make gdb aware of new thread */
164 if (__pthread_threads_debug
&& __pthread_sig_debug
> 0)
165 raise(__pthread_sig_debug
);
166 restart(request
.req_thread
);
173 /* Process creation */
175 static int pthread_start_thread(void *arg
)
177 pthread_descr self
= (pthread_descr
) arg
;
178 struct pthread_request request
;
180 /* Initialize special thread_self processing, if any. */
181 #ifdef INIT_THREAD_SELF
182 INIT_THREAD_SELF(self
, self
->p_nr
);
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
) {
197 request
.req_thread
= self
;
198 request
.req_kind
= REQ_DEBUG
;
199 __libc_write(__pthread_manager_request
,
200 (char *) &request
, sizeof(request
));
203 /* Run the thread code */
204 outcome
= self
->p_start_args
.start_routine(THREAD_GETMEM(self
,
206 /* Exit with the given return value */
207 pthread_exit(outcome
);
211 static int pthread_allocate_stack(const pthread_attr_t
*attr
,
212 pthread_descr default_new_thread
,
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
;
222 size_t stacksize
, guardsize
;
224 if (attr
!= NULL
&& attr
->__stackaddr_set
)
226 /* The user provided a stack. */
228 (pthread_descr
) ((long)(attr
->__stackaddr
) & -sizeof(void *)) - 1;
229 new_thread_bottom
= (char *) attr
->__stackaddr
- attr
->__stacksize
;
235 /* Allocate space for stack and thread descriptor at default address */
236 new_thread
= default_new_thread
;
237 new_thread_bottom
= (char *) new_thread
- STACK_SIZE
;
238 if (mmap((caddr_t
)((char *)(new_thread
+ 1) - INITIAL_STACK_SIZE
),
239 INITIAL_STACK_SIZE
, PROT_READ
| PROT_WRITE
| PROT_EXEC
,
240 MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_FIXED
| MAP_GROWSDOWN
,
241 -1, 0) == MAP_FAILED
)
242 /* Bad luck, this segment is already mapped. */
244 /* We manage to get a stack. Now see whether we need a guard
245 and allocate it if necessary. Notice that the default
246 attributes (stack_size = STACK_SIZE - pagesize and
247 guardsize = pagesize) do not need a guard page, since
248 the RLIMIT_STACK soft limit prevents stacks from
249 running into one another. */
251 attr
->__guardsize
== 0 ||
252 (attr
->__guardsize
== pagesize
&&
253 attr
->__stacksize
== STACK_SIZE
- pagesize
))
255 /* We don't need a guard page. */
261 /* Put a bad page at the bottom of the stack */
262 stacksize
= roundup(attr
->__stacksize
, pagesize
);
263 if (stacksize
>= STACK_SIZE
- pagesize
)
264 stacksize
= STACK_SIZE
- pagesize
;
265 guardaddr
= (void *)new_thread
- stacksize
;
266 guardsize
= attr
->__guardsize
;
267 if (mmap ((caddr_t
) guardaddr
, guardsize
, 0, MAP_FIXED
, -1, 0)
270 /* We don't make this an error. */
276 *out_new_thread
= new_thread
;
277 *out_new_thread_bottom
= new_thread_bottom
;
278 *out_guardaddr
= guardaddr
;
279 *out_guardsize
= guardsize
;
283 static int pthread_handle_create(pthread_t
*thread
, const pthread_attr_t
*attr
,
284 void * (*start_routine
)(void *), void *arg
,
285 sigset_t
* mask
, int father_pid
)
289 pthread_descr new_thread
;
290 char * new_thread_bottom
;
291 pthread_t new_thread_id
;
292 char *guardaddr
= NULL
;
293 size_t guardsize
= 0;
294 int pagesize
= __getpagesize();
296 /* First check whether we have to change the policy and if yes, whether
297 we can do this. Normally this should be done by examining the
298 return value of the __sched_setscheduler call in pthread_start_thread
299 but this is hard to implement. FIXME */
300 if (attr
!= NULL
&& attr
->__schedpolicy
!= SCHED_OTHER
&& geteuid () != 0)
302 /* Find a free segment for the thread, and allocate a stack if needed */
303 for (sseg
= 2; ; sseg
++)
305 if (sseg
>= PTHREAD_THREADS_MAX
)
307 if (__pthread_handles
[sseg
].h_descr
!= NULL
)
309 if (pthread_allocate_stack(attr
, thread_segment(sseg
), pagesize
,
310 &new_thread
, &new_thread_bottom
,
311 &guardaddr
, &guardsize
) == 0)
314 /* Allocate new thread identifier */
315 pthread_threads_counter
+= PTHREAD_THREADS_MAX
;
316 new_thread_id
= sseg
+ pthread_threads_counter
;
317 /* Initialize the thread descriptor */
318 new_thread
->p_nextwaiting
= NULL
;
319 new_thread
->p_tid
= new_thread_id
;
320 new_thread
->p_priority
= 0;
321 new_thread
->p_lock
= &(__pthread_handles
[sseg
].h_lock
);
322 new_thread
->p_signal
= 0;
323 new_thread
->p_signal_jmp
= NULL
;
324 new_thread
->p_cancel_jmp
= NULL
;
325 new_thread
->p_terminated
= 0;
326 new_thread
->p_detached
= attr
== NULL
? 0 : attr
->__detachstate
;
327 new_thread
->p_exited
= 0;
328 new_thread
->p_retval
= NULL
;
329 new_thread
->p_joining
= NULL
;
330 new_thread
->p_cleanup
= NULL
;
331 new_thread
->p_cancelstate
= PTHREAD_CANCEL_ENABLE
;
332 new_thread
->p_canceltype
= PTHREAD_CANCEL_DEFERRED
;
333 new_thread
->p_canceled
= 0;
334 new_thread
->p_errnop
= &new_thread
->p_errno
;
335 new_thread
->p_errno
= 0;
336 new_thread
->p_h_errnop
= &new_thread
->p_h_errno
;
337 new_thread
->p_h_errno
= 0;
338 new_thread
->p_in_sighandler
= NULL
;
339 new_thread
->p_sigwaiting
= 0;
340 new_thread
->p_guardaddr
= guardaddr
;
341 new_thread
->p_guardsize
= guardsize
;
342 new_thread
->p_userstack
= attr
!= NULL
&& attr
->__stackaddr_set
;
343 memset (new_thread
->p_specific
, '\0',
344 PTHREAD_KEY_1STLEVEL_SIZE
* sizeof (new_thread
->p_specific
[0]));
345 new_thread
->p_self
= new_thread
;
346 new_thread
->p_nr
= sseg
;
347 /* Initialize the thread handle */
348 __pthread_init_lock(&__pthread_handles
[sseg
].h_lock
);
349 __pthread_handles
[sseg
].h_descr
= new_thread
;
350 __pthread_handles
[sseg
].h_bottom
= new_thread_bottom
;
351 /* Determine scheduling parameters for the thread */
352 new_thread
->p_start_args
.schedpolicy
= -1;
354 switch(attr
->__inheritsched
) {
355 case PTHREAD_EXPLICIT_SCHED
:
356 new_thread
->p_start_args
.schedpolicy
= attr
->__schedpolicy
;
357 memcpy (&new_thread
->p_start_args
.schedparam
, &attr
->__schedparam
,
358 sizeof (struct sched_param
));
360 case PTHREAD_INHERIT_SCHED
:
361 /* schedpolicy doesn't need to be set, only get priority */
362 __sched_getparam(father_pid
, &new_thread
->p_start_args
.schedparam
);
365 new_thread
->p_priority
=
366 new_thread
->p_start_args
.schedparam
.sched_priority
;
368 /* Finish setting up arguments to pthread_start_thread */
369 new_thread
->p_start_args
.start_routine
= start_routine
;
370 new_thread
->p_start_args
.arg
= arg
;
371 new_thread
->p_start_args
.mask
= *mask
;
372 /* Raise priority of thread manager if needed */
373 __pthread_manager_adjust_prio(new_thread
->p_priority
);
375 pid
= __clone(pthread_start_thread
, (void **) new_thread
,
376 CLONE_VM
| CLONE_FS
| CLONE_FILES
| CLONE_SIGHAND
|
380 __pthread_sig_cancel
, new_thread
);
381 /* Check if cloning succeeded */
383 /* Free the stack if we allocated it */
384 if (attr
== NULL
|| !attr
->__stackaddr_set
)
386 munmap((caddr_t
)((char *)(new_thread
+1) - INITIAL_STACK_SIZE
),
388 if (new_thread
->p_guardsize
!= 0)
389 munmap(new_thread
->p_guardaddr
, new_thread
->p_guardsize
);
391 __pthread_handles
[sseg
].h_descr
= NULL
;
392 __pthread_handles
[sseg
].h_bottom
= NULL
;
393 __pthread_handles_num
--;
396 /* Insert new thread in doubly linked list of active threads */
397 new_thread
->p_prevlive
= __pthread_main_thread
;
398 new_thread
->p_nextlive
= __pthread_main_thread
->p_nextlive
;
399 __pthread_main_thread
->p_nextlive
->p_prevlive
= new_thread
;
400 __pthread_main_thread
->p_nextlive
= new_thread
;
401 /* Set pid field of the new thread, in case we get there before the
403 new_thread
->p_pid
= pid
;
405 *thread
= new_thread_id
;
410 /* Try to free the resources of a thread when requested by pthread_join
411 or pthread_detach on a terminated thread. */
413 static void pthread_free(pthread_descr th
)
415 pthread_handle handle
;
416 ASSERT(th
->p_exited
);
417 /* Make the handle invalid */
418 handle
= thread_handle(th
->p_tid
);
419 __pthread_lock(&handle
->h_lock
, NULL
);
420 handle
->h_descr
= NULL
;
421 handle
->h_bottom
= (char *)(-1L);
422 __pthread_unlock(&handle
->h_lock
);
423 #ifdef FREE_THREAD_SELF
424 FREE_THREAD_SELF(th
, th
->p_nr
);
426 /* One fewer threads in __pthread_handles */
427 __pthread_handles_num
--;
428 /* If initial thread, nothing to free */
429 if (th
== &__pthread_initial_thread
) return;
430 if (!th
->p_userstack
)
432 /* Free the stack and thread descriptor area */
433 if (th
->p_guardsize
!= 0)
434 munmap(th
->p_guardaddr
, th
->p_guardsize
);
435 munmap((caddr_t
) ((char *)(th
+1) - STACK_SIZE
), STACK_SIZE
);
439 /* Handle threads that have exited */
441 static void pthread_exited(pid_t pid
)
445 /* Find thread with that pid */
446 for (th
= __pthread_main_thread
->p_nextlive
;
447 th
!= __pthread_main_thread
;
448 th
= th
->p_nextlive
) {
449 if (th
->p_pid
== pid
) {
450 /* Remove thread from list of active threads */
451 th
->p_nextlive
->p_prevlive
= th
->p_prevlive
;
452 th
->p_prevlive
->p_nextlive
= th
->p_nextlive
;
453 /* Mark thread as exited, and if detached, free its resources */
454 __pthread_lock(th
->p_lock
, NULL
);
456 detached
= th
->p_detached
;
457 __pthread_unlock(th
->p_lock
);
463 /* If all threads have exited and the main thread is pending on a
464 pthread_exit, wake up the main thread and terminate ourselves. */
465 if (main_thread_exiting
&&
466 __pthread_main_thread
->p_nextlive
== __pthread_main_thread
) {
467 restart(__pthread_main_thread
);
472 static void pthread_reap_children(void)
477 while ((pid
= __libc_waitpid(-1, &status
, WNOHANG
| __WCLONE
)) > 0) {
479 if (WIFSIGNALED(status
)) {
480 /* If a thread died due to a signal, send the same signal to
481 all other threads, including the main thread. */
482 pthread_kill_all_threads(WTERMSIG(status
), 1);
488 /* Try to free the resources of a thread when requested by pthread_join
489 or pthread_detach on a terminated thread. */
491 static void pthread_handle_free(pthread_t th_id
)
493 pthread_handle handle
= thread_handle(th_id
);
496 __pthread_lock(&handle
->h_lock
, NULL
);
497 if (invalid_handle(handle
, th_id
)) {
498 /* pthread_reap_children has deallocated the thread already,
499 nothing needs to be done */
500 __pthread_unlock(&handle
->h_lock
);
503 th
= handle
->h_descr
;
505 __pthread_unlock(&handle
->h_lock
);
508 /* The Unix process of the thread is still running.
509 Mark the thread as detached so that the thread manager will
510 deallocate its resources when the Unix process exits. */
512 __pthread_unlock(&handle
->h_lock
);
516 /* Send a signal to all running threads */
518 static void pthread_kill_all_threads(int sig
, int main_thread_also
)
521 for (th
= __pthread_main_thread
->p_nextlive
;
522 th
!= __pthread_main_thread
;
523 th
= th
->p_nextlive
) {
524 kill(th
->p_pid
, sig
);
526 if (main_thread_also
) {
527 kill(__pthread_main_thread
->p_pid
, sig
);
531 /* Process-wide exit() */
533 static void pthread_handle_exit(pthread_descr issuing_thread
, int exitcode
)
536 __pthread_exit_requested
= 1;
537 __pthread_exit_code
= exitcode
;
538 /* Send the CANCEL signal to all running threads, including the main
539 thread, but excluding the thread from which the exit request originated
540 (that thread must complete the exit, e.g. calling atexit functions
541 and flushing stdio buffers). */
542 for (th
= issuing_thread
->p_nextlive
;
543 th
!= issuing_thread
;
544 th
= th
->p_nextlive
) {
545 kill(th
->p_pid
, __pthread_sig_cancel
);
547 /* Now, wait for all these threads, so that they don't become zombies
548 and their times are properly added to the thread manager's times. */
549 for (th
= issuing_thread
->p_nextlive
;
550 th
!= issuing_thread
;
551 th
= th
->p_nextlive
) {
552 waitpid(th
->p_pid
, NULL
, __WCLONE
);
554 restart(issuing_thread
);
558 /* Handler for __pthread_sig_cancel in thread manager thread */
560 void __pthread_manager_sighandler(int sig
)
562 terminated_children
= 1;
565 /* Adjust priority of thread manager so that it always run at a priority
566 higher than all threads */
568 void __pthread_manager_adjust_prio(int thread_prio
)
570 struct sched_param param
;
572 if (thread_prio
<= __pthread_manager_thread
.p_priority
) return;
573 param
.sched_priority
=
574 thread_prio
< __sched_get_priority_max(SCHED_FIFO
)
575 ? thread_prio
+ 1 : thread_prio
;
576 __sched_setscheduler(__pthread_manager_thread
.p_pid
, SCHED_FIFO
, ¶m
);
577 __pthread_manager_thread
.p_priority
= thread_prio
;