1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

Thu Jan 4 11:35:18 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>

* sysdeps/mach/hurd/setitimer.c: Code rearranged a bit to use new
	preemption interface.

	* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler):
	Use _hurdsig_catch_memory_fault.

	* hurd/Makefile (headers): Add hurd/sigpreempt.h.
	(sig): Add catch-signal.

	* hurd/hurdfault.c (_hurdsig_fault_catch_exception_raise):
	Rewritten using a preempter in new interface.
	* hurd/hurdfault.h (_hurdsig_catch_fault): Likewise.
	(_hurdsig_catch_memory_fault): New macro.
This commit is contained in:
Roland McGrath
1996-01-04 17:00:45 +00:00
parent fb8e70d6dd
commit 7974fe2117
6 changed files with 101 additions and 80 deletions

View File

@ -1,3 +1,19 @@
Thu Jan 4 11:35:18 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/setitimer.c: Code rearranged a bit to use new
preemption interface.
* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler):
Use _hurdsig_catch_memory_fault.
* hurd/Makefile (headers): Add hurd/sigpreempt.h.
(sig): Add catch-signal.
* hurd/hurdfault.c (_hurdsig_fault_catch_exception_raise):
Rewritten using a preempter in new interface.
* hurd/hurdfault.h (_hurdsig_catch_fault): Likewise.
(_hurdsig_catch_memory_fault): New macro.
Wed Jan 3 20:23:42 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/catch-signal.c: New file.

View File

@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@ -25,8 +25,8 @@ include ../Makeconfig
headers = hurd.h $(interface-headers) \
$(addprefix hurd/,fd.h id.h port.h signal.h userlink.h \
resource.h threadvar.h lookup.h)
$(addprefix hurd/,fd.h id.h port.h signal.h sigpreempt.h \
userlink.h resource.h threadvar.h lookup.h)
distribute := hurdstartup.h hurdfault.h intr-rpc.defs STATUS
@ -51,10 +51,10 @@ routines = hurdstartup hurdinit \
fopenport \
vpprintf \
ports-get ports-set hurdports hurdmsg \
$(sig) $(dtable) hurdinline port-cleanup
$(sig) $(dtable) hurdinline port-cleanup # report-wait
sig = hurdsig hurdfault faultexc siginfo hurd-raise preempt-sig \
trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind \
thread-self thread-cancel intr-msg
thread-self thread-cancel intr-msg catch-signal
dtable = dtable port2fd new-fd alloc-fd intern-fd \
getdport openport \
fd-close fd-read fd-write hurdioctl ctty-input ctty-output

View File

