Skip to content
Snippets Groups Projects
Commit 3fb42466 authored by ram's avatar ram
Browse files

Solaris/posix support.

parent 0d38205a
No related branches found
No related tags found
No related merge requests found
/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.4 1994/07/05 16:08:03 hallgren Exp $ */ /* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.5 1994/10/24 20:05:30 ram Exp $ */
/* Interrupt handing magic. */ /* Interrupt handing magic. */
...@@ -12,12 +12,12 @@ ...@@ -12,12 +12,12 @@
#endif #endif
#include "lisp.h" #include "lisp.h"
#include "arch.h"
#include "internals.h" #include "internals.h"
#include "os.h" #include "os.h"
#include "arch.h" #include "interrupt.h"
#include "globals.h" #include "globals.h"
#include "lispregs.h" #include "lispregs.h"
#include "interrupt.h"
#include "validate.h" #include "validate.h"
#include "monitor.h" #include "monitor.h"
#include "gc.h" #include "gc.h"
...@@ -30,10 +30,25 @@ boolean internal_errors_enabled = 0; ...@@ -30,10 +30,25 @@ boolean internal_errors_enabled = 0;
struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS]; struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS];
union interrupt_handler interrupt_handlers[NSIG]; union interrupt_handler interrupt_handlers[NSIG];
void (*interrupt_low_level_handlers[NSIG])(int signal, int code, void (*interrupt_low_level_handlers[NSIG]) (HANDLER_ARGS) = {0};
struct sigcontext *scp) = {0};
static int pending_signal = 0;
#ifdef SOLARIS
static siginfo_t *pending_code;
#define PASSCODE(code) ((code))
#define DEREFCODE(code) ((code))
#else
static int pending_code = 0;
#define PASSCODE(code) (code)
#define DEREFCODE(code) (code)
#endif
static int pending_signal = 0, pending_code = 0, pending_mask = 0; #ifdef POSIX_SIGS
static sigset_t pending_mask;
#else
static int pending_mask = 0;
#endif
static boolean maybe_gc_pending = FALSE; static boolean maybe_gc_pending = FALSE;
...@@ -118,7 +133,14 @@ void fake_foreign_function_call(struct sigcontext *context) ...@@ -118,7 +133,14 @@ void fake_foreign_function_call(struct sigcontext *context)
void undo_fake_foreign_function_call(struct sigcontext *context) void undo_fake_foreign_function_call(struct sigcontext *context)
{ {
/* Block all blockable signals */ /* Block all blockable signals */
#ifdef POSIX_SIGS
sigset_t block;
sigemptyset(&block);
FILLBLOCKSET(&block);
sigprocmask(SIG_BLOCK, &block, 0);
#else
sigblock(BLOCKABLE); sigblock(BLOCKABLE);
#endif
/* Going back into lisp. */ /* Going back into lisp. */
foreign_function_call_active = 0; foreign_function_call_active = 0;
...@@ -134,10 +156,14 @@ void undo_fake_foreign_function_call(struct sigcontext *context) ...@@ -134,10 +156,14 @@ void undo_fake_foreign_function_call(struct sigcontext *context)
#endif #endif
} }
void interrupt_internal_error(int signal, int code, struct sigcontext *context, void interrupt_internal_error(HANDLER_ARGS,
boolean continuable) boolean continuable)
{ {
#ifdef POSIX_SIGS
sigprocmask(SIG_SETMASK,&context->uc_sigmask, 0);
#else
sigsetmask(context->sc_mask); sigsetmask(context->sc_mask);
#endif
fake_foreign_function_call(context); fake_foreign_function_call(context);
if (internal_errors_enabled) if (internal_errors_enabled)
funcall2(SymbolFunction(INTERNAL_ERROR), alloc_sap(context), funcall2(SymbolFunction(INTERNAL_ERROR), alloc_sap(context),
...@@ -164,16 +190,25 @@ void interrupt_handle_pending(struct sigcontext *context) ...@@ -164,16 +190,25 @@ void interrupt_handle_pending(struct sigcontext *context)
undo_fake_foreign_function_call(context); undo_fake_foreign_function_call(context);
} }
if (pending_signal) { if (pending_signal) {
int signal, code; int signal;
#ifdef SOLARIS
siginfo_t *code;
#else
int code;
#endif
signal = pending_signal; signal = pending_signal;
code = pending_code; code = pending_code;
pending_signal = 0; pending_signal = 0;
pending_code = 0; /* pending_code = 0; /**/
interrupt_handle_now(signal, code, context); interrupt_handle_now(signal, PASSCODE(code), context);
} }
#ifdef POSIX_SIGS
context->uc_sigmask = pending_mask;
sigemptyset(&pending_mask);
#else
context->sc_mask = pending_mask; context->sc_mask = pending_mask;
pending_mask = 0; pending_mask = 0;
#endif
} }
...@@ -182,7 +217,7 @@ void interrupt_handle_pending(struct sigcontext *context) ...@@ -182,7 +217,7 @@ void interrupt_handle_pending(struct sigcontext *context)
* the two main signal handlers. * * the two main signal handlers. *
\****************************************************************/ \****************************************************************/
void interrupt_handle_now(int signal, int code, struct sigcontext *context) void interrupt_handle_now(HANDLER_ARGS)
{ {
int were_in_lisp; int were_in_lisp;
union interrupt_handler handler; union interrupt_handler handler;
...@@ -192,12 +227,18 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context) ...@@ -192,12 +227,18 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context)
if(handler.c==SIG_IGN) if(handler.c==SIG_IGN)
return; return;
SAVE_CONTEXT(); /**/
were_in_lisp = !foreign_function_call_active; were_in_lisp = !foreign_function_call_active;
if (were_in_lisp) if (were_in_lisp)
fake_foreign_function_call(context); fake_foreign_function_call(context);
/* Allow signals again. */ /* Allow signals again. */
#ifdef POSIX_SIGS
sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0);
#else
sigsetmask(context->sc_mask); sigsetmask(context->sc_mask);
#endif
if (handler.c==SIG_DFL) if (handler.c==SIG_DFL)
/* This can happen if someone tries to ignore or default on of the */ /* This can happen if someone tries to ignore or default on of the */
...@@ -205,8 +246,13 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context) ...@@ -205,8 +246,13 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context)
/* decides to pass on it. */ /* decides to pass on it. */
lose("interrupt_handle_now: No handler for signal %d?\n", signal); lose("interrupt_handle_now: No handler for signal %d?\n", signal);
else if (LowtagOf(handler.lisp) == type_FunctionPointer) else if (LowtagOf(handler.lisp) == type_FunctionPointer)
funcall3(handler.lisp, make_fixnum(signal), make_fixnum(code), #if 1
funcall3(handler.lisp, make_fixnum(signal), make_fixnum(CODE(code)),
alloc_sap(context));
#else
funcall3(handler.lisp, make_fixnum(signal), alloc_sap(code),
alloc_sap(context)); alloc_sap(context));
#endif
else else
(*handler.c)(signal, code, context); (*handler.c)(signal, code, context);
...@@ -214,21 +260,32 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context) ...@@ -214,21 +260,32 @@ void interrupt_handle_now(int signal, int code, struct sigcontext *context)
undo_fake_foreign_function_call(context); undo_fake_foreign_function_call(context);
} }
static void maybe_now_maybe_later(int signal, int code, static void maybe_now_maybe_later(HANDLER_ARGS)
struct sigcontext *context)
{ {
SAVE_CONTEXT(); /**/
if (SymbolValue(INTERRUPTS_ENABLED) == NIL) { if (SymbolValue(INTERRUPTS_ENABLED) == NIL) {
pending_signal = signal; pending_signal = signal;
pending_code = code; pending_code = DEREFCODE(code);
#ifdef POSIX_SIGS
pending_mask = context->uc_sigmask;
FILLBLOCKSET(&context->uc_sigmask);
#else
pending_mask = context->sc_mask; pending_mask = context->sc_mask;
context->sc_mask |= BLOCKABLE; context->sc_mask |= BLOCKABLE;
#endif
SetSymbolValue(INTERRUPT_PENDING, T); SetSymbolValue(INTERRUPT_PENDING, T);
} else if ((!foreign_function_call_active) } else if ((!foreign_function_call_active)
&& arch_pseudo_atomic_atomic(context)) { && arch_pseudo_atomic_atomic(context)) {
pending_signal = signal; pending_signal = signal;
pending_code = code; pending_code = DEREFCODE(code);
#ifdef POSIX_SIGS
pending_mask = context->uc_sigmask;
FILLBLOCKSET(&context->uc_sigmask);
#else
pending_mask = context->sc_mask; pending_mask = context->sc_mask;
context->sc_mask |= BLOCKABLE; context->sc_mask |= BLOCKABLE;
#endif
arch_set_pseudo_atomic_interrupted(context); arch_set_pseudo_atomic_interrupted(context);
} else } else
interrupt_handle_now(signal, code, context); interrupt_handle_now(signal, code, context);
...@@ -239,7 +296,7 @@ static void maybe_now_maybe_later(int signal, int code, ...@@ -239,7 +296,7 @@ static void maybe_now_maybe_later(int signal, int code,
\****************************************************************/ \****************************************************************/
#ifndef INTERNAL_GC_TRIGGER #ifndef INTERNAL_GC_TRIGGER
static boolean gc_trigger_hit(int signal, int code, struct sigcontext *context) static boolean gc_trigger_hit(HANDLER_ARGS)
{ {
if (current_auto_gc_trigger == NULL) if (current_auto_gc_trigger == NULL)
return FALSE; return FALSE;
...@@ -253,7 +310,7 @@ static boolean gc_trigger_hit(int signal, int code, struct sigcontext *context) ...@@ -253,7 +310,7 @@ static boolean gc_trigger_hit(int signal, int code, struct sigcontext *context)
#endif #endif
boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context) boolean interrupt_maybe_gc(HANDLER_ARGS)
{ {
if (!foreign_function_call_active if (!foreign_function_call_active
#ifndef INTERNAL_GC_TRIGGER #ifndef INTERNAL_GC_TRIGGER
...@@ -267,8 +324,13 @@ boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context) ...@@ -267,8 +324,13 @@ boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context)
if (arch_pseudo_atomic_atomic(context)) { if (arch_pseudo_atomic_atomic(context)) {
maybe_gc_pending = TRUE; maybe_gc_pending = TRUE;
if (pending_signal == 0) { if (pending_signal == 0) {
#ifdef POSIX_SIGS
pending_mask = context->uc_sigmask;
FILLBLOCKSET(&context->uc_sigmask);
#else
pending_mask = context->sc_mask; pending_mask = context->sc_mask;
context->sc_mask |= BLOCKABLE; context->sc_mask |= BLOCKABLE;
#endif
} }
arch_set_pseudo_atomic_interrupted(context); arch_set_pseudo_atomic_interrupted(context);
} }
...@@ -289,8 +351,18 @@ boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context) ...@@ -289,8 +351,18 @@ boolean interrupt_maybe_gc(int signal, int code, struct sigcontext *context)
void interrupt_install_low_level_handler void interrupt_install_low_level_handler
(int signal, (int signal,
void handler(int signal, int code, struct sigcontext *handler)) void handler(HANDLER_ARGS))
{ {
#ifdef POSIX_SIGS
struct sigaction sa;
sa.sa_sigaction=handler;
sigemptyset(&sa.sa_mask);
FILLBLOCKSET(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(signal, &sa, NULL);
#else
struct sigvec sv; struct sigvec sv;
sv.sv_handler=handler; sv.sv_handler=handler;
...@@ -298,13 +370,49 @@ void interrupt_install_low_level_handler ...@@ -298,13 +370,49 @@ void interrupt_install_low_level_handler
sv.sv_flags=0; sv.sv_flags=0;
sigvec(signal,&sv,NULL); sigvec(signal,&sv,NULL);
#endif
interrupt_low_level_handlers[signal]=(handler==SIG_DFL ? 0 : handler); interrupt_low_level_handlers[signal]=(handler==SIG_DFL ? 0 : handler);
} }
unsigned long install_handler(int signal, unsigned long install_handler(int signal,
void handler(int signal, int code, void handler(HANDLER_ARGS))
struct sigcontext *handler)) #ifdef POSIX_SIGS
{
struct sigaction sa;
sigset_t old,new;
union interrupt_handler oldhandler;
sigemptyset(&new);
sigaddset(&new, signal);
sigprocmask(SIG_BLOCK, &new, &old);
sigemptyset(&new);
FILLBLOCKSET(&new);
if(interrupt_low_level_handlers[signal]==0){
if(handler==SIG_DFL || handler==SIG_IGN)
sa.sa_sigaction = handler;
else if (sigismember(&new, signal))
sa.sa_sigaction = maybe_now_maybe_later;
else
sa.sa_sigaction = interrupt_handle_now;
sigemptyset(&sa.sa_mask);
FILLBLOCKSET(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sigaction(signal, &sa, NULL);
}
oldhandler = interrupt_handlers[signal];
interrupt_handlers[signal].c = handler;
sigprocmask(SIG_SETMASK, &old, 0);
return (unsigned long)oldhandler.lisp;
}
#else
{ {
struct sigvec sv; struct sigvec sv;
int oldmask; int oldmask;
...@@ -333,6 +441,7 @@ unsigned long install_handler(int signal, ...@@ -333,6 +441,7 @@ unsigned long install_handler(int signal,
return (unsigned long)oldhandler.lisp; return (unsigned long)oldhandler.lisp;
} }
#endif
void interrupt_init(void) void interrupt_init(void)
{ {
......
/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.h,v 1.3 1993/07/27 15:08:44 hallgren Exp $ */ /* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.h,v 1.4 1994/10/24 20:06:00 ram Exp $ */
#if !defined(_INCLUDE_INTERRUPT_H_) #if !defined(_INCLUDE_INTERRUPT_H_)
#define _INCLUDE_INTERRUPT_H_ #define _INCLUDE_INTERRUPT_H_
...@@ -11,24 +11,21 @@ extern struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS]; ...@@ -11,24 +11,21 @@ extern struct sigcontext *lisp_interrupt_contexts[MAX_INTERRUPTS];
union interrupt_handler { union interrupt_handler {
lispobj lisp; lispobj lisp;
void (*c)(int signal, int code, struct sigcontext *scp); void (*c)(HANDLER_ARGS);
}; };
extern void interrupt_init(void); extern void interrupt_init(void);
extern void fake_foreign_function_call(struct sigcontext *context); extern void fake_foreign_function_call(struct sigcontext *context);
extern void undo_fake_foreign_function_call(struct sigcontext *context); extern void undo_fake_foreign_function_call(struct sigcontext *context);
extern void interrupt_handle_now(int signal, int code, struct sigcontext *scp); extern void interrupt_handle_now(HANDLER_ARGS);
extern void interrupt_handle_pending(struct sigcontext *scp); extern void interrupt_handle_pending(struct sigcontext *scp);
extern void interrupt_internal_error(int signal, int code, extern void interrupt_internal_error(HANDLER_ARGS, boolean continuable);
struct sigcontext *scp, extern boolean interrupt_maybe_gc(HANDLER_ARGS);
boolean continuable);
extern boolean interrupt_maybe_gc(int sig, int code, struct sigcontext *scp);
extern void interrupt_install_low_level_handler extern void interrupt_install_low_level_handler
(int signal, (int signal,
void handler(int signal, int code, struct sigcontext *scp)); void handler(HANDLER_ARGS));
extern unsigned long install_handler(int signal, extern unsigned long install_handler(int signal,
void handler(int signal, int code, void handler(HANDLER_ARGS));
struct sigcontext *handler));
extern union interrupt_handler interrupt_handlers[NSIG]; extern union interrupt_handler interrupt_handlers[NSIG];
...@@ -41,6 +38,16 @@ extern union interrupt_handler interrupt_handlers[NSIG]; ...@@ -41,6 +38,16 @@ extern union interrupt_handler interrupt_handlers[NSIG];
sigmask(SIGPROF) | sigmask(SIGWINCH) | \ sigmask(SIGPROF) | sigmask(SIGWINCH) | \
sigmask(SIGUSR1) | sigmask(SIGUSR2)) sigmask(SIGUSR1) | sigmask(SIGUSR2))
#else #else
#ifdef POSIX_SIGS
#define FILLBLOCKSET(s) (sigaddset(s,SIGHUP), sigaddset(s,SIGINT), \
sigaddset(s,SIGQUIT), sigaddset(s,SIGPIPE), \
sigaddset(s,SIGALRM), sigaddset(s,SIGURG), \
sigaddset(s,SIGTSTP), sigaddset(s,SIGCHLD), \
sigaddset(s,SIGIO), sigaddset(s,SIGXCPU), \
sigaddset(s,SIGXFSZ), sigaddset(s,SIGVTALRM), \
sigaddset(s,SIGPROF), sigaddset(s,SIGWINCH), \
sigaddset(s,SIGUSR1), sigaddset(s,SIGUSR2))
#else
#define BLOCKABLE (sigmask(SIGHUP) | sigmask(SIGINT) | \ #define BLOCKABLE (sigmask(SIGHUP) | sigmask(SIGINT) | \
sigmask(SIGQUIT) | sigmask(SIGPIPE) | \ sigmask(SIGQUIT) | sigmask(SIGPIPE) | \
sigmask(SIGALRM) | sigmask(SIGURG) | \ sigmask(SIGALRM) | sigmask(SIGURG) | \
...@@ -51,3 +58,4 @@ extern union interrupt_handler interrupt_handlers[NSIG]; ...@@ -51,3 +58,4 @@ extern union interrupt_handler interrupt_handlers[NSIG];
sigmask(SIGUSR1) | sigmask(SIGUSR2)) sigmask(SIGUSR1) | sigmask(SIGUSR2))
#endif #endif
#endif #endif
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment