From: Roland McGrath Date: Thu, 18 Nov 1999 06:17:13 +0000 (+0000) Subject: 1999-11-18 Roland McGrath X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=267ff95b79bd2216a757814392c08d7cc0f529a8;p=thirdparty%2Fglibc.git 1999-11-18 Roland McGrath * hurd/hurdsig.c (_hurdsig_init): If __hurd_threadvar_stack_mask is nonzero, use cthread_fork to create the signal thread. * hurd/msgportdemux.c (_hurd_msgport_receive): Initialize _hurd_msgport_thread here (to self). * sysdeps/mach/hurd/fork.c (__fork): When __hurd_sigthread_stack_end is zero, instead compute child signal thread's starting SP from parent signal thread's current SP and the threadvar_stack variables. * hurd/Versions (GLIBC_2.1.3): Add cthread_fork, cthread_detach. These are now referenced weakly by _hurdsig_init. --- diff --git a/hurd/Versions b/hurd/Versions index 5dcdc355d93..a81bc551b26 100644 --- a/hurd/Versions +++ b/hurd/Versions @@ -108,6 +108,9 @@ libc { seteuids; } GLIBC_2.1.3 { + # c* + cthread_fork; cthread_detach; + # d* directory_name_split; diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index 2c9625b4746..47f5fbf0a43 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -1227,28 +1227,47 @@ _hurdsig_init (const int *intarray, size_t intarraysize) /* 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 (), diff --git a/hurd/msgportdemux.c b/hurd/msgportdemux.c index 4250affd0ba..7f61758cc37 100644 --- a/hurd/msgportdemux.c +++ b/hurd/msgportdemux.c @@ -1,5 +1,5 @@ /* 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 @@ -57,8 +57,12 @@ _hurd_msgport_receive (void) { /* 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); diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index 3981ed20872..b28f5cb5d4f 100644 --- a/sysdeps/mach/hurd/fork.c +++ b/sysdeps/mach/hurd/fork.c @@ -480,9 +480,27 @@ __fork (void) (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);