@ -1,5 +1,5 @@
/* Handle faults in the signal thread.
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1996 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
@ -29,13 +29,10 @@ Cambridge, MA 02139, USA. */
#include <assert.h>
jmp_buf _hurdsig_fault_env;
struct hurd_signal_preempter _hurdsig_fault_preempter;
static mach_port_t forward_sigexc;
int _hurdsig_fault_expect_signo;
long int _hurdsig_fault_sigcode;
int _hurdsig_fault_sigerror;
kern_return_t
_hurdsig_fault_catch_exception_raise (mach_port_t port,
thread_t thread,
@ -45,6 +42,8 @@ _hurdsig_fault_catch_exception_raise (mach_port_t port,
int subcode)
{
int signo;
long int sigcode;
int sigerror;
if (port != forward_sigexc ||
thread != _hurd_msgport_thread || task != __mach_task_self ())
@ -52,10 +51,11 @@ _hurdsig_fault_catch_exception_raise (mach_port_t port,
/* Call the machine-dependent function to translate the Mach exception
codes into a signal number and subcode. */
_hurd_exception2signal (exception, code, subcode, &signo,
&_hurdsig_fault_sigcode, &_hurdsig_fault_sigerror);
_hurd_exception2signal (exception, code, subcode,
&signo, &sigcode, &sigerror);
return signo == _hurdsig_fault_expect_signo ? 0 : EGREGIOUS;
return HURD_PREEMPT_SIGNAL_P (&_hurdsig_fault_preempter, signo, sigcode)
? 0 : EGREGIOUS;
}
static void
@ -85,19 +85,17 @@ faulted (void)
/* Run the exc demuxer which should call the server function above.
That function returns 0 if the exception was expected. */
switch (_hurdsig_fault_exc_server (&request.head, &reply.head))
{
case KERN_SUCCESS:
if (reply.head.msgh_remote_port != MACH_PORT_NULL)
__mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
break;
default:
__mach_msg_destroy (&request.head);
case MIG_NO_REPLY:
}
_hurdsig_fault_exc_server (&request.head, &reply.head);
if (reply.head.msgh_remote_port != MACH_PORT_NULL)
__mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
if (reply.result == MIG_BAD_ID)
__mach_msg_destroy (&request.head);
_hurdsig_fault_expect_signo = 0;
if (reply.result)
__libc_fatal ("BUG: unexpected fault in signal thread\n");
_hurdsig_fault_preempter.signals = 0;
longjmp (_hurdsig_fault_env, 1);
}
@ -125,8 +123,10 @@ _hurdsig_fault_init (void)
err = __mach_port_insert_right (__mach_task_self (), sigexc,
sigexc, MACH_MSG_TYPE_MAKE_SEND);
assert_perror (err);
#if 0 /* XXX gdb bites */
err = __thread_set_special_port (_hurd_msgport_thread,
THREAD_EXCEPTION_PORT, sigexc);
#endif
__mach_port_deallocate (__mach_task_self (), sigexc);
assert_perror (err);

View File

@ -1,5 +1,5 @@
/* Declarations for handling faults in the signal thread.
Copyright (C) 1994 Free Software Foundation, Inc.
Copyright (C) 1994, 1996 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
@ -20,6 +20,7 @@ Cambridge, MA 02139, USA. */
#ifndef _HURD_FAULT_H
#define _HURD_FAULT_H
#include <hurd/sigpreempt.h>
#include <setjmp.h>
/* Call this before code that might fault in the signal thread; SIGNO is
@ -27,23 +28,24 @@ Cambridge, MA 02139, USA. */
returns zero the first time, and returns again nonzero if the signal
does arrive. */
#define _hurdsig_catch_fault(signo) \
(_hurdsig_fault_expect_signo = (signo), setjmp (_hurdsig_fault_env))
#define _hurdsig_catch_fault(sigset, firstcode, lastcode) \
(_hurdsig_fault_preempter.signals = (sigset), \
_hurdsig_fault_preempter.first = (long int) (firstcode), \
_hurdsig_fault_preempter.last = (long int) (lastcode), \
setjmp (_hurdsig_fault_env))
/* Call this at the end of a section protected by _hurdsig_catch_fault. */
#define _hurdsig_end_catch_fault() \
(_hurdsig_fault_expect_signo = 0)
(_hurdsig_fault_preempter.signals = 0)
extern jmp_buf _hurdsig_fault_env;
extern int _hurdsig_fault_expect_signo;
/* If _hurdsig_catch_fault returns nonzero, these variables
contain information about the signal that arrived. */
extern struct hurd_signal_preempter _hurdsig_fault_preempter;
#define _hurdsig_catch_memory_fault(object) \
_hurdsig_catch_fault (sigmask (SIGSEGV) | sigmask (SIGBUS), \
(object), (object) + 1)
extern long int _hurdsig_fault_sigcode;
extern int _hurdsig_fault_sigerror;
#endif /* hurd/fault.h */
#endif /* hurdfault.h */

View File

@ -1,5 +1,5 @@
/* Set thread_state for sighandler, and sigcontext to recover. i386 version.
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1996 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
@ -67,10 +67,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
/* We have a previous sigcontext that sigreturn was about
to restore when another signal arrived. We will just base
our setup on that. */
if (_hurdsig_catch_fault (SIGSEGV))
assert (_hurdsig_fault_sigcode >= (long int) ss->context &&
_hurdsig_fault_sigcode < (long int) (ss->context + 1));
else
if (! _hurdsig_catch_memory_fault (ss->context))
{
memcpy (&state->basic, &ss->context->sc_i386_thread_state,
sizeof (state->basic));
@ -121,10 +118,8 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
sigsp -= sizeof (*stackframe);
stackframe = sigsp;
if (_hurdsig_catch_fault (SIGSEGV))
if (_hurdsig_catch_memory_fault (stackframe))
{
assert (_hurdsig_fault_sigcode >= (long int) stackframe &&
_hurdsig_fault_sigcode <= (long int) (stackframe + 1));
/* We got a fault trying to write the stack frame.
We cannot set up the signal handler.
Returning NULL tells our caller, who will nuke us with a SIGILL. */
@ -194,10 +189,8 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
struct mach_msg_trap_args *args = (void *) state->basic.esp;
if (_hurdsig_catch_fault (SIGSEGV))
if (_hurdsig_catch_memory_fault (args))
{
assert (_hurdsig_fault_sigcode >= (long int) args &&
_hurdsig_fault_sigcode < (long int) (args + 1));
/* Faulted accessing ARGS. Bomb. */
return NULL;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1994, 1995, 1996 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
@ -22,6 +22,7 @@ Cambridge, MA 02139, USA. */
#include <sys/time.h>
#include <hurd.h>
#include <hurd/signal.h>
#include <hurd/sigpreempt.h>
#include <hurd/msg_request.h>
#include <mach/message.h>
@ -109,9 +110,29 @@ timer_thread (void)
}
}
/* Forward declaration. */
static sighandler_t preempt_sigalrm (thread_t thread, int signo,
long int sigcode, int sigerror);
static sighandler_t
restart_itimer (struct hurd_signal_preempter *preempter,
struct hurd_sigstate *ss,
int *signo, long int *sigcode,
int *sigerror)
{
static int setitimer_locked (const struct itimerval *new,
struct itimerval *old, void *crit);
/* This function gets called in the signal thread
each time a SIGALRM is arriving (even if blocked). */
struct itimerval it;
/* Either reload or disable the itimer. */
__spin_lock (&_hurd_itimer_lock);
it.it_value = it.it_interval = _hurd_itimerval.it_interval;
setitimer_locked (&it, NULL, NULL);
/* Continue with normal delivery (or hold, etc.) of SIGALRM. */
return SIG_ERR;
}
/* Called before any normal SIGALRM signal is delivered.
Reload the itimer, or disable the itimer. */
@ -138,12 +159,20 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old,
{
/* Make sure the itimer thread is set up. */
if (_hurd_signal_preempt[SIGALRM] == NULL)
/* Set up a signal preempter global for all threads to
run `restart_itimer' each time a SIGALRM would arrive. */
static struct hurd_signal_preempter preempter =
{
static struct hurd_signal_preempt preempt =
{ preempt_sigalrm, 0, 0, NULL };
_hurd_signal_preempt[SIGALRM] = &preempt;
__sigmask (SIGALRM), 0, 0,
&restart_itimer,
};
__mutex_lock (&_hurd_siglock);
if (! preempter.next && _hurdsig_preempters != &preempter)
{
preempter.next = _hurdsig_preempters;
_hurdsig_preempters = &preempter;
}
__mutex_unlock (&_hurd_siglock);
if (_hurd_itimer_port == MACH_PORT_NULL)
{
@ -293,25 +322,6 @@ DEFUN(__setitimer, (which, new, old),
__spin_lock (&_hurd_itimer_lock);
return setitimer_locked (new, old, crit);
}
static sighandler_t
preempt_sigalrm (thread_t thread, int signo, long int sigcode, int sigerror)
{
struct itimerval it;
if (thread != _hurd_sigthread || signo != SIGALRM || sigcode != 0)
/* Too much monkey business. */
return SIG_DFL;
/* Either reload or disable the itimer. */
__spin_lock (&_hurd_itimer_lock);
it = _hurd_itimerval;
it.it_value = it.it_interval;
setitimer_locked (&it, NULL, NULL);
/* Continue with normal delivery of SIGALRM. */
return SIG_DFL;
}
static void
fork_itimer (void)