android
This commit is contained in:
parent
5f2964cce6
commit
9b3bbf5e33
309
os/sig.c
309
os/sig.c
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include "sysbits.h"
|
#include "sysbits.h"
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_SIGINFO_H
|
#if HAVE_SIGINFO_H
|
||||||
#include <siginfo.h>
|
#include <siginfo.h>
|
||||||
#endif
|
#endif
|
||||||
@ -12,40 +13,26 @@
|
|||||||
#include <fpu_control.h>
|
#include <fpu_control.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_SIGNAL
|
|
||||||
|
|
||||||
#ifdef MSH
|
|
||||||
|
|
||||||
#define SIGFPE SIGDIV
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void HandleMatherr(int sig, void *sipv, void *uapv);
|
|
||||||
|
|
||||||
#define PLSIG_PREPARED 0x01 /* signal is prepared */
|
|
||||||
#define PLSIG_THROW 0x02 /* throw signal(num, name) */
|
|
||||||
#define PLSIG_SYNC 0x04 /* call synchronously */
|
|
||||||
#define PLSIG_NOFRAME 0x08 /* Do not create a Prolog frame */
|
|
||||||
|
|
||||||
#define SIG_PROLOG_OFFSET 32 /* Start of Prolog signals */
|
#define SIG_PROLOG_OFFSET 32 /* Start of Prolog signals */
|
||||||
|
|
||||||
|
|
||||||
#define SIG_EXCEPTION (SIG_PROLOG_OFFSET+0)
|
#define SIG_EXCEPTION (SIG_PROLOG_OFFSET+0)
|
||||||
#ifdef ATOMGC
|
#ifdef O_ATOMGC
|
||||||
#define SIG_ATOM_GC (SIG_PROLOG_OFFSET+1)
|
#define SIG_ATOM_GC (SIG_PROLOG_OFFSET+1)
|
||||||
#endif
|
#endif
|
||||||
#define SIG_GC (SIG_PROLOG_OFFSET+2)
|
#define SIG_GC (SIG_PROLOG_OFFSET+2)
|
||||||
#ifdef THREADS
|
#ifdef O_PLMT
|
||||||
#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET + 3)b
|
#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET+3)
|
||||||
#endif
|
#endif
|
||||||
#define SIG_FREECLAUSES (SIG_PROLOG_OFFSET+4)
|
#define SIG_FREECLAUSES (SIG_PROLOG_OFFSET+4)
|
||||||
#define SIG_PLABORT (SIG_PROLOG_OFFSET+5)
|
#define SIG_PLABORT (SIG_PROLOG_OFFSET+5)
|
||||||
|
|
||||||
static struct signame {
|
static struct signame
|
||||||
int sig;
|
{ int sig;
|
||||||
const char *name;
|
const char *name;
|
||||||
int flags;
|
int flags;
|
||||||
} signames[] = {
|
} signames[] =
|
||||||
|
{
|
||||||
#ifdef SIGHUP
|
#ifdef SIGHUP
|
||||||
{ SIGHUP, "hup", 0},
|
{ SIGHUP, "hup", 0},
|
||||||
#endif
|
#endif
|
||||||
@ -55,9 +42,7 @@ static struct signame {
|
|||||||
#endif
|
#endif
|
||||||
{ SIGILL, "ill", 0},
|
{ SIGILL, "ill", 0},
|
||||||
{ SIGABRT, "abrt", 0},
|
{ SIGABRT, "abrt", 0},
|
||||||
#if HAVE_SIGFPE
|
{ SIGFPE, "fpe", 0},
|
||||||
{SIGFPE, "fpe", PLSIG_THROW},
|
|
||||||
#endif
|
|
||||||
#ifdef SIGKILL
|
#ifdef SIGKILL
|
||||||
{ SIGKILL, "kill", 0},
|
{ SIGKILL, "kill", 0},
|
||||||
#endif
|
#endif
|
||||||
@ -66,7 +51,7 @@ static struct signame {
|
|||||||
{ SIGPIPE, "pipe", 0},
|
{ SIGPIPE, "pipe", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGALRM
|
#ifdef SIGALRM
|
||||||
{SIGALRM, "alrm", PLSIG_THROW},
|
{ SIGALRM, "alrm", 0},
|
||||||
#endif
|
#endif
|
||||||
{ SIGTERM, "term", 0},
|
{ SIGTERM, "term", 0},
|
||||||
#ifdef SIGUSR1
|
#ifdef SIGUSR1
|
||||||
@ -112,13 +97,13 @@ static struct signame {
|
|||||||
{ SIGPOLL, "poll", 0},
|
{ SIGPOLL, "poll", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGXCPU
|
#ifdef SIGXCPU
|
||||||
{SIGXCPU, "xcpu", PLSIG_THROW},
|
{ SIGXCPU, "xcpu", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGXFSZ
|
#ifdef SIGXFSZ
|
||||||
{SIGXFSZ, "xfsz", PLSIG_THROW},
|
{ SIGXFSZ, "xfsz", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGVTALRM
|
#ifdef SIGVTALRM
|
||||||
{SIGVTALRM, "vtalrm", PLSIG_THROW},
|
{ SIGVTALRM, "vtalrm", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPROF
|
#ifdef SIGPROF
|
||||||
{ SIGPROF, "prof", 0},
|
{ SIGPROF, "prof", 0},
|
||||||
@ -137,7 +122,6 @@ static struct signame {
|
|||||||
|
|
||||||
{-1, NULL, 0}};
|
{-1, NULL, 0}};
|
||||||
|
|
||||||
typedef void (*signal_handler_t)(int, void *, void *);
|
|
||||||
|
|
||||||
#if HAVE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
static void my_signal_info(int sig, void *handler) {
|
static void my_signal_info(int sig, void *handler) {
|
||||||
@ -161,15 +145,30 @@ static void my_signal(int sig, void *handler) {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static void my_signal(int sig, void *handler) { signal(sig, handler); }
|
static void my_signal(int sig, void *handler) {
|
||||||
|
#if HAVE_SIGNAL
|
||||||
|
signal(sig, handler);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void my_signal_info(int sig, void *handler) {
|
static void my_signal_info(int sig, void *handler) {
|
||||||
|
#if HAVE_SIGNAL
|
||||||
if (signal(sig, (void *)handler) == SIG_ERR)
|
if (signal(sig, (void *)handler) == SIG_ERR)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void HandleMatherr(int sig, void *sipv, void *uapv) {
|
||||||
|
CACHE_REGS
|
||||||
|
LOCAL_matherror = Yap_MathException();
|
||||||
|
/* reset the registers so that we don't have trash in abstract machine */
|
||||||
|
Yap_external_signal(worker_id, YAP_FPE_SIGNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SWI emulation */
|
/* SWI emulation */
|
||||||
int Yap_signal_index(const char *name) {
|
int Yap_signal_index(const char *name) {
|
||||||
struct signame *sn = signames;
|
struct signame *sn = signames;
|
||||||
@ -244,8 +243,6 @@ static void HandleSIGSEGV(int sig, void *sipv, void *uap) {
|
|||||||
}
|
}
|
||||||
#endif /* SIGSEGV */
|
#endif /* SIGSEGV */
|
||||||
|
|
||||||
#if HAVE_SIGFPE
|
|
||||||
|
|
||||||
/* by default Linux with glibc is IEEE compliant anyway..., but we will pretend
|
/* by default Linux with glibc is IEEE compliant anyway..., but we will pretend
|
||||||
* it is not. */
|
* it is not. */
|
||||||
static bool set_fpu_exceptions(Term flag) {
|
static bool set_fpu_exceptions(Term flag) {
|
||||||
@ -321,99 +318,11 @@ static bool set_fpu_exceptions(Term flag) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Yap_set_fpu_exceptions(Term flag) { return set_fpu_exceptions(flag); }
|
|
||||||
|
|
||||||
yap_error_number Yap_MathException__(USES_REGS1) {
|
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__)
|
||||||
#if HAVE_FETESTEXCEPT
|
|
||||||
int raised;
|
|
||||||
|
|
||||||
// #pragma STDC FENV_ACCESS ON
|
|
||||||
if ((raised = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW))) {
|
|
||||||
|
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
static void * ReceiveSignal(int s, void *x, void *y) {
|
||||||
if (raised & FE_OVERFLOW) {
|
|
||||||
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
|
||||||
} else if (raised & FE_DIVBYZERO) {
|
|
||||||
return EVALUATION_ERROR_ZERO_DIVISOR;
|
|
||||||
} else if (raised & FE_UNDERFLOW) {
|
|
||||||
return EVALUATION_ERROR_FLOAT_UNDERFLOW;
|
|
||||||
//} else if (raised & (FE_INVALID|FE_INEXACT)) {
|
|
||||||
// return EVALUATION_ERROR_UNDEFINED;
|
|
||||||
} else {
|
|
||||||
return EVALUATION_ERROR_UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif _WIN32
|
|
||||||
unsigned int raised;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
// Show original FP control word and do calculation.
|
|
||||||
err = _controlfp_s(&raised, 0, 0);
|
|
||||||
if (err) {
|
|
||||||
return EVALUATION_ERROR_UNDEFINED;
|
|
||||||
}
|
|
||||||
if (raised) {
|
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
|
||||||
if (raised & FE_OVERFLOW) {
|
|
||||||
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
|
||||||
} else if (raised & FE_DIVBYZERO) {
|
|
||||||
return EVALUATION_ERROR_ZERO_DIVISOR;
|
|
||||||
} else if (raised & FE_UNDERFLOW) {
|
|
||||||
return EVALUATION_ERROR_FLOAT_UNDERFLOW;
|
|
||||||
//} else if (raised & (FE_INVALID|FE_INEXACT)) {
|
|
||||||
// return EVALUATION_ERROR_UNDEFINED;
|
|
||||||
} else {
|
|
||||||
return EVALUATION_ERROR_UNDEFINED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif (defined(__svr4__) || defined(__SVR4))
|
|
||||||
switch (sip->si_code) {
|
|
||||||
case FPE_INTDIV:
|
|
||||||
return EVALUATION_ERROR_ZERO_DIVISOR;
|
|
||||||
break;
|
|
||||||
case FPE_INTOVF:
|
|
||||||
return EVALUATION_ERROR_INT_OVERFLOW;
|
|
||||||
break;
|
|
||||||
case FPE_FLTDIV:
|
|
||||||
return EVALUATION_ERROR_ZERO_DIVISOR;
|
|
||||||
break;
|
|
||||||
case FPE_FLTOVF:
|
|
||||||
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
|
||||||
break;
|
|
||||||
case FPE_FLTUND:
|
|
||||||
return EVALUATION_ERROR_FLOAT_UNDERFLOW;
|
|
||||||
break;
|
|
||||||
case FPE_FLTRES:
|
|
||||||
case FPE_FLTINV:
|
|
||||||
case FPE_FLTSUB:
|
|
||||||
default:
|
|
||||||
return EVALUATION_ERROR_UNDEFINED;
|
|
||||||
}
|
|
||||||
set_fpu_exceptions(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return LOCAL_matherror;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Int fpe_error(USES_REGS1) {
|
|
||||||
Yap_Error(LOCAL_matherror, LOCAL_mathtt, LOCAL_mathstring);
|
|
||||||
LOCAL_matherror = YAP_NO_ERROR;
|
|
||||||
LOCAL_mathtt = TermNil;
|
|
||||||
LOCAL_mathstring = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void HandleMatherr(int sig, void *sipv, void *uapv) {
|
|
||||||
CACHE_REGS
|
|
||||||
LOCAL_matherror = Yap_MathException();
|
|
||||||
/* reset the registers so that we don't have trash in abstract machine */
|
|
||||||
Yap_external_signal(worker_id, YAP_FPE_SIGNAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SIGFPE */
|
|
||||||
|
|
||||||
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
|
||||||
static RETSIGTYPE ReceiveSignal(int s, void *x, void *y) {
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
LOCAL_PrologMode |= InterruptMode;
|
LOCAL_PrologMode |= InterruptMode;
|
||||||
my_signal(s, ReceiveSignal);
|
my_signal(s, ReceiveSignal);
|
||||||
@ -503,40 +412,6 @@ static BOOL WINAPI MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* SIGINT can cause problems, if caught before full initialization */
|
|
||||||
void Yap_InitOSSignals(int wid) {
|
|
||||||
if (GLOBAL_PrologShouldHandleInterrupts) {
|
|
||||||
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
|
||||||
my_signal(SIGQUIT, ReceiveSignal);
|
|
||||||
my_signal(SIGKILL, ReceiveSignal);
|
|
||||||
my_signal(SIGUSR1, ReceiveSignal);
|
|
||||||
my_signal(SIGUSR2, ReceiveSignal);
|
|
||||||
my_signal(SIGHUP, ReceiveSignal);
|
|
||||||
my_signal(SIGALRM, ReceiveSignal);
|
|
||||||
my_signal(SIGVTALRM, ReceiveSignal);
|
|
||||||
#endif
|
|
||||||
#ifdef SIGPIPE
|
|
||||||
my_signal(SIGPIPE, ReceiveSignal);
|
|
||||||
#endif
|
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
|
||||||
signal(SIGINT, SIG_IGN);
|
|
||||||
SetConsoleCtrlHandler(MSCHandleSignal, TRUE);
|
|
||||||
#else
|
|
||||||
my_signal(SIGINT, ReceiveSignal);
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SIGFPE
|
|
||||||
my_signal(SIGFPE, HandleMatherr);
|
|
||||||
#endif
|
|
||||||
#if HAVE_SIGSEGV
|
|
||||||
my_signal_info(SIGSEGV, HandleSIGSEGV);
|
|
||||||
#endif
|
|
||||||
#ifdef YAPOR_COW
|
|
||||||
signal(SIGCHLD, SIG_IGN); /* avoid ghosts */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_SIGNAL */
|
|
||||||
|
|
||||||
/* wrapper for alarm system call */
|
/* wrapper for alarm system call */
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
@ -877,6 +752,126 @@ void rw_lock_voodoo(void) {
|
|||||||
|
|
||||||
#endif /* YAPOR || THREADS */
|
#endif /* YAPOR || THREADS */
|
||||||
|
|
||||||
|
yap_error_number Yap_MathException__(USES_REGS1) {
|
||||||
|
#if HAVE_FETESTEXCEPT
|
||||||
|
int raised;
|
||||||
|
|
||||||
|
// #pragma STDC FENV_ACCESS ON
|
||||||
|
if ((raised = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW))) {
|
||||||
|
|
||||||
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
if (raised & FE_OVERFLOW) {
|
||||||
|
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
||||||
|
} else if (raised & FE_DIVBYZERO) {
|
||||||
|
return EVALUATION_ERROR_ZERO_DIVISOR;
|
||||||
|
} else if (raised & FE_UNDERFLOW) {
|
||||||
|
return EVALUATION_ERROR_FLOAT_UNDERFLOW;
|
||||||
|
//} else if (raised & (FE_INVALID|FE_INEXACT)) {
|
||||||
|
// return EVALUATION_ERROR_UNDEFINED;
|
||||||
|
} else {
|
||||||
|
return EVALUATION_ERROR_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif _WIN32
|
||||||
|
unsigned int raised;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
// Show original FP control word and do calculation.
|
||||||
|
err = _controlfp_s(&raised, 0, 0);
|
||||||
|
if (err) {
|
||||||
|
return EVALUATION_ERROR_UNDEFINED;
|
||||||
|
}
|
||||||
|
if (raised) {
|
||||||
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
if (raised & FE_OVERFLOW) {
|
||||||
|
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
||||||
|
} else if (raised & FE_DIVBYZERO) {
|
||||||
|
return EVALUATION_ERROR_ZERO_DIVISOR;
|
||||||
|
} else if (raised & FE_UNDERFLOW) {
|
||||||
|
return EVALUATION_ERROR_FLOAT_UNDERFLOW;
|
||||||
|
//} else if (raised & (FE_INVALID|FE_INEXACT)) {
|
||||||
|
// return EVALUATION_ERROR_UNDEFINED;
|
||||||
|
} else {
|
||||||
|
return EVALUATION_ERROR_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif (defined(__svr4__) || defined(__SVR4))
|
||||||
|
switch (sip->si_code) {
|
||||||
|
case FPE_INTDIV:
|
||||||
|
return EVALUATION_ERROR_ZERO_DIVISOR;
|
||||||
|
break;
|
||||||
|
case FPE_INTOVF:
|
||||||
|
return EVALUATION_ERROR_INT_OVERFLOW;
|
||||||
|
break;
|
||||||
|
case FPE_FLTDIV:
|
||||||
|
return EVALUATION_ERROR_ZERO_DIVISOR;
|
||||||
|
break;
|
||||||
|
case FPE_FLTOVF:
|
||||||
|
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
||||||
|
break;
|
||||||
|
case FPE_FLTUND:
|
||||||
|
return EVALUATION_ERROR_FLOAT_UNDERFLOW;
|
||||||
|
break;
|
||||||
|
case FPE_FLTRES:
|
||||||
|
case FPE_FLTINV:
|
||||||
|
case FPE_FLTSUB:
|
||||||
|
default:
|
||||||
|
return EVALUATION_ERROR_UNDEFINED;
|
||||||
|
}
|
||||||
|
set_fpu_exceptions(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return LOCAL_matherror;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Int fpe_error(USES_REGS1) {
|
||||||
|
Yap_Error(LOCAL_matherror, LOCAL_mathtt, LOCAL_mathstring);
|
||||||
|
LOCAL_matherror = YAP_NO_ERROR;
|
||||||
|
LOCAL_mathtt = TermNil;
|
||||||
|
LOCAL_mathstring = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SIGINT can cause problems, if caught before full initialization */
|
||||||
|
void Yap_InitOSSignals(int wid) {
|
||||||
|
if (GLOBAL_PrologShouldHandleInterrupts) {
|
||||||
|
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
||||||
|
my_signal(SIGQUIT, ReceiveSignal);
|
||||||
|
my_signal(SIGKILL, ReceiveSignal);
|
||||||
|
my_signal(SIGUSR1, ReceiveSignal);
|
||||||
|
my_signal(SIGUSR2, ReceiveSignal);
|
||||||
|
my_signal(SIGHUP, ReceiveSignal);
|
||||||
|
my_signal(SIGALRM, ReceiveSignal);
|
||||||
|
my_signal(SIGVTALRM, ReceiveSignal);
|
||||||
|
#endif
|
||||||
|
#ifdef SIGPIPE
|
||||||
|
my_signal(SIGPIPE, ReceiveSignal);
|
||||||
|
#endif
|
||||||
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
SetConsoleCtrlHandler(MSCHandleSignal, TRUE);
|
||||||
|
#else
|
||||||
|
my_signal(SIGINT, ReceiveSignal);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SIGFPE
|
||||||
|
my_signal(SIGFPE, HandleMatherr);
|
||||||
|
#endif
|
||||||
|
#if HAVE_SIGSEGV
|
||||||
|
my_signal_info(SIGSEGV, HandleSIGSEGV);
|
||||||
|
#endif
|
||||||
|
#ifdef YAPOR_COW
|
||||||
|
signal(SIGCHLD, SIG_IGN); /* avoid ghosts */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Yap_set_fpu_exceptions(Term flag) {
|
||||||
|
return set_fpu_exceptions(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Yap_InitSignalPreds(void) {
|
void Yap_InitSignalPreds(void) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
Term cm = CurrentModule;
|
Term cm = CurrentModule;
|
||||||
|
Reference in New Issue
Block a user