/* Start the signal thread listening on the message port. */
- err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
- assert_perror (err);
+ if (__hurd_threadvar_stack_mask == 0)
+ {
+ err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
+ assert_perror (err);
- stacksize = __vm_page_size * 8; /* Small stack for signal thread. */
- err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread,
- _hurd_msgport_receive,
- (vm_address_t *) &__hurd_sigthread_stack_base,
- &stacksize);
- assert_perror (err);
+ stacksize = ~__hurd_threadvar_stack_mask + 1;
+ stacksize = __vm_page_size * 8; /* Small stack for signal thread. */
+ err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread,
+ _hurd_msgport_receive,
+ (vm_address_t *) &__hurd_sigthread_stack_base,
+ &stacksize);
+ assert_perror (err);
- __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
- __hurd_sigthread_variables =
- malloc (__hurd_threadvar_max * sizeof (unsigned long int));
- if (__hurd_sigthread_variables == NULL)
- __libc_fatal ("hurd: Can't allocate thread variables for signal thread\n");
+ __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
+ __hurd_sigthread_variables =
+ malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+ if (__hurd_sigthread_variables == NULL)
+ __libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
- /* Reinitialize the MiG support routines so they will use a per-thread
- variable for the cached reply port. */
- __mig_init ((void *) __hurd_sigthread_stack_base);
+ /* Reinitialize the MiG support routines so they will use a per-thread
+ variable for the cached reply port. */
+ __mig_init ((void *) __hurd_sigthread_stack_base);
- err = __thread_resume (_hurd_msgport_thread);
- assert_perror (err);
+ err = __thread_resume (_hurd_msgport_thread);
+ assert_perror (err);
+ }
+ else
+ {
+ /* When cthreads is being used, we need to make the signal thread a
+ proper cthread. Otherwise it cannot use mutex_lock et al, which
+ will be the cthreads versions. Various of the message port RPC
+ handlers need to take locks, so we need to be able to call into
+ cthreads code and meet its assumptions about how our thread and
+ its stack are arranged. Since cthreads puts it there anyway,
+ we'll let the signal thread's per-thread variables be found as for
+ any normal cthread, and just leave the magic __hurd_sigthread_*
+ values all zero so they'll be ignored. */
+#pragma weak cthread_fork
+#pragma weak cthread_detach
+ cthread_detach (cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));
+ }
/* Receive exceptions on the signal port. */
__task_set_special_port (__mach_task_self (),
/* Demux messages sent on the signal port.
- Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1991,92,94,95,97,99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
{
/* Get our own sigstate cached so we never again have to take a lock to
fetch it. There is much code in hurdsig.c that operates with some
- sigstate lock held, which will deadlock with _hurd_thread_sigstate. */
- (void) _hurd_self_sigstate ();
+ sigstate lock held, which will deadlock with _hurd_thread_sigstate.
+
+ Furthermore, in the cthreads case this is the convenient spot
+ to initialize _hurd_msgport_thread (see hurdsig.c:_hurdsig_init). */
+
+ _hurd_msgport_thread = _hurd_self_sigstate ()->thread;
while (1)
(void) __mach_msg_server (msgport_server, __vm_page_size, _hurd_msgport);
(natural_t *) &state, &statecount))
LOSE;
#if STACK_GROWTH_UP
- state.SP = __hurd_sigthread_stack_base;
+#define THREADVAR_SPACE (__hurd_threadvar_max \
+ * sizeof *__hurd_sightread_variables)
+ if (__hurd_sigthread_stack_base == 0)
+ {
+ state.SP &= __hurd_threadvar_stack_mask;
+ state.SP += __hurd_threadvar_stack_offset + THREADVAR_SPACE;
+ }
+ else
+ state.SP = __hurd_sigthread_stack_base;
#else
- state.SP = __hurd_sigthread_stack_end;
+ if (__hurd_sigthread_stack_end == 0)
+ {
+ /* The signal thread has a normal stack assigned by cthreads.
+ The threadvar_stack variables conveniently tell us how
+ to get to the highest address in the stack, just below
+ the per-thread variables. */
+ state.SP &= __hurd_threadvar_stack_mask;
+ state.SP += __hurd_threadvar_stack_offset;
+ }
+ else
+ state.SP = __hurd_sigthread_stack_end;
#endif
MACHINE_THREAD_STATE_SET_PC (&state,
(unsigned long int) _hurd_msgport_receive);