1999-11-18 Roland McGrath <roland@baalperazim.frob.com>
authorroland <roland>
Fri, 3 Dec 1999 05:00:51 +0000 (05:00 +0000)
committerroland <roland>
Fri, 3 Dec 1999 05:00:51 +0000 (05:00 +0000)
        * 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.

hurd/Versions
hurd/hurdsig.c
hurd/msgportdemux.c
sysdeps/mach/hurd/fork.c

index 5dcdc35..a81bc55 100644 (file)
@@ -108,6 +108,9 @@ libc {
     seteuids;
   }
   GLIBC_2.1.3 {
+    # c*
+    cthread_fork; cthread_detach;
+
     # d*
     directory_name_split;
 
index 2c9625b..47f5fbf 100644 (file)
@@ -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 (),
index 4250aff..7f61758 100644 (file)
@@ -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);
index 3981ed2..b28f5cb 100644 (file)
@@ -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);