diff --git a/C/absmi.c b/C/absmi.c index 1de866d5b..c63851073 100755 --- a/C/absmi.c +++ b/C/absmi.c @@ -2652,6 +2652,12 @@ Yap_absmi(int inp) NoStackCall: PP = PREG->u.Osbpp.p0; /* on X86 machines S will not actually be holding the pointer to pred */ + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } if (ActiveSignals & YAP_CREEP_SIGNAL) { PredEntry *ap = PREG->u.Osbpp.p; SREG = (CELL *) ap; @@ -2687,6 +2693,12 @@ Yap_absmi(int inp) { CELL cut_b = LCL0-(CELL *)(SREG[E_CB]); + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } /* don't do a creep here; also, if our instruction is followed by a execute_c, just wait a bit more */ @@ -2735,6 +2747,12 @@ Yap_absmi(int inp) if (!ActiveSignals || ActiveSignals & YAP_CDOVF_SIGNAL) { goto do_commit_b_y; } + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + FAIL(); + } if (!(ActiveSignals & YAP_CREEP_SIGNAL)) { SREG = (CELL *)RepPredProp(Yap_GetPredPropByFunc(FunctorRestoreRegs,0)); XREGS[0] = YREG[PREG->u.yp.y]; @@ -2751,6 +2769,12 @@ Yap_absmi(int inp) if (!ActiveSignals || ActiveSignals & YAP_CDOVF_SIGNAL) { goto do_commit_b_x; } + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + FAIL(); + } if (!(ActiveSignals & YAP_CREEP_SIGNAL)) { SREG = (CELL *)RepPredProp(Yap_GetPredPropByFunc(FunctorRestoreRegs,0)); #if USE_THREADED_CODE @@ -2777,8 +2801,15 @@ Yap_absmi(int inp) /* Problem: have I got an environment or not? */ NoStackFail: + if (ActiveSignals && ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + /* we're happy */ + goto fail; + } /* find something to fool S */ - if (!ActiveSignals || ActiveSignals & YAP_CDOVF_SIGNAL) { + if (!ActiveSignals || ActiveSignals & (YAP_CDOVF_SIGNAL)) { goto fail; } if (!(ActiveSignals & YAP_CREEP_SIGNAL)) { @@ -2793,6 +2824,12 @@ Yap_absmi(int inp) /* don't forget I cannot creep at ; */ NoStackEither: + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } PP = PREG->u.Osblp.p0; if (ActiveSignals & YAP_CREEP_SIGNAL) { goto either_notest; @@ -2870,6 +2907,12 @@ Yap_absmi(int inp) goto creep; NoStackDExecute: + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } PP = PREG->u.pp.p0; if (ActiveSignals & YAP_CREEP_SIGNAL) { PredEntry *ap = PREG->u.pp.p; @@ -2942,6 +2985,12 @@ Yap_absmi(int inp) /* try performing garbage collection */ + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } ASP = YREG+E_CB; if (ASP > (CELL *)PROTECT_FROZEN_B(B)) ASP = (CELL *)PROTECT_FROZEN_B(B); @@ -2985,6 +3034,12 @@ Yap_absmi(int inp) /* and now CREEP */ creep: + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } #if defined(_MSC_VER) || defined(__MINGW32__) /* I need this for Windows and other systems where SIGINT is not proceesed by same thread as absmi */ @@ -13848,6 +13903,12 @@ Yap_absmi(int inp) ENDD(d0); NoStackPExecute2: + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } PP = PredMetaCall; SREG = (CELL *) pen; ASP = ENV_YREG; @@ -14047,6 +14108,12 @@ Yap_absmi(int inp) ENDD(d0); NoStackPExecute: + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } PP = PredMetaCall; SREG = (CELL *) pen; ASP = ENV_YREG; @@ -14317,6 +14384,12 @@ Yap_absmi(int inp) ENDD(d0); ENDP(pt0); NoStackPTExecute: + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); + goto fail; + } PP = NULL; WRITEBACK_Y_AS_ENV(); SREG = (CELL *) pen; diff --git a/C/errors.c b/C/errors.c index f372b9828..bb2ff55e0 100644 --- a/C/errors.c +++ b/C/errors.c @@ -455,6 +455,7 @@ Yap_Error(yap_error_number type, Term where, char *format,...) where = TermNil; Yap_PrologMode &= ~AbortMode; Yap_PrologMode |= InErrorMode; + Yap_signal(YAP_FAIL_SIGNAL); P = FAILCODE; } else { if (IsVarTerm(where)) { @@ -1874,7 +1875,6 @@ Yap_Error(yap_error_number type, Term where, char *format,...) } else { if (type == PURE_ABORT) { Yap_JumpToEnv(MkAtomTerm(AtomDAbort)); - CreepFlag = LCL0-ASP; } else Yap_JumpToEnv(Yap_MkApplTerm(fun, 2, nt)); P = (yamop *)FAILCODE; diff --git a/C/exec.c b/C/exec.c index 7588b175b..db6e3a9f0 100644 --- a/C/exec.c +++ b/C/exec.c @@ -971,6 +971,8 @@ exec_absmi(int top) ASP = (CELL *)PROTECT_FROZEN_B(B); Yap_StartSlots(); LOCK(SignalLock); + /* forget any signals active, we're reborne */ + ActiveSignals = 0; CreepFlag = CalculateStackGap(); Yap_PrologMode = UserMode; UNLOCK(SignalLock); @@ -1002,6 +1004,10 @@ exec_absmi(int top) Yap_CloseSlots(); out = Yap_absmi(0); Yap_StartSlots(); + /* make sure we don't leave a FAIL signal hanging around */ + ActiveSignals &= ~YAP_FAIL_SIGNAL; + if (!ActiveSignals) + CreepFlag = CalculateStackGap(); return out; } @@ -1505,6 +1511,7 @@ JumpToEnv(Term t) { EX = BallTerm; BallTerm = NULL; P = (yamop *)FAILCODE; + Yap_signal(YAP_FAIL_SIGNAL); HB = B->cp_h; return TRUE; } @@ -1546,6 +1553,7 @@ JumpToEnv(Term t) { /* B->cp_h = H; */ /* I could backtrack here, but it is easier to leave the unwinding to the emulator */ + Yap_signal(YAP_FAIL_SIGNAL); P = (yamop *)FAILCODE; HB = B->cp_h; /* try to recover space */ diff --git a/C/sysbits.c b/C/sysbits.c index 30491f445..a889d4a81 100755 --- a/C/sysbits.c +++ b/C/sysbits.c @@ -2987,8 +2987,16 @@ p_first_signal(void) UNLOCK(SignalLock); return Yap_unify(ARG1, MkAtomTerm(AtomSigStatistics)); } + if (ActiveSignals & YAP_FAIL_SIGNAL) { + ActiveSignals &= ~YAP_FAIL_SIGNAL; #ifdef THREADS pthread_mutex_unlock(&(MY_ThreadHandle.tlock)); +#endif + UNLOCK(SignalLock); + return Yap_unify(ARG1, MkAtomTerm(AtomFail)); + } +#ifdef THREADS + pthread_mutex_unlock(&(MY_ThreadHandle.tlock)); #endif UNLOCK(SignalLock); return FALSE; @@ -3040,6 +3048,9 @@ p_continue_signals(void) if (ActiveSignals & YAP_STATISTICS_SIGNAL) { Yap_signal(YAP_STATISTICS_SIGNAL); } + if (ActiveSignals & YAP_FAIL_SIGNAL) { + Yap_signal(YAP_FAIL_SIGNAL); + } #ifdef THREADS pthread_mutex_unlock(&(MY_ThreadHandle.tlock)); #endif diff --git a/H/Yap.h b/H/Yap.h index 90dfbac5c..6db98bdda 100755 --- a/H/Yap.h +++ b/H/Yap.h @@ -620,7 +620,8 @@ typedef enum YAP_DELAY_CREEP_SIGNAL = 0x10000, /* received a creep but should not do it */ YAP_AGC_SIGNAL = 0x20000, /* call atom garbage collector asap */ YAP_PIPE_SIGNAL = 0x40000, /* call atom garbage collector asap */ - YAP_VTALARM_SIGNAL = 0x80000 /* received SIGVTALARM */ + YAP_VTALARM_SIGNAL = 0x80000, /* received SIGVTALARM */ + YAP_FAIL_SIGNAL = 0x100000 /* P = FAILCODE */ } yap_signals; #define NUMBER_OF_YAP_FLAGS LAST_FLAG diff --git a/pl/signals.yap b/pl/signals.yap index 2ba46821e..298e7bf93 100644 --- a/pl/signals.yap +++ b/pl/signals.yap @@ -89,6 +89,9 @@ '$continue_signals', statistics, '$execute0'(G,M). +% the next one should never be called... +'$do_signal'(fail, [_|_]) :- + fail. '$do_signal'(sig_stack_dump, [M|G]) :- '$continue_signals', '$stack_dump',