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 */
30 #include <locale.h> /* for __uselocale */
32 #include <l4/sys/ipc.h>
34 #include <l4/re/mem_alloc>
35 #include <l4/re/dataspace>
37 #include <l4/re/util/cap_alloc>
38 #include <l4/sys/capability>
39 #include <l4/sys/factory>
40 #include <l4/sys/scheduler>
41 #include <l4/sys/thread>
45 #include "internals.h"
48 #include "semaphore.h"
53 #include <pthread-l4.h>
55 #define USE_L4RE_FOR_STACK
58 # define MIN(a,b) (((a) < (b)) ? (a) : (b))
61 extern "C" void __pthread_new_thread_entry(void);
64 /* Indicate whether at least one thread has a user-defined stack (if 1),
65 or if all threads have stacks supplied by LinuxThreads (if 0). */
66 int __pthread_nonstandard_stacks;
69 /* Number of active entries in __pthread_handles (used by gdb) */
70 __volatile__ int __pthread_handles_num = 2;
72 /* Whether to use debugger additional actions for thread creation
74 __volatile__ int __pthread_threads_debug;
76 static pthread_descr manager_thread;
78 /* Mapping from stack segment to thread descriptor. */
79 /* Stack segment numbers are also indices into the __pthread_handles array. */
80 /* Stack segment number 0 is reserved for the initial thread. */
82 # define thread_segment(seq) NULL
84 /* Flag set in signal handler to record child termination */
86 static __volatile__ int terminated_children;
88 /* Flag set when the initial thread is blocked on pthread_exit waiting
89 for all other threads to terminate */
91 static int main_thread_exiting;
93 /* Counter used to generate unique thread identifier.
94 Thread identifier is pthread_threads_counter + segment. */
96 //l4/static pthread_t pthread_threads_counter;
98 /* Forward declarations */
100 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
101 void * (*start_routine)(void *), void *arg);
102 static void pthread_handle_free(pthread_t th_id);
103 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
104 __attribute__ ((noreturn));
105 //l4/static void pthread_kill_all_threads(int main_thread_also);
106 static void pthread_for_each_thread(void *arg,
107 void (*fn)(void *, pthread_descr));
109 static void pthread_exited(pthread_descr th);
111 /* The server thread managing requests for thread creation and termination */
114 __attribute__ ((noreturn))
115 __pthread_manager(void *arg)
117 pthread_descr self = manager_thread = (pthread_descr)arg;
118 struct pthread_request request;
121 # if defined(TLS_TCB_AT_TP)
122 TLS_INIT_TP(self, 0);
123 #elif defined(TLS_DTV_AT_TP)
124 TLS_INIT_TP(self + 1, 0);
126 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
129 /* If we have special thread_self processing, initialize it. */
130 #ifdef INIT_THREAD_SELF
131 INIT_THREAD_SELF(self, 1);
133 #if !(USE_TLS && HAVE___THREAD)
134 /* Set the error variable. */
135 self->p_errnop = &self->p_errno;
136 self->p_h_errnop = &self->p_h_errno;
138 /* Raise our priority to match that of main thread */
139 __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
142 l4_msgtag_t tag = l4_msgtag(0, 0, 0, L4_MSGTAG_SCHEDULE);
144 /* Enter server loop */
148 tag = l4_ipc_reply_and_wait(l4_utcb(), tag, &src, L4_IPC_NEVER);
150 tag = l4_ipc_wait(l4_utcb(), &src, L4_IPC_NEVER);
152 if (l4_msgtag_has_error(tag))
158 memcpy(&request, l4_utcb_mr()->mr, sizeof(request));
161 switch(request.req_kind)
164 request.req_thread->p_retcode =
165 pthread_handle_create((pthread_t *) &request.req_thread->p_retval,
166 request.req_args.create.attr,
167 request.req_args.create.fn,
168 request.req_args.create.arg);
172 pthread_handle_free(request.req_args.free.thread_id);
174 case REQ_PROCESS_EXIT:
175 pthread_handle_exit(request.req_thread,
176 request.req_args.exit.code);
179 case REQ_MAIN_THREAD_EXIT:
180 main_thread_exiting = 1;
181 /* Reap children in case all other threads died and the signal handler
182 went off before we set main_thread_exiting to 1, and therefore did
184 //l4/pthread_reap_children();
186 if (__pthread_main_thread->p_nextlive == __pthread_main_thread) {
187 restart(__pthread_main_thread);
188 /* The main thread will now call exit() which will trigger an
189 __on_exit handler, which in turn will send REQ_PROCESS_EXIT
190 to the thread manager. In case you are wondering how the
191 manager terminates from its loop here. */
195 sem_post((sem_t*)request.req_args.post);
199 /* Make gdb aware of new thread and gdb will restart the
200 new thread when it is ready to handle the new thread. */
201 if (__pthread_threads_debug && __pthread_sig_debug > 0)
202 raise(__pthread_sig_debug);
208 /* This is just a prod to get the manager to reap some
209 threads right away, avoiding a potential delay at shutdown. */
211 case REQ_FOR_EACH_THREAD:
212 pthread_for_each_thread(request.req_args.for_each.arg,
213 request.req_args.for_each.fn);
214 restart(request.req_thread);
217 case REQ_THREAD_EXIT:
220 L4::Cap<L4::Thread> c;
222 pthread_exited(request.req_thread);
224 c = L4::Cap<L4::Thread>(request.req_thread->p_thsem_cap);
225 e = L4::Cap<L4::Task>(L4Re::This_task)
226 ->unmap(c.fpage(), L4_FP_ALL_SPACES);
228 c = L4::Cap<L4::Thread>(request.req_thread->p_th_cap);
229 e = L4::Cap<L4::Task>(L4Re::This_task)
230 ->unmap(c.fpage(), L4_FP_ALL_SPACES);
234 tag = l4_msgtag(0, 0, 0, L4_MSGTAG_SCHEDULE);
238 int __pthread_manager_event(void *arg)
240 pthread_descr self = (pthread_descr)arg;
241 /* If we have special thread_self processing, initialize it. */
242 #ifdef INIT_THREAD_SELF
243 INIT_THREAD_SELF(self, 1);
246 /* Get the lock the manager will free once all is correctly set up. */
247 __pthread_lock (THREAD_GETMEM(self, p_lock), NULL);
248 /* Free it immediately. */
249 __pthread_unlock (THREAD_GETMEM(self, p_lock));
251 return __pthread_manager(arg);
254 /* Process creation */
257 __attribute__ ((noreturn))
258 pthread_start_thread(void *arg)
260 pthread_descr self = (pthread_descr) arg;
262 # if defined(TLS_TCB_AT_TP)
263 TLS_INIT_TP(self, 0);
264 #elif defined(TLS_DTV_AT_TP)
265 TLS_INIT_TP(self + 1, 0);
267 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
272 struct pthread_request request;
276 hp_timing_t tmpclock;
278 /* Initialize special thread_self processing, if any. */
279 #ifdef INIT_THREAD_SELF
280 INIT_THREAD_SELF(self, self->p_nr);
283 HP_TIMING_NOW (tmpclock);
284 THREAD_SETMEM (self, p_cpuclock_offset, tmpclock);
288 /* Set the scheduling policy and priority for the new thread, if needed */
289 if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0)
290 /* Explicit scheduling attributes were provided: apply them */
291 __sched_setscheduler(THREAD_GETMEM(self, p_pid),
292 THREAD_GETMEM(self, p_start_args.schedpolicy),
293 &self->p_start_args.schedparam);
294 else if (manager_thread->p_priority > 0)
295 /* Default scheduling required, but thread manager runs in realtime
296 scheduling: switch new thread to SCHED_OTHER policy */
298 struct sched_param default_params;
299 default_params.sched_priority = 0;
300 __sched_setscheduler(THREAD_GETMEM(self, p_pid),
301 SCHED_OTHER, &default_params);
303 #if !(USE_TLS && HAVE___THREAD)
304 /* Initialize thread-locale current locale to point to the global one.
305 With __thread support, the variable's initializer takes care of this. */
306 __uselocale (LC_GLOBAL_LOCALE);
308 /* Initialize __resp. */
309 __resp = &self->p_res;
311 /* Make gdb aware of new thread */
312 if (__pthread_threads_debug && __pthread_sig_debug > 0) {
313 request.req_thread = self;
314 request.req_kind = REQ_DEBUG;
315 TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request,
316 (char *) &request, sizeof(request)));
320 /* Run the thread code */
321 outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
323 /* Exit with the given return value */
324 __pthread_do_exit(outcome, (char *)CURRENT_STACK_FRAME);
329 __attribute__ ((noreturn))
330 pthread_start_thread_event(void *arg)
332 pthread_descr self = (pthread_descr) arg;
334 #ifdef INIT_THREAD_SELF
335 INIT_THREAD_SELF(self, self->p_nr);
337 /* Make sure our pid field is initialized, just in case we get there
338 before our father has initialized it. */
339 THREAD_SETMEM(self, p_pid, __getpid());
340 /* Get the lock the manager will free once all is correctly set up. */
341 __pthread_lock (THREAD_GETMEM(self, p_lock), NULL);
342 /* Free it immediately. */
343 __pthread_unlock (THREAD_GETMEM(self, p_lock));
345 /* Continue with the real function. */
346 pthread_start_thread (arg);
350 #ifdef USE_L4RE_FOR_STACK
351 static int pthread_l4_free_stack(void *stack_addr, void *guardaddr)
353 L4Re::Env const *e = L4Re::Env::env();
355 L4::Cap<L4Re::Dataspace> ds;
357 err = e->rm()->detach(stack_addr, &ds);
368 L4Re::Util::cap_alloc.free(ds);
370 return e->rm()->free_area((l4_addr_t)guardaddr);
374 static int pthread_allocate_stack(const pthread_attr_t *attr,
375 pthread_descr default_new_thread,
377 char ** out_new_thread,
378 char ** out_new_thread_bottom,
379 char ** out_guardaddr,
380 size_t * out_guardsize,
381 size_t * out_stacksize)
383 pthread_descr new_thread;
384 char * new_thread_bottom;
386 size_t stacksize, guardsize;
389 /* TLS cannot work with fixed thread descriptor addresses. */
390 assert (default_new_thread == NULL);
393 if (attr != NULL && attr->__stackaddr_set)
395 #ifdef _STACK_GROWS_UP
396 /* The user provided a stack. */
398 /* This value is not needed. */
399 new_thread = (pthread_descr) attr->__stackaddr;
400 new_thread_bottom = (char *) new_thread;
402 new_thread = (pthread_descr) attr->__stackaddr;
403 new_thread_bottom = (char *) (new_thread + 1);
405 guardaddr = attr->__stackaddr + attr->__stacksize;
408 /* The user provided a stack. For now we interpret the supplied
409 address as 1 + the highest addr. in the stack segment. If a
410 separate register stack is needed, we place it at the low end
411 of the segment, relying on the associated stacksize to
412 determine the low end of the segment. This differs from many
413 (but not all) other pthreads implementations. The intent is
414 that on machines with a single stack growing toward higher
415 addresses, stackaddr would be the lowest address in the stack
416 segment, so that it is consistently close to the initial sp
419 new_thread = (pthread_descr) attr->__stackaddr;
422 (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
424 new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
425 guardaddr = new_thread_bottom;
429 __pthread_nonstandard_stacks = 1;
432 /* Clear the thread data structure. */
433 memset (new_thread, '\0', sizeof (*new_thread));
435 stacksize = attr->__stacksize;
439 const size_t granularity = pagesize;
442 /* Allocate space for stack and thread descriptor at default address */
445 guardsize = page_roundup (attr->__guardsize, granularity);
446 stacksize = __pthread_max_stacksize - guardsize;
447 stacksize = MIN (stacksize,
448 page_roundup (attr->__stacksize, granularity));
452 guardsize = granularity;
453 stacksize = __pthread_max_stacksize - guardsize;
456 #ifdef USE_L4RE_FOR_STACK
458 L4Re::Env const *e = L4Re::Env::env();
461 if (e->rm()->reserve_area(&map_addr, stacksize + guardsize,
462 L4Re::Rm::Search_addr) < 0)
465 guardaddr = (char*)map_addr;
467 L4::Cap<L4Re::Dataspace> ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
471 err = e->mem_alloc()->alloc(stacksize, ds);
475 L4Re::Util::cap_alloc.free(ds);
476 e->rm()->free_area(l4_addr_t(map_addr));
480 new_thread_bottom = (char *) map_addr + guardsize;
481 err = e->rm()->attach(&new_thread_bottom, stacksize, L4Re::Rm::In_area,
486 L4Re::Util::cap_alloc.free(ds);
487 e->rm()->free_area(l4_addr_t(map_addr));
491 map_addr = mmap(NULL, stacksize + guardsize,
492 PROT_READ | PROT_WRITE | PROT_EXEC,
493 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
494 if (map_addr == MAP_FAILED)
495 /* No more memory available. */
498 guardaddr = (char *)map_addr;
500 mprotect (guardaddr, guardsize, PROT_NONE);
502 new_thread_bottom = (char *) map_addr + guardsize;
506 new_thread = ((pthread_descr) (new_thread_bottom + stacksize));
508 new_thread = ((pthread_descr) (new_thread_bottom + stacksize)) - 1;
511 *out_new_thread = (char *) new_thread;
512 *out_new_thread_bottom = new_thread_bottom;
513 *out_guardaddr = guardaddr;
514 *out_guardsize = guardsize;
515 *out_stacksize = stacksize;
520 int __pthread_mgr_create_thread(pthread_descr thread, char **tos,
521 int (*f)(void*), int prio,
522 unsigned create_flags,
523 l4_sched_cpu_set_t const &affinity)
525 using namespace L4Re;
526 Env const *e = Env::env();
527 L4Re::Util::Auto_cap<L4::Thread>::Cap _t = L4Re::Util::cap_alloc.alloc<L4::Thread>();
531 L4Re::Util::Auto_cap<Th_sem_cap>::Cap th_sem
532 = L4Re::Util::cap_alloc.alloc<Th_sem_cap>();
533 if (!th_sem.is_valid())
536 int err = l4_error(e->factory()->create_thread(_t.get()));
540 // needed by __alloc_thread_sem
541 thread->p_th_cap = _t.cap();
543 err = __alloc_thread_sem(thread, th_sem.get());
547 thread->p_thsem_cap = th_sem.cap();
549 L4::Thread::Attr attr;
550 l4_utcb_t *nt_utcb = (l4_utcb_t*)thread->p_tid;
552 attr.bind(nt_utcb, L4Re::This_task);
554 attr.exc_handler(e->rm());
555 if ((err = l4_error(_t->control(attr))) < 0)
556 fprintf(stderr, "ERROR: l4 thread control returned: %d\n", err);
558 l4_utcb_tcr_u(nt_utcb)->user[0] = l4_addr_t(thread);
561 l4_umword_t *&_tos = (l4_umword_t*&)*tos;
563 *(--_tos) = l4_addr_t(thread);
564 *(--_tos) = 0; /* ret addr */
565 *(--_tos) = l4_addr_t(f);
568 _t->ex_regs(l4_addr_t(__pthread_new_thread_entry), l4_addr_t(_tos), 0);
570 if (!(create_flags & PTHREAD_L4_ATTR_NO_START))
572 l4_sched_param_t sp = l4_sched_param(prio >= 0 ? prio : 2);
573 sp.affinity = affinity;
574 e->scheduler()->run_thread(_t.get(), sp);
577 // release the automatic capabilities
583 static int l4pthr_get_more_utcb()
585 using namespace L4Re;
588 Env const *e = Env::env();
590 if (e->rm()->reserve_area(&kumem, L4_PAGESIZE,
591 Rm::Reserved | Rm::Search_addr))
594 if (l4_error(e->task()->add_ku_mem(l4_fpage(kumem, L4_PAGESHIFT,
597 e->rm()->free_area(kumem);
601 __l4_add_utcbs(kumem, kumem + L4_PAGESIZE);
606 static inline l4_utcb_t *mgr_alloc_utcb()
608 l4_utcb_t *new_utcb = __pthread_first_free_handle;
612 __pthread_first_free_handle = (l4_utcb_t*)l4_utcb_tcr_u(new_utcb)->user[0];
616 static inline void mgr_free_utcb(l4_utcb_t *u)
621 l4_utcb_tcr_u(u)->user[0] = l4_addr_t(__pthread_first_free_handle);
622 __pthread_first_free_handle = u;
625 int __pthread_start_manager(pthread_descr mgr)
629 mgr->p_tid = mgr_alloc_utcb();
631 err = __pthread_mgr_create_thread(mgr, &__pthread_manager_thread_tos,
632 __pthread_manager, -1, 0, l4_sched_cpu_set(0, ~0, 1));
635 fprintf(stderr, "ERROR: could not start pthread manager thread\n");
639 __pthread_manager_request = mgr->p_th_cap;
644 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
645 void * (*start_routine)(void *), void *arg)
648 pthread_descr new_thread;
650 char * new_thread_bottom;
651 pthread_t new_thread_id;
652 char *guardaddr = NULL;
653 size_t guardsize = 0, stksize = 0;
654 int pagesize = L4_PAGESIZE;
658 new_thread = (_pthread_descr_struct*)_dl_allocate_tls (NULL);
659 if (new_thread == NULL)
661 # if defined(TLS_DTV_AT_TP)
662 /* pthread_descr is below TP. */
663 new_thread = (pthread_descr) ((char *) new_thread - TLS_PRE_TCB_SIZE);
666 /* Prevent warnings. */
669 #ifdef __NOT_FOR_L4__
670 /* First check whether we have to change the policy and if yes, whether
671 we can do this. Normally this should be done by examining the
672 return value of the __sched_setscheduler call in pthread_start_thread
673 but this is hard to implement. FIXME */
674 if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0)
677 /* Find a free segment for the thread, and allocate a stack if needed */
679 if (__pthread_first_free_handle == 0 && l4pthr_get_more_utcb())
682 # if defined(TLS_DTV_AT_TP)
683 new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
685 _dl_deallocate_tls (new_thread, true);
691 l4_utcb_t *new_utcb = mgr_alloc_utcb();
695 new_thread_id = new_utcb;
697 if (pthread_allocate_stack(attr, thread_segment(sseg),
698 pagesize, &stack_addr, &new_thread_bottom,
699 &guardaddr, &guardsize, &stksize) == 0)
702 new_thread->p_stackaddr = stack_addr;
704 new_thread = (pthread_descr) stack_addr;
709 mgr_free_utcb(new_utcb);
713 /* Allocate new thread identifier */
714 /* Initialize the thread descriptor. Elements which have to be
715 initialized to zero already have this value. */
716 #if !defined USE_TLS || !TLS_DTV_AT_TP
717 new_thread->p_header.data.tcb = new_thread;
718 new_thread->p_header.data.self = new_thread;
720 #if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
721 new_thread->p_multiple_threads = 1;
723 new_thread->p_tid = new_thread_id;
724 new_thread->p_lock = handle_to_lock(new_utcb);
725 new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
726 new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
727 #if !(USE_TLS && HAVE___THREAD)
728 new_thread->p_errnop = &new_thread->p_errno;
729 new_thread->p_h_errnop = &new_thread->p_h_errno;
731 new_thread->p_guardaddr = guardaddr;
732 new_thread->p_guardsize = guardsize;
733 new_thread->p_inheritsched = attr ? attr->__inheritsched : 0;
734 new_thread->p_alloca_cutoff = stksize / 4 > __MAX_ALLOCA_CUTOFF
735 ? __MAX_ALLOCA_CUTOFF : stksize / 4;
736 /* Initialize the thread handle */
737 __pthread_init_lock(handle_to_lock(new_utcb));
738 /* Determine scheduling parameters for the thread */
739 new_thread->p_sched_policy = -1;
742 new_thread->p_detached = attr->__detachstate;
743 new_thread->p_userstack = attr->__stackaddr_set;
745 switch(attr->__inheritsched)
747 case PTHREAD_EXPLICIT_SCHED:
748 new_thread->p_sched_policy = attr->__schedpolicy;
749 new_thread->p_priority = attr->__schedparam.sched_priority;
751 case PTHREAD_INHERIT_SCHED:
756 /* Set the scheduling policy and priority for the new thread, if needed */
757 if (new_thread->p_sched_policy >= 0)
759 /* Explicit scheduling attributes were provided: apply them */
760 prio = __pthread_l4_getprio(new_thread->p_sched_policy,
761 new_thread->p_priority);
762 /* Raise priority of thread manager if needed */
763 __pthread_manager_adjust_prio(prio);
765 else if (manager_thread->p_sched_policy > 3)
767 /* Default scheduling required, but thread manager runs in realtime
768 scheduling: switch new thread to SCHED_OTHER policy */
769 prio = __pthread_l4_getprio(SCHED_OTHER, 0);
771 /* Finish setting up arguments to pthread_start_thread */
772 new_thread->p_start_args.start_routine = start_routine;
773 new_thread->p_start_args.arg = arg;
774 /* Make the new thread ID available already now. If any of the later
775 functions fail we return an error value and the caller must not use
776 the stored thread ID. */
777 *thread = new_thread_id;
778 /* Do the cloning. We have to use two different functions depending
779 on whether we are debugging or not. */
780 err = __pthread_mgr_create_thread(new_thread, &stack_addr,
781 pthread_start_thread, prio,
782 attr ? attr->create_flags : 0,
783 attr ? attr->affinity : l4_sched_cpu_set(0, ~0, 1));
786 /* Check if cloning succeeded */
788 /* Free the stack if we allocated it */
789 if (attr == NULL || !attr->__stackaddr_set)
791 #ifdef NEED_SEPARATE_REGISTER_STACK
792 size_t stacksize = ((char *)(new_thread->p_guardaddr)
793 - new_thread_bottom);
794 munmap((caddr_t)new_thread_bottom,
795 2 * stacksize + new_thread->p_guardsize);
796 #elif _STACK_GROWS_UP
798 size_t stacksize = guardaddr - stack_addr;
799 munmap(stack_addr, stacksize + guardsize);
802 size_t stacksize = guardaddr - (char *)new_thread;
803 munmap(new_thread, stacksize + guardsize);
806 #ifdef USE_L4RE_FOR_STACK
807 if (pthread_l4_free_stack(new_thread_bottom, guardaddr))
808 fprintf(stderr, "ERROR: failed to free stack\n");
811 size_t stacksize = stack_addr - new_thread_bottom;
813 size_t stacksize = (char *)(new_thread+1) - new_thread_bottom;
815 munmap(new_thread_bottom - guardsize, guardsize + stacksize);
820 # if defined(TLS_DTV_AT_TP)
821 new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
823 _dl_deallocate_tls (new_thread, true);
825 mgr_free_utcb(new_utcb);
828 /* Insert new thread in doubly linked list of active threads */
829 new_thread->p_prevlive = __pthread_main_thread;
830 new_thread->p_nextlive = __pthread_main_thread->p_nextlive;
831 __pthread_main_thread->p_nextlive->p_prevlive = new_thread;
832 __pthread_main_thread->p_nextlive = new_thread;
833 /* Set pid field of the new thread, in case we get there before the
839 /* Try to free the resources of a thread when requested by pthread_join
840 or pthread_detach on a terminated thread. */
842 static void pthread_free(pthread_descr th)
844 pthread_handle handle;
845 pthread_readlock_info *iter, *next;
847 ASSERT(th->p_exited);
848 /* Make the handle invalid */
849 handle = thread_handle(th->p_tid);
850 __pthread_lock(handle_to_lock(handle), NULL);
851 mgr_free_utcb(handle);
852 __pthread_unlock(handle_to_lock(handle));
855 // free the semaphore and the thread
856 L4Re::Util::Auto_cap<void>::Cap s = L4::Cap<void>(th->p_thsem_cap);
857 L4Re::Util::Auto_cap<void>::Cap t = L4::Cap<void>(th->p_th_cap);
860 /* One fewer threads in __pthread_handles */
862 /* Destroy read lock list, and list of free read lock structures.
863 If the former is not empty, it means the thread exited while
864 holding read locks! */
866 for (iter = th->p_readlock_list; iter != NULL; iter = next)
868 next = iter->pr_next;
872 for (iter = th->p_readlock_free; iter != NULL; iter = next)
874 next = iter->pr_next;
878 /* If initial thread, nothing to free */
879 if (!th->p_userstack)
881 size_t guardsize = th->p_guardsize;
882 /* Free the stack and thread descriptor area */
883 char *guardaddr = (char*)th->p_guardaddr;
884 #ifdef _STACK_GROWS_UP
886 size_t stacksize = guardaddr - th->p_stackaddr;
888 size_t stacksize = guardaddr - (char *)th;
890 guardaddr = (char *)th;
892 /* Guardaddr is always set, even if guardsize is 0. This allows
893 us to compute everything else. */
895 //l4/size_t stacksize = th->p_stackaddr - guardaddr - guardsize;
897 //l4/size_t stacksize = (char *)(th+1) - guardaddr - guardsize;
899 # ifdef NEED_SEPARATE_REGISTER_STACK
900 /* Take account of the register stack, which is below guardaddr. */
901 guardaddr -= stacksize;
905 #ifdef USE_L4RE_FOR_STACK
906 pthread_l4_free_stack(guardaddr + guardsize, guardaddr);
908 munmap(guardaddr, stacksize + guardsize);
914 # if defined(TLS_DTV_AT_TP)
915 th = (pthread_descr) ((char *) th + TLS_PRE_TCB_SIZE);
917 _dl_deallocate_tls (th, true);
921 /* Handle threads that have exited */
923 static void pthread_exited(pthread_descr th)
926 /* Remove thread from list of active threads */
927 th->p_nextlive->p_prevlive = th->p_prevlive;
928 th->p_prevlive->p_nextlive = th->p_nextlive;
929 /* Mark thread as exited, and if detached, free its resources */
930 __pthread_lock(th->p_lock, NULL);
932 /* If we have to signal this event do it now. */
933 detached = th->p_detached;
934 __pthread_unlock(th->p_lock);
937 /* If all threads have exited and the main thread is pending on a
938 pthread_exit, wake up the main thread and terminate ourselves. */
939 if (main_thread_exiting &&
940 __pthread_main_thread->p_nextlive == __pthread_main_thread) {
941 restart(__pthread_main_thread);
942 /* Same logic as REQ_MAIN_THREAD_EXIT. */
947 /* Try to free the resources of a thread when requested by pthread_join
948 or pthread_detach on a terminated thread. */
950 static void pthread_handle_free(pthread_t th_id)
952 pthread_handle handle = thread_handle(th_id);
955 __pthread_lock(handle_to_lock(handle), NULL);
956 if (nonexisting_handle(handle, th_id)) {
957 /* pthread_reap_children has deallocated the thread already,
958 nothing needs to be done */
959 __pthread_unlock(handle_to_lock(handle));
962 th = handle_to_descr(handle);
963 __pthread_unlock(handle_to_lock(handle));
968 /* Send a signal to all running threads */
971 static void pthread_kill_all_threads(int main_thread_also)
973 UNIMPL("pthread_kill_all_threads");
976 for (th = __pthread_main_thread->p_nextlive;
977 th != __pthread_main_thread;
978 th = th->p_nextlive) {
979 kill(th->p_pid, sig);
981 if (main_thread_also) {
982 kill(__pthread_main_thread->p_pid, sig);
988 static void pthread_for_each_thread(void *arg,
989 void (*fn)(void *, pthread_descr))
993 for (th = __pthread_main_thread->p_nextlive;
994 th != __pthread_main_thread;
995 th = th->p_nextlive) {
999 fn(arg, __pthread_main_thread);
1002 /* Process-wide exit() */
1004 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
1006 //l4/pthread_descr th;
1007 __pthread_exit_requested = 1;
1008 __pthread_exit_code = exitcode;
1010 /* A forced asynchronous cancellation follows. Make sure we won't
1011 get stuck later in the main thread with a system lock being held
1012 by one of the cancelled threads. Ideally one would use the same
1013 code as in pthread_atfork(), but we can't distinguish system and
1014 user handlers there. */
1016 /* Send the CANCEL signal to all running threads, including the main
1017 thread, but excluding the thread from which the exit request originated
1018 (that thread must complete the exit, e.g. calling atexit functions
1019 and flushing stdio buffers). */
1020 for (th = issuing_thread->p_nextlive;
1021 th != issuing_thread;
1022 th = th->p_nextlive) {
1023 kill(th->p_pid, __pthread_sig_cancel);
1025 /* Now, wait for all these threads, so that they don't become zombies
1026 and their times are properly added to the thread manager's times. */
1027 for (th = issuing_thread->p_nextlive;
1028 th != issuing_thread;
1029 th = th->p_nextlive) {
1030 waitpid(th->p_pid, NULL, __WCLONE);
1032 __fresetlockfiles();
1034 restart(issuing_thread);
1035 #ifdef THIS_IS_THE_ORIGINAL
1038 // we do not do the exit path with kill and waitpid, so give the code here
1044 /* Handler for __pthread_sig_cancel in thread manager thread */
1046 void __pthread_manager_sighandler(int sig)
1048 int kick_manager = terminated_children == 0 && main_thread_exiting;
1049 terminated_children = 1;
1051 /* If the main thread is terminating, kick the thread manager loop
1052 each time some threads terminate. This eliminates a two second
1053 shutdown delay caused by the thread manager sleeping in the
1054 call to __poll(). Instead, the thread manager is kicked into
1055 action, reaps the outstanding threads and resumes the main thread
1056 so that it can complete the shutdown. */
1059 struct pthread_request request;
1060 request.req_thread = 0;
1061 request.req_kind = REQ_KICK;
1062 TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request,
1063 (char *) &request, sizeof(request)));
1067 /* Adjust priority of thread manager so that it always run at a priority
1068 higher than all threads */
1070 void __pthread_manager_adjust_prio(int thread_prio)
1072 if (!manager_thread)
1075 if (thread_prio <= manager_thread->p_priority)
1078 l4_sched_param_t sp = l4_sched_param(thread_prio, 0);
1079 L4Re::Env::env()->scheduler()->run_thread(L4::Cap<L4::Thread>(manager_thread->p_th_cap), sp);
1080 manager_thread->p_priority = thread_prio;