]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/libpthread/src/manager.cc
update
[l4.git] / l4 / pkg / uclibc / lib / libpthread / src / manager.cc
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.                 */
14
15 /* The "thread manager" thread: manages creation and termination of threads */
16
17 #ifndef PT_EI
18 #define PT_EI inline
19 #endif
20
21 #include <assert.h>
22 #include <errno.h>
23 #include <stddef.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/mman.h>
29 #include <sys/time.h>
30 #include <locale.h>             /* for __uselocale */
31
32 #include <l4/sys/ipc.h>
33 #include <l4/re/env>
34 #include <l4/re/mem_alloc>
35 #include <l4/re/dataspace>
36 #include <l4/re/rm>
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>
42
43 extern "C" {
44 #include "pthread.h"
45 #include "internals.h"
46 #include "spinlock.h"
47 #include "restart.h"
48 #include "semaphore.h"
49 #include "l4.h"
50 #include <ldsodefs.h>
51 }
52
53 #include <pthread-l4.h>
54
55 #define USE_L4RE_FOR_STACK
56
57 #ifndef MIN
58 # define MIN(a,b) (((a) < (b)) ? (a) : (b))
59 #endif
60
61 extern "C" void __pthread_new_thread_entry(void);
62
63 #ifndef THREAD_SELF
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;
67 #endif
68
69 /* Number of active entries in __pthread_handles (used by gdb) */
70 __volatile__ int __pthread_handles_num = 2;
71
72 /* Whether to use debugger additional actions for thread creation
73    (set to 1 by gdb) */
74 __volatile__ int __pthread_threads_debug;
75
76 static pthread_descr manager_thread;
77
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. */
81
82 # define thread_segment(seq) NULL
83
84 /* Flag set in signal handler to record child termination */
85
86 static __volatile__ int terminated_children;
87
88 /* Flag set when the initial thread is blocked on pthread_exit waiting
89    for all other threads to terminate */
90
91 static int main_thread_exiting;
92
93 /* Counter used to generate unique thread identifier.
94    Thread identifier is pthread_threads_counter + segment. */
95
96 //l4/static pthread_t pthread_threads_counter;
97
98 /* Forward declarations */
99
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));
108
109 static void pthread_exited(pthread_descr th);
110
111 /* The server thread managing requests for thread creation and termination */
112
113 int
114 __attribute__ ((noreturn))
115 __pthread_manager(void *arg)
116 {
117   pthread_descr self = manager_thread = (pthread_descr)arg;
118   struct pthread_request request;
119
120 #ifdef USE_TLS
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);
125 #else
126 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
127 #endif
128 #endif
129   /* If we have special thread_self processing, initialize it.  */
130 #ifdef INIT_THREAD_SELF
131   INIT_THREAD_SELF(self, 1);
132 #endif
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;
137 #endif
138   /* Raise our priority to match that of main thread */
139   __pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
140
141   l4_umword_t src;
142   l4_msgtag_t tag = l4_msgtag(0, 0, 0, L4_MSGTAG_SCHEDULE);
143   int do_reply = 0;
144   /* Enter server loop */
145   while (1)
146     {
147       if (do_reply)
148         tag = l4_ipc_reply_and_wait(l4_utcb(), tag, &src, L4_IPC_NEVER);
149       else
150         tag = l4_ipc_wait(l4_utcb(), &src, L4_IPC_NEVER);
151
152       if (l4_msgtag_has_error(tag))
153         {
154           do_reply = 0;
155           continue;
156         }
157
158       memcpy(&request, l4_utcb_mr()->mr, sizeof(request));
159
160       do_reply = 0;
161       switch(request.req_kind)
162         {
163         case REQ_CREATE:
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);
169           do_reply = 1;
170           break;
171         case REQ_FREE:
172           pthread_handle_free(request.req_args.free.thread_id);
173           break;
174         case REQ_PROCESS_EXIT:
175           pthread_handle_exit(request.req_thread,
176               request.req_args.exit.code);
177           /* NOTREACHED */
178           break;
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
183              not do REQ_KICK. */
184           //l4/pthread_reap_children();
185
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. */
192           }
193           break;
194         case REQ_POST:
195           sem_post((sem_t*)request.req_args.post);
196           break;
197         case REQ_DEBUG:
198 #ifdef NOT_FOR_L4
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);
203 #else
204           do_reply = 1;
205 #endif
206           break;
207         case REQ_KICK:
208           /* This is just a prod to get the manager to reap some
209              threads right away, avoiding a potential delay at shutdown. */
210           break;
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);
215           do_reply = 1;
216           break;
217         case REQ_THREAD_EXIT:
218             {
219               l4_msgtag_t e;
220               L4::Cap<L4::Thread> c;
221
222               pthread_exited(request.req_thread);
223
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);
227
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);
231             }
232           break;
233         }
234       tag = l4_msgtag(0, 0, 0, L4_MSGTAG_SCHEDULE);
235     }
236 }
237
238 int __pthread_manager_event(void *arg)
239 {
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);
244 #endif
245
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));
250
251   return __pthread_manager(arg);
252 }
253
254 /* Process creation */
255
256 static int
257 __attribute__ ((noreturn))
258 pthread_start_thread(void *arg)
259 {
260   pthread_descr self = (pthread_descr) arg;
261 #ifdef USE_TLS
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);
266 #else
267 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
268 #endif
269 #endif
270
271 #ifdef NOT_FOR_L4
272   struct pthread_request request;
273 #endif
274   void * outcome;
275 #if HP_TIMING_AVAIL
276   hp_timing_t tmpclock;
277 #endif
278   /* Initialize special thread_self processing, if any.  */
279 #ifdef INIT_THREAD_SELF
280   INIT_THREAD_SELF(self, self->p_nr);
281 #endif
282 #if HP_TIMING_AVAIL
283   HP_TIMING_NOW (tmpclock);
284   THREAD_SETMEM (self, p_cpuclock_offset, tmpclock);
285 #endif
286
287 #ifdef NOT_FOR_L4
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 */
297     {
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);
302     }
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);
307 #else
308   /* Initialize __resp.  */
309   __resp = &self->p_res;
310 #endif
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)));
317     suspend(self);
318   }
319 #endif
320   /* Run the thread code */
321   outcome = self->p_start_args.start_routine(THREAD_GETMEM(self,
322                                                            p_start_args.arg));
323   /* Exit with the given return value */
324   __pthread_do_exit(outcome, (char *)CURRENT_STACK_FRAME);
325 }
326
327 #ifdef NOT_FOR_L4
328 static int
329 __attribute__ ((noreturn))
330 pthread_start_thread_event(void *arg)
331 {
332   pthread_descr self = (pthread_descr) arg;
333
334 #ifdef INIT_THREAD_SELF
335   INIT_THREAD_SELF(self, self->p_nr);
336 #endif
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));
344
345   /* Continue with the real function.  */
346   pthread_start_thread (arg);
347 }
348 #endif
349
350 #ifdef USE_L4RE_FOR_STACK
351 static int pthread_l4_free_stack(void *stack_addr, void *guardaddr)
352 {
353   L4Re::Env const *e = L4Re::Env::env();
354   int err;
355   L4::Cap<L4Re::Dataspace> ds;
356
357   err = e->rm()->detach(stack_addr, &ds);
358   if (err < 0)
359     return err;
360
361   if (ds.is_valid())
362     {
363       err = ds->release();
364       if (err < 0)
365         return err;
366     }
367
368   L4Re::Util::cap_alloc.free(ds);
369
370   return e->rm()->free_area((l4_addr_t)guardaddr);
371 }
372 #endif
373
374 static int pthread_allocate_stack(const pthread_attr_t *attr,
375                                   pthread_descr default_new_thread,
376                                   int pagesize,
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)
382 {
383   pthread_descr new_thread;
384   char * new_thread_bottom;
385   char * guardaddr;
386   size_t stacksize, guardsize;
387
388 #ifdef USE_TLS
389   /* TLS cannot work with fixed thread descriptor addresses.  */
390   assert (default_new_thread == NULL);
391 #endif
392
393   if (attr != NULL && attr->__stackaddr_set)
394     {
395 #ifdef _STACK_GROWS_UP
396       /* The user provided a stack. */
397 # ifdef USE_TLS
398       /* This value is not needed.  */
399       new_thread = (pthread_descr) attr->__stackaddr;
400       new_thread_bottom = (char *) new_thread;
401 # else
402       new_thread = (pthread_descr) attr->__stackaddr;
403       new_thread_bottom = (char *) (new_thread + 1);
404 # endif
405       guardaddr = attr->__stackaddr + attr->__stacksize;
406       guardsize = 0;
407 #else
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
417          value. */
418 # ifdef USE_TLS
419       new_thread = (pthread_descr) attr->__stackaddr;
420 # else
421       new_thread =
422         (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1;
423 # endif
424       new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize;
425       guardaddr = new_thread_bottom;
426       guardsize = 0;
427 #endif
428 #ifndef THREAD_SELF
429       __pthread_nonstandard_stacks = 1;
430 #endif
431 #ifndef USE_TLS
432       /* Clear the thread data structure.  */
433       memset (new_thread, '\0', sizeof (*new_thread));
434 #endif
435       stacksize = attr->__stacksize;
436     }
437   else
438     {
439       const size_t granularity = pagesize;
440       void *map_addr;
441
442       /* Allocate space for stack and thread descriptor at default address */
443       if (attr != NULL)
444         {
445           guardsize = page_roundup (attr->__guardsize, granularity);
446           stacksize = __pthread_max_stacksize - guardsize;
447           stacksize = MIN (stacksize,
448                            page_roundup (attr->__stacksize, granularity));
449         }
450       else
451         {
452           guardsize = granularity;
453           stacksize = __pthread_max_stacksize - guardsize;
454         }
455
456 #ifdef USE_L4RE_FOR_STACK
457       map_addr = 0;
458       L4Re::Env const *e = L4Re::Env::env();
459       long err;
460
461       if (e->rm()->reserve_area(&map_addr, stacksize + guardsize,
462                                 L4Re::Rm::Search_addr) < 0)
463         return -1;
464
465       guardaddr = (char*)map_addr;
466
467       L4::Cap<L4Re::Dataspace> ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
468       if (!ds.is_valid())
469         return -1;
470
471       err = e->mem_alloc()->alloc(stacksize, ds);
472
473       if (err < 0)
474         {
475           L4Re::Util::cap_alloc.free(ds);
476           e->rm()->free_area(l4_addr_t(map_addr));
477           return -1;
478         }
479
480       new_thread_bottom = (char *) map_addr + guardsize;
481       err = e->rm()->attach(&new_thread_bottom, stacksize, L4Re::Rm::In_area,
482                             ds, 0);
483
484       if (err < 0)
485         {
486           L4Re::Util::cap_alloc.free(ds);
487           e->rm()->free_area(l4_addr_t(map_addr));
488           return -1;
489         }
490 #else
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.  */
496         return -1;
497
498       guardaddr = (char *)map_addr;
499       if (guardsize > 0)
500         mprotect (guardaddr, guardsize, PROT_NONE);
501
502       new_thread_bottom = (char *) map_addr + guardsize;
503 #endif
504
505 #ifdef USE_TLS
506       new_thread = ((pthread_descr) (new_thread_bottom + stacksize));
507 #else
508       new_thread = ((pthread_descr) (new_thread_bottom + stacksize)) - 1;
509 #endif
510     }
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;
516   return 0;
517 }
518
519 static inline
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)
524 {
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>();
528   if (!_t.is_valid())
529     return ENOMEM;
530
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())
534     return ENOMEM;
535
536   int err = l4_error(e->factory()->create_thread(_t.get()));
537   if (err < 0)
538     return -err;
539
540   // needed by __alloc_thread_sem
541   thread->p_th_cap = _t.cap();
542
543   err = __alloc_thread_sem(thread, th_sem.get());
544   if (err < 0)
545     return -err;
546
547   thread->p_thsem_cap = th_sem.cap();
548
549   L4::Thread::Attr attr;
550   l4_utcb_t *nt_utcb = (l4_utcb_t*)thread->p_tid;
551
552   attr.bind(nt_utcb, L4Re::This_task);
553   attr.pager(e->rm());
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);
557
558   l4_utcb_tcr_u(nt_utcb)->user[0] = l4_addr_t(thread);
559
560
561   l4_umword_t *&_tos = (l4_umword_t*&)*tos;
562
563   *(--_tos) = l4_addr_t(thread);
564   *(--_tos) = 0; /* ret addr */
565   *(--_tos) = l4_addr_t(f);
566
567
568   _t->ex_regs(l4_addr_t(__pthread_new_thread_entry), l4_addr_t(_tos), 0);
569
570   if (!(create_flags & PTHREAD_L4_ATTR_NO_START))
571     {
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);
575     }
576
577   // release the automatic capabilities
578   _t.release();
579   th_sem.release();
580   return 0;
581 }
582
583 static int l4pthr_get_more_utcb()
584 {
585   using namespace L4Re;
586
587   l4_addr_t kumem = 0;
588   Env const *e = Env::env();
589
590   if (e->rm()->reserve_area(&kumem, L4_PAGESIZE,
591                             Rm::Reserved | Rm::Search_addr))
592     return 1;
593
594   if (l4_error(e->task()->add_ku_mem(l4_fpage(kumem, L4_PAGESHIFT,
595                                               L4_FPAGE_RW))))
596     {
597       e->rm()->free_area(kumem);
598       return 1;
599     }
600
601   __l4_add_utcbs(kumem, kumem + L4_PAGESIZE);
602   return 0;
603 }
604
605
606 static inline l4_utcb_t *mgr_alloc_utcb()
607 {
608   l4_utcb_t *new_utcb = __pthread_first_free_handle;
609   if (!new_utcb)
610     return 0;
611
612   __pthread_first_free_handle = (l4_utcb_t*)l4_utcb_tcr_u(new_utcb)->user[0];
613   return new_utcb;
614 }
615
616 static inline void mgr_free_utcb(l4_utcb_t *u)
617 {
618   if (!u)
619     return;
620
621   l4_utcb_tcr_u(u)->user[0] = l4_addr_t(__pthread_first_free_handle);
622   __pthread_first_free_handle = u;
623 }
624
625 int __pthread_start_manager(pthread_descr mgr)
626 {
627   int err;
628
629   mgr->p_tid = mgr_alloc_utcb();
630
631   err = __pthread_mgr_create_thread(mgr, &__pthread_manager_thread_tos,
632                                     __pthread_manager, -1, 0, l4_sched_cpu_set(0, ~0, 1));
633   if (err < 0)
634     {
635       fprintf(stderr, "ERROR: could not start pthread manager thread\n");
636       exit(100);
637     }
638
639   __pthread_manager_request = mgr->p_th_cap;
640   return 0;
641 }
642
643
644 static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
645                                  void * (*start_routine)(void *), void *arg)
646 {
647   int err;
648   pthread_descr new_thread;
649   char *stack_addr;
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;
655   int saved_errno = 0;
656
657 #ifdef USE_TLS
658   new_thread = (_pthread_descr_struct*)_dl_allocate_tls (NULL);
659   if (new_thread == NULL)
660     return EAGAIN;
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);
664 # endif
665 #else
666   /* Prevent warnings.  */
667   new_thread = NULL;
668 #endif
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)
675     return EPERM;
676 #endif
677   /* Find a free segment for the thread, and allocate a stack if needed */
678
679   if (__pthread_first_free_handle == 0 && l4pthr_get_more_utcb())
680     {
681 #ifdef USE_TLS
682 # if defined(TLS_DTV_AT_TP)
683           new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
684 # endif
685           _dl_deallocate_tls (new_thread, true);
686 #endif
687
688       return EAGAIN;
689     }
690
691   l4_utcb_t *new_utcb = mgr_alloc_utcb();
692   if (!new_utcb)
693     return EAGAIN;
694
695   new_thread_id = new_utcb;
696
697   if (pthread_allocate_stack(attr, thread_segment(sseg),
698                              pagesize, &stack_addr, &new_thread_bottom,
699                              &guardaddr, &guardsize, &stksize) == 0)
700     {
701 #ifdef USE_TLS
702       new_thread->p_stackaddr = stack_addr;
703 #else
704       new_thread = (pthread_descr) stack_addr;
705 #endif
706     }
707   else
708     {
709       mgr_free_utcb(new_utcb);
710       return EAGAIN;
711     }
712
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;
719 #endif
720 #if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
721   new_thread->p_multiple_threads = 1;
722 #endif
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;
730 #endif
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;
740   if (attr != NULL)
741     {
742       new_thread->p_detached = attr->__detachstate;
743       new_thread->p_userstack = attr->__stackaddr_set;
744
745       switch(attr->__inheritsched)
746         {
747         case PTHREAD_EXPLICIT_SCHED:
748           new_thread->p_sched_policy = attr->__schedpolicy;
749           new_thread->p_priority = attr->__schedparam.sched_priority;
750           break;
751         case PTHREAD_INHERIT_SCHED:
752           break;
753         }
754     }
755   int prio = -1;
756   /* Set the scheduling policy and priority for the new thread, if needed */
757   if (new_thread->p_sched_policy >= 0)
758     {
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);
764     }
765   else if (manager_thread->p_sched_policy > 3)
766     {
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);
770     }
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));
784   saved_errno = err;
785
786   /* Check if cloning succeeded */
787   if (err < 0) {
788     /* Free the stack if we allocated it */
789     if (attr == NULL || !attr->__stackaddr_set)
790       {
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
797 # ifdef USE_TLS
798         size_t stacksize = guardaddr - stack_addr;
799         munmap(stack_addr, stacksize + guardsize);
800 # else
801         
802         size_t stacksize = guardaddr - (char *)new_thread;
803         munmap(new_thread, stacksize + guardsize);
804 # endif
805 #else
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");
809 #else
810 # ifdef USE_TLS
811         size_t stacksize = stack_addr - new_thread_bottom;
812 # else
813         size_t stacksize = (char *)(new_thread+1) - new_thread_bottom;
814 # endif
815         munmap(new_thread_bottom - guardsize, guardsize + stacksize);
816 #endif
817 #endif
818       }
819 #ifdef USE_TLS
820 # if defined(TLS_DTV_AT_TP)
821     new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
822 # endif
823     _dl_deallocate_tls (new_thread, true);
824 #endif
825     mgr_free_utcb(new_utcb);
826     return saved_errno;
827   }
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
834      child starts. */
835   return 0;
836 }
837
838
839 /* Try to free the resources of a thread when requested by pthread_join
840    or pthread_detach on a terminated thread. */
841
842 static void pthread_free(pthread_descr th)
843 {
844   pthread_handle handle;
845   pthread_readlock_info *iter, *next;
846
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));
853
854     {
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);
858     }
859
860   /* One fewer threads in __pthread_handles */
861
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! */
865
866   for (iter = th->p_readlock_list; iter != NULL; iter = next)
867     {
868       next = iter->pr_next;
869       free(iter);
870     }
871
872   for (iter = th->p_readlock_free; iter != NULL; iter = next)
873     {
874       next = iter->pr_next;
875       free(iter);
876     }
877
878   /* If initial thread, nothing to free */
879   if (!th->p_userstack)
880     {
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
885 # ifdef USE_TLS
886       size_t stacksize = guardaddr - th->p_stackaddr;
887 # else
888       size_t stacksize = guardaddr - (char *)th;
889 # endif
890       guardaddr = (char *)th;
891 #else
892       /* Guardaddr is always set, even if guardsize is 0.  This allows
893          us to compute everything else.  */
894 # ifdef USE_TLS
895       //l4/size_t stacksize = th->p_stackaddr - guardaddr - guardsize;
896 # else
897       //l4/size_t stacksize = (char *)(th+1) - guardaddr - guardsize;
898 # endif
899 # ifdef NEED_SEPARATE_REGISTER_STACK
900       /* Take account of the register stack, which is below guardaddr.  */
901       guardaddr -= stacksize;
902       stacksize *= 2;
903 # endif
904 #endif
905 #ifdef USE_L4RE_FOR_STACK
906       pthread_l4_free_stack(guardaddr + guardsize, guardaddr);
907 #else
908       munmap(guardaddr, stacksize + guardsize);
909 #endif
910
911     }
912
913 #ifdef USE_TLS
914 # if defined(TLS_DTV_AT_TP)
915   th = (pthread_descr) ((char *) th + TLS_PRE_TCB_SIZE);
916 # endif
917   _dl_deallocate_tls (th, true);
918 #endif
919 }
920
921 /* Handle threads that have exited */
922
923 static void pthread_exited(pthread_descr th)
924 {
925   int detached;
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);
931   th->p_exited = 1;
932   /* If we have to signal this event do it now.  */
933   detached = th->p_detached;
934   __pthread_unlock(th->p_lock);
935   if (detached)
936     pthread_free(th);
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. */
943   }
944 }
945
946
947 /* Try to free the resources of a thread when requested by pthread_join
948    or pthread_detach on a terminated thread. */
949
950 static void pthread_handle_free(pthread_t th_id)
951 {
952   pthread_handle handle = thread_handle(th_id);
953   pthread_descr th;
954
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));
960     return;
961   }
962   th = handle_to_descr(handle);
963   __pthread_unlock(handle_to_lock(handle));
964   pthread_exited(th);
965   pthread_free(th);
966 }
967
968 /* Send a signal to all running threads */
969
970 #if 0
971 static void pthread_kill_all_threads(int main_thread_also)
972 {
973   UNIMPL("pthread_kill_all_threads");
974 #if 0
975   pthread_descr th;
976   for (th = __pthread_main_thread->p_nextlive;
977        th != __pthread_main_thread;
978        th = th->p_nextlive) {
979     kill(th->p_pid, sig);
980   }
981   if (main_thread_also) {
982     kill(__pthread_main_thread->p_pid, sig);
983   }
984 #endif
985 }
986 #endif
987
988 static void pthread_for_each_thread(void *arg,
989     void (*fn)(void *, pthread_descr))
990 {
991   pthread_descr th;
992
993   for (th = __pthread_main_thread->p_nextlive;
994        th != __pthread_main_thread;
995        th = th->p_nextlive) {
996     fn(arg, th);
997   }
998
999   fn(arg, __pthread_main_thread);
1000 }
1001
1002 /* Process-wide exit() */
1003
1004 static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
1005 {
1006   //l4/pthread_descr th;
1007   __pthread_exit_requested = 1;
1008   __pthread_exit_code = exitcode;
1009 #if 0
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.  */
1015   __flockfilelist();
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);
1024   }
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);
1031   }
1032   __fresetlockfiles();
1033 #endif
1034   restart(issuing_thread);
1035 #ifdef THIS_IS_THE_ORIGINAL
1036   _exit(0);
1037 #else
1038   // we do not do the exit path with kill and waitpid, so give the code here
1039   _exit(exitcode);
1040 #endif
1041 }
1042
1043 #if 0
1044 /* Handler for __pthread_sig_cancel in thread manager thread */
1045
1046 void __pthread_manager_sighandler(int sig)
1047 {
1048   int kick_manager = terminated_children == 0 && main_thread_exiting;
1049   terminated_children = 1;
1050
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. */
1057
1058   if (kick_manager) {
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)));
1064   }
1065 }
1066 #endif
1067 /* Adjust priority of thread manager so that it always run at a priority
1068    higher than all threads */
1069
1070 void __pthread_manager_adjust_prio(int thread_prio)
1071 {
1072   if (!manager_thread)
1073     return;
1074
1075   if (thread_prio <= manager_thread->p_priority)
1076     return;
1077
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;
1081 }