diff --git a/C/absmi.c b/C/absmi.c index f57440884..3124d6e9b 100755 --- a/C/absmi.c +++ b/C/absmi.c @@ -593,14 +593,11 @@ check_alarm_fail_int(int CONT USES_REGS) #if defined(_MSC_VER) || defined(__MINGW32__) /* I need this for Windows and any system where SIGINT is not proceesed by same thread as absmi */ - LOCK(LOCAL_SignalLock); if (LOCAL_PrologMode & (AbortMode|InterruptMode)) { CalculateStackGap( PASS_REGS1 ); - UNLOCK(LOCAL_SignalLock); return CONT; } - UNLOCK(LOCAL_SignalLock); #endif if (Yap_has_signals( YAP_INT_SIGNAL, YAP_FAIL_SIGNAL ) ) { if (Yap_undo_signal( YAP_INT_SIGNAL ) ) { @@ -622,7 +619,7 @@ stack_overflow( CELL *env, yamop *cp USES_REGS ) { if ((Int)(Unsigned(YREG) - Unsigned(HR)) < StackGap( PASS_REGS1 ) || Yap_undo_signal( YAP_STOVF_SIGNAL )) { - if (!Yap_gc(((PredEntry *)(S))->ArityOfPE, env, cp)) { + if (!Yap_locked_gc(((PredEntry *)(S))->ArityOfPE, env, cp)) { Yap_NilError(OUT_OF_STACK_ERROR,LOCAL_ErrorMessage); return 0; } @@ -638,7 +635,7 @@ code_overflow( CELL *yenv USES_REGS ) CELL cut_b = LCL0-(CELL *)(S[E_CB]); /* do a garbage collection first to check if we can recover memory */ - if (!Yap_growheap(FALSE, 0, NULL)) { + if (!Yap_locked_growheap(FALSE, 0, NULL)) { Yap_NilError(OUT_OF_HEAP_ERROR, "YAP failed to grow heap: %s", LOCAL_ErrorMessage); return 0; } @@ -720,6 +717,7 @@ interrupt_handler( USES_REGS1 ) pe = CreepCode; } P = pe->CodeOfPred; + UNLOCK(LOCAL_SignalLock); #ifdef LOW_LEVEL_TRACER if (Yap_do_low_level_trace) low_level_trace(enter_pred,pe,XREGS+1); @@ -801,6 +799,7 @@ interrupt_fail( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif + LOCK(LOCAL_SignalLock); check_alarm_fail_int( FALSE PASS_REGS ); /* don't do debugging and stack expansion here: space will be recovered. automatically by fail, so @@ -808,6 +807,7 @@ interrupt_fail( USES_REGS1 ) */ if (!Yap_has_a_signal() || Yap_has_signals( YAP_CDOVF_SIGNAL, YAP_CREEP_SIGNAL )) { + UNLOCK(LOCAL_SignalLock); return FALSE; } S = (CELL *)RepPredProp(Yap_GetPredPropByAtom(AtomFail,0)); @@ -826,15 +826,26 @@ interrupt_execute( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( TRUE PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( TRUE PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } PP = P->u.pp.p0; - if ((PP->ExtraPredFlags & (NoDebugPredFlag|HiddenPredFlag)) && Yap_only_has_signal(YAP_CREEP_SIGNAL)) + if ((PP->ExtraPredFlags & (NoDebugPredFlag|HiddenPredFlag)) && Yap_only_has_signal(YAP_CREEP_SIGNAL)) { + UNLOCK(LOCAL_SignalLock); return 2; + } S = (CELL *) P->u.pp.p; SET_ASP(YENV, E_CB*sizeof(CELL)); - if ((v = code_overflow(YENV PASS_REGS)) >= 0) return v; - if ((v = stack_overflow(ENV, CP PASS_REGS )) >= 0) return v; + if ((v = code_overflow(YENV PASS_REGS)) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } + if ((v = stack_overflow(ENV, CP PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } return interrupt_handler( PASS_REGS1 ); } @@ -847,16 +858,27 @@ interrupt_call( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( TRUE PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( TRUE PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } PP = P->u.Osbpp.p0; if (Yap_only_has_signal(YAP_CREEP_SIGNAL) && - (PP->ExtraPredFlags & (NoDebugPredFlag|HiddenPredFlag)) ) + (PP->ExtraPredFlags & (NoDebugPredFlag|HiddenPredFlag)) ) { + UNLOCK(LOCAL_SignalLock); return 2; + } S = (CELL *) P->u.Osbpp.p; SET_ASP(YENV, P->u.Osbpp.s); - if ((v = code_overflow(YENV PASS_REGS)) >= 0) return v; - if ((v = stack_overflow(YENV, NEXTOP(P, Osbpp) PASS_REGS )) >= 0) return v; + if ((v = code_overflow(YENV PASS_REGS)) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } + if ((v = stack_overflow(YENV, NEXTOP(P, Osbpp) PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } return interrupt_handlerc( PASS_REGS1 ); } @@ -869,17 +891,28 @@ interrupt_pexecute( PredEntry *pen USES_REGS ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } PP = NULL; - if (Yap_only_has_signal(YAP_CREEP_SIGNAL)) + if (Yap_only_has_signal(YAP_CREEP_SIGNAL)) { + UNLOCK(LOCAL_SignalLock); return 2; /* keep on creeping */ + } S = (CELL *) pen; SET_ASP(YENV, E_CB*sizeof(CELL)); /* setup GB */ YENV[E_CB] = (CELL) B; - if ((v = code_overflow(YENV PASS_REGS)) >= 0) return v; - if ((v = stack_overflow(ENV, NEXTOP(P, Osbmp) PASS_REGS )) >= 0) return v; + if ((v = code_overflow(YENV PASS_REGS)) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } + if ((v = stack_overflow(ENV, NEXTOP(P, Osbmp) PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } CP = NEXTOP(P, Osbmp); return interrupt_handler( PASS_REGS1 ); } @@ -897,8 +930,11 @@ interrupt_deallocate( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( TRUE PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( TRUE PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } /* don't do a creep here; also, if our instruction is followed by a execute_c, just wait a bit more */ @@ -906,6 +942,7 @@ interrupt_deallocate( USES_REGS1 ) /* keep on going if there is something else */ (P->opc != Yap_opcode(_procceed) && P->opc != Yap_opcode(_cut_e))) { + UNLOCK(LOCAL_SignalLock); return 1; } else { CELL cut_b = LCL0-(CELL *)(S[E_CB]); @@ -914,7 +951,10 @@ interrupt_deallocate( USES_REGS1 ) ASP = YENV+E_CB; /* cut_e */ SET_ASP(YENV, E_CB*sizeof(CELL)); - if ((v = code_overflow(YENV PASS_REGS)) >= 0) return v; + if ((v = code_overflow(YENV PASS_REGS)) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } if (Yap_has_a_signal()) { if (Yap_op_from_opcode(P->opc) == _cut_e) { /* followed by a cut */ @@ -925,12 +965,13 @@ interrupt_deallocate( USES_REGS1 ) } return interrupt_handler( PASS_REGS1 ); } - if (!Yap_gc(0, ENV, CP)) { + if (!Yap_locked_gc(0, ENV, CP)) { Yap_NilError(OUT_OF_STACK_ERROR,LOCAL_ErrorMessage); } S = ASP; S[E_CB] = (CELL)(LCL0-cut_b); } + UNLOCK(LOCAL_SignalLock); return 1; } @@ -942,10 +983,13 @@ interrupt_cut( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) + if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } if (!Yap_has_a_signal() || Yap_only_has_signals(YAP_CDOVF_SIGNAL , YAP_CREEP_SIGNAL )) { + UNLOCK(LOCAL_SignalLock); return 2; } /* find something to fool S */ @@ -963,10 +1007,14 @@ interrupt_cut_t( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } if (!Yap_has_a_signal() || Yap_only_has_signals(YAP_CDOVF_SIGNAL , YAP_CREEP_SIGNAL )) { + UNLOCK(LOCAL_SignalLock); return 2; } /* find something to fool S */ @@ -984,10 +1032,14 @@ interrupt_commit_y( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } if (!Yap_has_a_signal() || Yap_only_has_signals(YAP_CDOVF_SIGNAL , YAP_CREEP_SIGNAL )) { + UNLOCK(LOCAL_SignalLock); return 2; } /* find something to fool S */ @@ -1005,10 +1057,14 @@ interrupt_commit_x( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; + } if (!Yap_has_a_signal() || Yap_only_has_signals(YAP_CDOVF_SIGNAL , YAP_CREEP_SIGNAL )) { + UNLOCK(LOCAL_SignalLock); return 2; } PP = P->u.xps.p0; @@ -1038,18 +1094,29 @@ interrupt_either( USES_REGS1 ) if (trace_interrupts) fprintf(stderr,"[%d] %lu--%lu %s:%d: (YENV=%p ENV=%p ASP=%p)\n", worker_id, LOCAL_FirstActiveSignal, LOCAL_LastActiveSignal, \ __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif - if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) + LOCK(LOCAL_SignalLock); + if ((v = check_alarm_fail_int( 2 PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); return v; - if (Yap_only_has_signal(YAP_CREEP_SIGNAL)) + } + if (Yap_only_has_signal(YAP_CREEP_SIGNAL)) { + UNLOCK(LOCAL_SignalLock); return 2; + } PP = P->u.Osblp.p0; /* find something to fool S */ S = (CELL *)RepPredProp(Yap_GetPredPropByFunc(FunctorRestoreRegs1,0)); SET_ASP(YENV, P->u.Osbpp.s); if (ASP > (CELL *)PROTECT_FROZEN_B(B)) ASP = (CELL *)PROTECT_FROZEN_B(B); - if ((v = code_overflow(YENV PASS_REGS)) >= 0) return v; - if ((v = stack_overflow(YENV, NEXTOP(P, Osbpp) PASS_REGS )) >= 0) return v; + if ((v = code_overflow(YENV PASS_REGS)) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } + if ((v = stack_overflow(YENV, NEXTOP(P, Osbpp) PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } return interrupt_handler_either( PASS_REGS1 ); } @@ -1063,8 +1130,10 @@ interrupt_dexecute( USES_REGS1 ) __FUNCTION__, __LINE__,YENV,ENV,ASP); #endif PP = P->u.pp.p0; + LOCK(LOCAL_SignalLock); if (Yap_has_signal(YAP_CREEP_SIGNAL) && (PP->ExtraPredFlags & (NoDebugPredFlag|HiddenPredFlag))) { + UNLOCK(LOCAL_SignalLock); return 2; } /* set S for next instructions */ @@ -1072,8 +1141,14 @@ interrupt_dexecute( USES_REGS1 ) ASP = YENV+E_CB; if (ASP > (CELL *)PROTECT_FROZEN_B(B)) ASP = (CELL *)PROTECT_FROZEN_B(B); - if ((v = code_overflow(YENV PASS_REGS)) >= 0) return v; - if ((v = stack_overflow((CELL *)YENV[E_E], (yamop *)YENV[E_CP] PASS_REGS )) >= 0) return v; + if ((v = code_overflow(YENV PASS_REGS)) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } + if ((v = stack_overflow((CELL *)YENV[E_E], (yamop *)YENV[E_CP] PASS_REGS )) >= 0) { + UNLOCK(LOCAL_SignalLock); + return v; + } /* first, deallocate */ CP = (yamop *) YENV[E_CP]; ENV = YENV = (CELL *) YENV[E_E]; @@ -11698,7 +11773,9 @@ Yap_absmi(int inp) /* now restore Woken Goals to its old value */ Yap_UpdateTimedVar(LOCAL_WokenGoals, OldWokenGoals); if (OldWokenGoals == TermNil) { + LOCK(LOCAL_SignalLock); Yap_undo_signal(YAP_WAKEUP_SIGNAL); + UNLOCK(LOCAL_SignalLock); } #endif /* restore B */ diff --git a/C/adtdefs.c b/C/adtdefs.c index 07e92bf65..2fd5ff7c7 100755 --- a/C/adtdefs.c +++ b/C/adtdefs.c @@ -205,9 +205,12 @@ LookupAtom(char *atom) HashChain[hash].Entry = na; INIT_RWLOCK(ae->ARWLock); WRITE_UNLOCK(HashChain[hash].AERWLock); + CACHE_REGS + LOCK(LOCAL_SignalLock); if (NOfAtoms > 2*AtomHashTableSize) { Yap_signal(YAP_CDOVF_SIGNAL); } + UNLOCK(LOCAL_SignalLock); return na; } @@ -272,9 +275,12 @@ LookupWideAtom(wchar_t *atom) WideHashChain[hash].Entry = na; INIT_RWLOCK(ae->ARWLock); WRITE_UNLOCK(WideHashChain[hash].AERWLock); + CACHE_REGS + LOCK(LOCAL_SignalLock); if (NOfWideAtoms > 2*WideAtomHashTableSize) { Yap_signal(YAP_CDOVF_SIGNAL); } + UNLOCK(LOCAL_SignalLock); return na; } @@ -306,7 +312,7 @@ Yap_LookupMaybeWideAtomWithLength(wchar_t *atom, size_t len0) { /* lookup atom in atom table */ Atom at; int wide = FALSE; - size_t i; + size_t i = 0; while (i < len0) { // primary support for atoms with null chars diff --git a/C/alloc.c b/C/alloc.c index 755364aa1..50d0a6f01 100644 --- a/C/alloc.c +++ b/C/alloc.c @@ -714,7 +714,9 @@ AllocHeap(unsigned long int size) HeapUsed += size * sizeof(CELL) + sizeof(YAP_SEG_SIZE); UNLOCK(HeapUsedLock); UNLOCK(HeapTopLock); + LOCK(LOCAL_SignalLock); Yap_signal(YAP_CDOVF_SIGNAL); + UNLOCK(LOCAL_SignalLock); } else { if (size > GLOBAL_SizeOfOverflow) GLOBAL_SizeOfOverflow = size*sizeof(CELL) + sizeof(YAP_SEG_SIZE); diff --git a/C/attvar.c b/C/attvar.c index 4e6cde4d9..1c39ad184 100644 --- a/C/attvar.c +++ b/C/attvar.c @@ -46,8 +46,10 @@ AddToQueue(attvar_record *attv USES_REGS) Yap_UpdateTimedVar(LOCAL_WokenGoals, MkPairTerm(ng, WGs)); if ((Term)WGs == TermNil) { + LOCK(LOCAL_SignalLock); /* from now on, we have to start waking up goals */ Yap_signal(YAP_WAKEUP_SIGNAL); + UNLOCK(LOCAL_SignalLock); } return(RepAppl(ng)+2); } @@ -61,10 +63,12 @@ AddFailToQueue( USES_REGS1 ) WGs = Yap_ReadTimedVar(LOCAL_WokenGoals); Yap_UpdateTimedVar(LOCAL_WokenGoals, MkPairTerm(MkAtomTerm(AtomFail), WGs)); + LOCK(LOCAL_SignalLock); if ((Term)WGs == TermNil) { /* from now on, we have to start waking up goals */ Yap_signal(YAP_WAKEUP_SIGNAL); } + UNLOCK(LOCAL_SignalLock); } static attvar_record * diff --git a/C/c_interface.c b/C/c_interface.c index 54ea251b6..b1705d93b 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -893,11 +893,14 @@ YAP_LookupAtom(char *c) while (TRUE) { a = Yap_LookupAtom(c); + LOCK(LOCAL_SignalLock); if (a == NIL || Yap_has_signal(YAP_CDOVF_SIGNAL)) { - if (!Yap_growheap(FALSE, 0, NULL)) { + if (!Yap_locked_growheap(FALSE, 0, NULL)) { Yap_Error(OUT_OF_HEAP_ERROR, TermNil, "YAP failed to grow heap: %s", LOCAL_ErrorMessage); } + UNLOCK(LOCAL_SignalLock); } else { + UNLOCK(LOCAL_SignalLock); return a; } } @@ -911,11 +914,14 @@ YAP_LookupWideAtom(wchar_t *c) while (TRUE) { a = Yap_LookupWideAtom(c); + LOCK(LOCAL_SignalLock); if (a == NIL || Yap_has_signal(YAP_CDOVF_SIGNAL)) { - if (!Yap_growheap(FALSE, 0, NULL)) { + if (!Yap_locked_growheap(FALSE, 0, NULL)) { Yap_Error(OUT_OF_HEAP_ERROR, TermNil, "YAP failed to grow heap: %s", LOCAL_ErrorMessage); } + UNLOCK(LOCAL_SignalLock); } else { + UNLOCK(LOCAL_SignalLock); return a; } } @@ -929,11 +935,14 @@ YAP_FullLookupAtom(char *c) while (TRUE) { at = Yap_FullLookupAtom(c); + LOCK(LOCAL_SignalLock); if (at == NIL || Yap_has_signal(YAP_CDOVF_SIGNAL)) { - if (!Yap_growheap(FALSE, 0, NULL)) { + if (!Yap_locked_growheap(FALSE, 0, NULL)) { Yap_Error(OUT_OF_HEAP_ERROR, TermNil, "YAP failed to grow heap: %s", LOCAL_ErrorMessage); } + UNLOCK(LOCAL_SignalLock); } else { + UNLOCK(LOCAL_SignalLock); return at; } } @@ -2953,11 +2962,13 @@ YAP_CompileClause(Term t) } YAPLeaveCriticalSection(); + LOCK(LOCAL_SignalLock); if (Yap_has_signal( YAP_CDOVF_SIGNAL ) ) { - if (!Yap_growheap(FALSE, 0, NULL)) { + if (!Yap_locked_growheap(FALSE, 0, NULL)) { Yap_Error(OUT_OF_HEAP_ERROR, TermNil, "YAP failed to grow heap: %s", LOCAL_ErrorMessage); } } + UNLOCK(LOCAL_SignalLock); RECOVER_MACHINE_REGS(); return(LOCAL_ErrorMessage); } @@ -3995,7 +4006,10 @@ YAP_SlotsToArgs(int n, Int slot) X_API void YAP_signal(int sig) { + CACHE_REGS + LOCK(LOCAL_SignalLock); Yap_signal(sig); + UNLOCK(LOCAL_SignalLock); } X_API int diff --git a/C/cdmgr.c b/C/cdmgr.c index 5a1e0de03..6d6288063 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -4866,14 +4866,14 @@ fetch_next_lu_clause_erase(PredEntry *pe, yamop *i_code, Term th, Term tb, Term ARG7 = tr; if (LOCAL_Error_TYPE == OUT_OF_ATTVARS_ERROR) { LOCAL_Error_TYPE = YAP_NO_ERROR; - if (!Yap_growglobal(NULL)) { + if (!Yap_locked_growglobal(NULL)) { UNLOCK(pe->PELock); Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, LOCAL_ErrorMessage); return FALSE; } } else { LOCAL_Error_TYPE = YAP_NO_ERROR; - if (!Yap_gcl(LOCAL_Error_Size, 7, ENV, gc_P(P,CP))) { + if (!Yap_locked_gcl(LOCAL_Error_Size, 7, ENV, gc_P(P,CP))) { UNLOCK(pe->PELock); Yap_Error(OUT_OF_STACK_ERROR, TermNil, LOCAL_ErrorMessage); return FALSE; diff --git a/C/dlmalloc.c b/C/dlmalloc.c index 9ec17147b..8ea59d5a0 100644 --- a/C/dlmalloc.c +++ b/C/dlmalloc.c @@ -210,7 +210,9 @@ yapsbrk(long size) /* small allocations, we can wait */ HeapTop += size; UNLOCK(HeapTopLock); + LOCK(LOCAL_SignalLock); Yap_signal(YAP_CDOVF_SIGNAL); + UNLOCK(LOCAL_SignalLock); } else { if (size > GLOBAL_SizeOfOverflow) GLOBAL_SizeOfOverflow = size; diff --git a/C/errors.c b/C/errors.c index 9790dd765..ce108809c 100755 --- a/C/errors.c +++ b/C/errors.c @@ -583,8 +583,10 @@ Yap_Error(yap_error_number type, Term where, char *format,...) LOCAL_CurrentError = type; LOCAL_PrologMode |= InErrorMode; /* make sure failure will be seen at next port */ + LOCK(LOCAL_SignalLock); if (LOCAL_PrologMode & AsyncIntMode) Yap_signal(YAP_FAIL_SIGNAL); + UNLOCK(LOCAL_SignalLock); P = FAILCODE; } else { if (IsVarTerm(where)) { diff --git a/C/exec.c b/C/exec.c index 66eb0e7e2..2cbf5d43d 100755 --- a/C/exec.c +++ b/C/exec.c @@ -25,6 +25,7 @@ static char SccsId[] = "@(#)cdmgr.c 1.1 05/02/98"; #include "cut_c.h" static Int CallPredicate(PredEntry *, choiceptr, yamop * CACHE_TYPE); +// must hold thread worker comm lock at call. static Int EnterCreepMode(Term, Term CACHE_TYPE); static Int p_save_cp( USES_REGS1 ); static Int p_execute( USES_REGS1 ); @@ -158,18 +159,21 @@ do_execute(Term t, Term mod USES_REGS) Term t0 = t; /* first do predicate expansion, even before you process signals. This way you don't get to spy goal_expansion(). */ + LOCK(LOCAL_SignalLock); if (PRED_GOAL_EXPANSION_ALL) { /* disable creeping when we do goal expansion */ if (!LOCAL_InterruptsDisabled && Yap_undo_signal( YAP_CREEP_SIGNAL ) ) { CalculateStackGap( PASS_REGS1 ); } + UNLOCK(LOCAL_SignalLock); return CallMetaCall(ARG1, mod PASS_REGS); } else if (Yap_has_a_signal() && !LOCAL_InterruptsDisabled && !(LOCAL_PrologMode & (AbortMode|InterruptMode|SystemMode))) { return EnterCreepMode(t, mod PASS_REGS); } + UNLOCK(LOCAL_SignalLock); restart_exec: if (IsVarTerm(t)) { return CallError(INSTANTIATION_ERROR, t0, mod PASS_REGS); @@ -330,6 +334,7 @@ do_execute_n(Term t, Term mod, unsigned int n USES_REGS) if (IsExtensionFunctor(f)) { return CallError(TYPE_ERROR_CALLABLE, t0, mod PASS_REGS); } + LOCK(LOCAL_SignalLock); if (PRED_GOAL_EXPANSION_ALL) { /* disable creeping when we do goal expansion */ if (Yap_has_signal( YAP_CREEP_SIGNAL ) && @@ -338,11 +343,13 @@ do_execute_n(Term t, Term mod, unsigned int n USES_REGS) CalculateStackGap( PASS_REGS1 ); } t = copy_execn_to_heap(f, pt, n, arity, mod PASS_REGS); - return CallMetaCall(t, mod PASS_REGS); + UNLOCK(LOCAL_SignalLock); + return CallMetaCall(t, mod PASS_REGS); } else if (Yap_has_a_signal() && !LOCAL_InterruptsDisabled) { return EnterCreepMode(copy_execn_to_heap(f, pt, n, arity, CurrentModule PASS_REGS), mod PASS_REGS); } + UNLOCK(LOCAL_SignalLock); if (arity > MaxTemps) { return CallError(TYPE_ERROR_CALLABLE, t0, mod PASS_REGS); } @@ -374,16 +381,18 @@ do_execute_n(Term t, Term mod, unsigned int n USES_REGS) return CallPredicate(pen, B, pen->CodeOfPred PASS_REGS); } +// enter locked static Int EnterCreepMode(Term t, Term mod USES_REGS) { PredEntry *PredCreep; if (Yap_has_signal( YAP_CDOVF_SIGNAL ) ) { ARG1 = t; - if (!Yap_growheap(FALSE, 0, NULL)) { + if (!Yap_locked_growheap(FALSE, 0, NULL)) { Yap_Error(OUT_OF_HEAP_ERROR, TermNil, "YAP failed to grow heap at meta-call"); } if (!Yap_has_a_signal()) { + UNLOCK(LOCAL_SignalLock); return do_execute(ARG1, mod PASS_REGS); } } @@ -398,7 +407,6 @@ EnterCreepMode(Term t, Term mod USES_REGS) { ARG1 = MkPairTerm(TermProlog,t); } } - LOCK(LOCAL_SignalLock); CalculateStackGap( PASS_REGS1 ); UNLOCK(LOCAL_SignalLock); P_before_spy = P; @@ -635,9 +643,11 @@ p_execute_clause( USES_REGS1 ) } else { code = Yap_ClauseFromTerm(clt)->ClCode; } + LOCK(LOCAL_SignalLock); if (Yap_undo_signal(YAP_CREEP_SIGNAL)) { Yap_signal(YAP_CREEP_SIGNAL); } + UNLOCK(LOCAL_SignalLock); return CallPredicate(RepPredProp(pe), cut_cp, code PASS_REGS); } @@ -656,8 +666,11 @@ p_do_goal_expansion( USES_REGS1 ) Term cmod = Deref(ARG2); ARG2 = ARG3; - if (creeping) + if (creeping) { + LOCK(LOCAL_SignalLock); Yap_undo_signal(YAP_CREEP_SIGNAL); + UNLOCK(LOCAL_SignalLock); + } /* CurMod:goal_expansion(A,B) */ if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorGoalExpansion2, cmod) ) ) && @@ -698,15 +711,18 @@ p_do_goal_expansion( USES_REGS1 ) out = TRUE; } complete: + LOCK(LOCAL_SignalLock); if (creeping) { Yap_signal( YAP_CREEP_SIGNAL ); } + UNLOCK(LOCAL_SignalLock); return out; } static Int p_do_term_expansion( USES_REGS1 ) { + LOCK(LOCAL_SignalLock); Int creeping = Yap_has_signal(YAP_CREEP_SIGNAL); Int out = FALSE; PredEntry *pe; @@ -716,6 +732,8 @@ p_do_term_expansion( USES_REGS1 ) if (creeping) Yap_undo_signal(YAP_CREEP_SIGNAL); + UNLOCK(LOCAL_SignalLock); + /* CurMod:term_expansion(A,B) */ if ( (pe = RepPredProp(Yap_GetPredPropByFunc(FunctorTermExpansion, cmod) ) ) && pe->OpcodeOfPred != FAIL_OPCODE && @@ -741,9 +759,11 @@ p_do_term_expansion( USES_REGS1 ) out = TRUE; } complete: + LOCK(LOCAL_SignalLock); if (creeping) { Yap_signal(YAP_CREEP_SIGNAL); } + UNLOCK(LOCAL_SignalLock); return out; } @@ -755,10 +775,12 @@ p_execute0( USES_REGS1 ) unsigned int arity; Prop pe; + LOCK(LOCAL_SignalLock); if (Yap_has_a_signal() && !LOCAL_InterruptsDisabled) { return EnterCreepMode(t, mod PASS_REGS); } + UNLOCK(LOCAL_SignalLock); restart_exec: if (IsVarTerm(t)) { Yap_Error(INSTANTIATION_ERROR,ARG3,"call/1"); @@ -885,6 +907,7 @@ p_execute_nonstop( USES_REGS1 ) } /* N = arity; */ /* call may not define new system predicates!! */ + LOCK(LOCAL_SignalLock); if (RepPredProp(pe)->PredFlags & SpiedPredFlag) { if (!LOCAL_InterruptsDisabled && Yap_undo_signal(YAP_CREEP_SIGNAL)) { @@ -895,6 +918,7 @@ p_execute_nonstop( USES_REGS1 ) PP = RepPredProp(pe); PELOCK(80,PP); } + UNLOCK(LOCAL_SignalLock); #endif return CallPredicate(RepPredProp(pe), B, RepPredProp(pe)->cs.p_code.TrueCodeOfPred PASS_REGS); } else { if (Yap_has_signal( YAP_CREEP_SIGNAL ) && @@ -903,6 +927,7 @@ p_execute_nonstop( USES_REGS1 ) RepPredProp(pe)->OpcodeOfPred == Yap_opcode(_call_bfunc_xx))) { Yap_signal(YAP_CREEP_SIGNAL); } + UNLOCK(LOCAL_SignalLock); return CallPredicate(RepPredProp(pe), B, RepPredProp(pe)->CodeOfPred PASS_REGS); } } @@ -1108,9 +1133,11 @@ exec_absmi(int top USES_REGS) YENV[E_CB] = Unsigned (B); out = Yap_absmi(0); /* make sure we don't leave a FAIL signal hanging around */ + LOCK(LOCAL_SignalLock); Yap_undo_signal( YAP_FAIL_SIGNAL ); if (!Yap_has_a_signal()) CalculateStackGap( PASS_REGS1 ); + UNLOCK(LOCAL_SignalLock); return out; } @@ -1628,9 +1655,11 @@ JumpToEnv(Term t USES_REGS) { LOCAL_BallTerm = NULL; P = (yamop *)FAILCODE; /* make sure failure will be seen at next port */ + LOCK(LOCAL_SignalLock); if (LOCAL_PrologMode & AsyncIntMode) { Yap_signal(YAP_FAIL_SIGNAL); } + UNLOCK(LOCAL_SignalLock); HB = B->cp_h; return TRUE; } @@ -1676,9 +1705,11 @@ JumpToEnv(Term t USES_REGS) { /* B->cp_h = H; */ /* I could backtrack here, but it is easier to leave the unwinding to the emulator */ + LOCK(LOCAL_SignalLock); if (LOCAL_PrologMode & AsyncIntMode) { Yap_signal(YAP_FAIL_SIGNAL); } + UNLOCK(LOCAL_SignalLock); P = (yamop *)FAILCODE; HB = B->cp_h; /* try to recover space */ diff --git a/C/grow.c b/C/grow.c index a4febce8f..0d405b713 100755 --- a/C/grow.c +++ b/C/grow.c @@ -129,10 +129,8 @@ SetHeapRegs(int copying_threads USES_REGS) ASP = PtoLocAdjust(ASP); if (H0) H0 = PtoGloAdjust(H0); - LOCK(LOCAL_SignalLock); if (LCL0) LCL0 = PtoLocAdjust(LCL0); - UNLOCK(LOCAL_SignalLock); if (HR) HR = PtoGloAdjust(HR); if (Yap_REGS.CUT_C_TOP) @@ -819,9 +817,7 @@ static_growheap(long size, int fix_code, struct intermediates *cip, tr_fr_ptr *o } /* CreepFlag is set to force heap expansion */ if ( Yap_only_has_signal( YAP_CDOVF_SIGNAL) ) { - LOCK(LOCAL_SignalLock); CalculateStackGap( PASS_REGS1 ); - UNLOCK(LOCAL_SignalLock); } ASP -= 256; LOCAL_TrDiff = LOCAL_LDiff = LOCAL_GDiff = LOCAL_GDiff0 = LOCAL_DelayDiff = LOCAL_BaseDiff = size; @@ -1417,7 +1413,7 @@ growatomtable( USES_REGS1 ) int -Yap_growheap(int fix_code, size_t in_size, void *cip) +Yap_locked_growheap(int fix_code, size_t in_size, void *cip) { CACHE_REGS int res; @@ -1459,6 +1455,17 @@ Yap_growheap(int fix_code, size_t in_size, void *cip) return res; } +int +Yap_growheap(int fix_code, size_t in_size, void *cip) +{ + CACHE_REGS + int rc; + LOCK(LOCAL_SignalLock); + rc = Yap_locked_growheap(fix_code, in_size, cip); + UNLOCK(LOCAL_SignalLock); + return rc; +} + int Yap_growheap_in_parser(tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep) { @@ -1471,7 +1478,7 @@ Yap_growheap_in_parser(tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep) } int -Yap_growglobal(CELL **ptr) +Yap_locked_growglobal(CELL **ptr) { CACHE_REGS unsigned long sz = sizeof(CELL) * K16; @@ -1495,6 +1502,16 @@ Yap_growglobal(CELL **ptr) return TRUE; } +int +Yap_growglobal(CELL **ptr) +{ + CACHE_REGS + int rc; + LOCK(LOCAL_SignalLock); + rc = Yap_locked_growglobal(ptr); + UNLOCK(LOCAL_SignalLock); + return rc; +} UInt Yap_InsertInGlobal(CELL *where, UInt howmuch) @@ -1510,7 +1527,7 @@ Yap_InsertInGlobal(CELL *where, UInt howmuch) int -Yap_growstack(size_t size) +Yap_locked_growstack(size_t size) { CACHE_REGS int res; @@ -1521,6 +1538,20 @@ Yap_growstack(size_t size) return res; } +int +Yap_growstack(size_t size) +{ + CACHE_REGS + int res; + + LOCAL_PrologMode |= GrowStackMode; + LOCK(LOCAL_SignalLock); + res=growstack(size PASS_REGS); + LeaveGrowMode(GrowStackMode); + UNLOCK(LOCAL_SignalLock); + return res; +} + static int execute_growstack(long size0, int from_trail, int in_parser, tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep USES_REGS) { @@ -1780,6 +1811,18 @@ static int do_growtrail(long size, int contiguous_only, int in_parser, tr_fr_ptr /* Used by do_goal() when we're short of stack space */ int Yap_growtrail(long size, int contiguous_only) +{ + int rc; + CACHE_REGS + LOCK(LOCAL_SignalLock); + rc = do_growtrail(size, contiguous_only, FALSE, NULL, NULL, NULL PASS_REGS); + UNLOCK(LOCAL_SignalLock); + return rc; +} + +/* Used by do_goal() when we're short of stack space */ +int +Yap_locked_growtrail(long size, int contiguous_only) { CACHE_REGS return do_growtrail(size, contiguous_only, FALSE, NULL, NULL, NULL PASS_REGS); diff --git a/C/heapgc.c b/C/heapgc.c index 247b41253..7eac9e03f 100755 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -4250,7 +4250,7 @@ call_gc(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop USES_REGS) CalculateStackGap( PASS_REGS1 ); if (gc_margin < 2*EventFlag) gc_margin = 2*EventFlag; - return Yap_growstack(gc_margin); + return Yap_locked_growstack(gc_margin); #endif } /* @@ -4275,6 +4275,17 @@ LeaveGCMode( USES_REGS1 ) int Yap_gc(Int predarity, CELL *current_env, yamop *nextop) +{ + CACHE_REGS + int rc; + LOCK(LOCAL_SignalLock); + rc = Yap_locked_gc(predarity, current_env, nextop); + UNLOCK(LOCAL_SignalLock); + return rc; +} + +int +Yap_locked_gc(Int predarity, CELL *current_env, yamop *nextop) { CACHE_REGS int res; @@ -4297,6 +4308,25 @@ Yap_gcl(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop) int res; UInt min; + LOCK(LOCAL_SignalLock); + CalculateStackGap( PASS_REGS1 ); + min = EventFlag*sizeof(CELL); + LOCAL_PrologMode |= GCMode; + if (gc_lim < min) + gc_lim = min; + res = call_gc(gc_lim, predarity, current_env, nextop PASS_REGS); + LeaveGCMode( PASS_REGS1 ); + UNLOCK(LOCAL_SignalLock); + return res; +} + +int +Yap_locked_gcl(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop) +{ + CACHE_REGS + int res; + UInt min; + CalculateStackGap( PASS_REGS1 ); min = EventFlag*sizeof(CELL); LOCAL_PrologMode |= GCMode; diff --git a/C/inlines.c b/C/inlines.c index df8b4c315..648c0c996 100644 --- a/C/inlines.c +++ b/C/inlines.c @@ -432,9 +432,11 @@ p_dif( USES_REGS1 ) #ifdef COROUTINING /* now restore Woken Goals to its old value */ Yap_UpdateTimedVar(LOCAL_WokenGoals, OldWokenGoals); + LOCK(LOCAL_SignalLock); if (OldWokenGoals == TermNil) { Yap_undo_signal(YAP_WAKEUP_SIGNAL); } + UNLOCK(LOCAL_SignalLock); #endif /* restore B */ B = pt1; diff --git a/C/pl-yap.c b/C/pl-yap.c index d6211cc8d..563934770 100755 --- a/C/pl-yap.c +++ b/C/pl-yap.c @@ -1182,23 +1182,26 @@ PL_w32thread_raise(DWORD id, int sig) if ( sig < 0 || sig > MAXSIGNAL ) return FALSE; /* illegal signal */ - LOCK(); - for(i = 0; i <= thread_highest_id; i++) - { PL_thread_info_t *info = GD->thread.threads[i]; - - if ( info && info->w32id == id && info->thread_data ) - { - Sfprintf(GLOBAL_stderr, "post %d %d\n\n\n",i, sig); - Yap_external_signal(i, sig); //raiseSignal(info->thread_data, sig); - if ( info->w32id ) - PostThreadMessage(info->w32id, WM_SIGNALLED, 0, 0L); - UNLOCK(); - DEBUG(1, Sdprintf("Signalled %d to thread %d\n", sig, i)); - return TRUE; - } - } + LOCK(); + LOCK(LOCAL_SignalLock); + for(i = 0; i <= thread_highest_id; i++) + { PL_thread_info_t *info = GD->thread.threads[i]; + + if ( info && info->w32id == id && info->thread_data ) + { + Sfprintf(GLOBAL_stderr, "post %d %d\n\n\n",i, sig); + Yap_external_signal(i, sig); //raiseSignal(info->thread_data, sig); + if ( info->w32id ) + PostThreadMessage(info->w32id, WM_SIGNALLED, 0, 0L); + UNLOCK(LOCAL_SignalLock); + UNLOCK(); + DEBUG(1, Sdprintf("Signalled %d to thread %d\n", sig, i)); + return TRUE; + } + } + UNLOCK(LOCAL_SignalLock); UNLOCK(); - + return FALSE; /* can't find thread */ } @@ -1213,19 +1216,6 @@ PL_w32thread_raise(DWORD id, int sig) #endif /*__WINDOWS__*/ -X_API int -PL_raise(int sig) -{ - if (sig < SIG_PROLOG_OFFSET) { - Yap_signal(YAP_INT_SIGNAL); - return 1; - } else if (sig == SIG_PLABORT) { - YAP_signal(0x40); /* YAP_INT_SIGNAL */ - return 1; - } - return 0; -} - extern size_t PL_utf8_strlen(const char *s, size_t len); X_API size_t @@ -1374,19 +1364,6 @@ sysError(const char *fm, ...) PL_fail; } -int -raiseSignal(PL_local_data_t *ld, int sig) -{ -#if THREADS - if (sig == SIG_THREAD_SIGNAL) { - Yap_signal(YAP_ITI_SIGNAL); - return TRUE; - } -#endif - fprintf(stderr, "Unsupported signal %d\n", sig); - return FALSE; -} - Int Yap_source_line_no( void ) { GET_LD diff --git a/C/signals.c b/C/signals.c index 94914254a..6c7f1fb33 100755 --- a/C/signals.c +++ b/C/signals.c @@ -45,7 +45,6 @@ inline static void do_signal(int wid, yap_signals sig USES_REGS) { #if THREADS - LOCK(REMOTE_SignalLock(wid)); if (!REMOTE_InterruptsDisabled(wid)) { REMOTE_ThreadHandle(wid).current_yaam_regs->CreepFlag_ = Unsigned(REMOTE_ThreadHandle(wid).current_yaam_regs->LCL0_); @@ -57,7 +56,6 @@ do_signal(int wid, yap_signals sig USES_REGS) if (REMOTE_FirstActiveSignal(wid) != REMOTE_LastActiveSignal(wid)) { do { if (sig == REMOTE_ActiveSignals(wid)[i]) { - UNLOCK(REMOTE_SignalLock(wid)); return; } i++; @@ -69,7 +67,6 @@ do_signal(int wid, yap_signals sig USES_REGS) REMOTE_LastActiveSignal(wid)++; if (REMOTE_LastActiveSignal(wid) == REMOTE_MaxActiveSignals(wid)) REMOTE_LastActiveSignal(wid) = 0; - UNLOCK(REMOTE_SignalLock(wid)); #else if (!LOCAL_InterruptsDisabled) { CreepFlag = @@ -99,7 +96,6 @@ do_signal(int wid, yap_signals sig USES_REGS) inline static int undo_signal(yap_signals sig USES_REGS) { - LOCK(LOCAL_SignalLock); UInt i = LOCAL_FirstActiveSignal; if (LOCAL_FirstActiveSignal != LOCAL_LastActiveSignal) { do { @@ -111,7 +107,6 @@ undo_signal(yap_signals sig USES_REGS) } while (i != LOCAL_LastActiveSignal); } if (i == LOCAL_LastActiveSignal) { - UNLOCK(LOCAL_SignalLock); return FALSE; } while ((i+1) % LOCAL_MaxActiveSignals != LOCAL_LastActiveSignal) { @@ -125,7 +120,6 @@ undo_signal(yap_signals sig USES_REGS) if (LOCAL_FirstActiveSignal != LOCAL_LastActiveSignal) { CalculateStackGap( PASS_REGS1 ); } - UNLOCK(LOCAL_SignalLock); return TRUE; } @@ -138,7 +132,9 @@ p_creep( USES_REGS1 ) at = AtomCreep; pred = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, 1),0)); CreepCode = pred; + LOCK(LOCAL_SignalLock); do_signal(worker_id, YAP_CREEP_SIGNAL PASS_REGS); + UNLOCK(LOCAL_SignalLock); return TRUE; } @@ -151,30 +147,32 @@ p_creep_fail( USES_REGS1 ) at = AtomCreep; pred = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, 1),0)); CreepCode = pred; + LOCK(LOCAL_SignalLock); do_signal(worker_id, YAP_CREEP_SIGNAL PASS_REGS); + UNLOCK(LOCAL_SignalLock); return FALSE; } static Int p_stop_creeping( USES_REGS1 ) { + LOCK(LOCAL_SignalLock); undo_signal( YAP_CREEP_SIGNAL PASS_REGS ); + UNLOCK(LOCAL_SignalLock); return TRUE; } static Int p_creep_allowed( USES_REGS1 ) { + LOCK(LOCAL_SignalLock); if (PP != NULL) { undo_signal(YAP_CREEP_SIGNAL PASS_REGS); - LOCK(LOCAL_SignalLock); if (!LOCAL_InterruptsDisabled) { if (LOCAL_FirstActiveSignal == LOCAL_LastActiveSignal) CalculateStackGap( PASS_REGS1 ); - UNLOCK(LOCAL_SignalLock); - } else { - UNLOCK(LOCAL_SignalLock); } + UNLOCK(LOCAL_SignalLock); return TRUE; } UNLOCK(LOCAL_SignalLock); @@ -206,12 +204,10 @@ Yap_undo_signal__(yap_signals sig USES_REGS) int Yap_has_signal__(yap_signals sig USES_REGS) { - LOCK(LOCAL_SignalLock); UInt i = LOCAL_FirstActiveSignal; if (LOCAL_FirstActiveSignal != LOCAL_LastActiveSignal) { do { if (sig == LOCAL_ActiveSignals[i]) { - UNLOCK(LOCAL_SignalLock); return TRUE; } i++; @@ -219,20 +215,18 @@ Yap_has_signal__(yap_signals sig USES_REGS) i = 0; } while (i != LOCAL_LastActiveSignal); } - UNLOCK(LOCAL_SignalLock); return FALSE; } +// the caller holds the lock. int Yap_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) { - LOCK(LOCAL_SignalLock); UInt i = LOCAL_FirstActiveSignal; if (LOCAL_FirstActiveSignal != LOCAL_LastActiveSignal) { do { if (sig1 == LOCAL_ActiveSignals[i] || sig2 == LOCAL_ActiveSignals[i]) { - UNLOCK(LOCAL_SignalLock); return TRUE; } i++; @@ -240,7 +234,6 @@ Yap_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) i = 0; } while (i != LOCAL_LastActiveSignal); } - UNLOCK(LOCAL_SignalLock); return FALSE; } @@ -248,12 +241,10 @@ Yap_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) int Yap_only_has_signal__(yap_signals sig USES_REGS) { - LOCK(LOCAL_SignalLock); UInt i = LOCAL_FirstActiveSignal; if (LOCAL_FirstActiveSignal != LOCAL_LastActiveSignal) { do { if (sig != LOCAL_ActiveSignals[i]) { - UNLOCK(LOCAL_SignalLock); return FALSE; } i++; @@ -261,23 +252,19 @@ Yap_only_has_signal__(yap_signals sig USES_REGS) i = 0; } while (i != LOCAL_LastActiveSignal); } else { - UNLOCK(LOCAL_SignalLock); return FALSE; } - UNLOCK(LOCAL_SignalLock); return TRUE; } int Yap_only_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) { - LOCK(LOCAL_SignalLock); UInt i = LOCAL_FirstActiveSignal; if (LOCAL_FirstActiveSignal != LOCAL_LastActiveSignal) { do { if (sig1 != LOCAL_ActiveSignals[i] && sig2 != LOCAL_ActiveSignals[i]) { - UNLOCK(LOCAL_SignalLock); return FALSE; } i++; @@ -285,10 +272,8 @@ Yap_only_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) i = 0; } while (i != LOCAL_LastActiveSignal); } else { - UNLOCK(LOCAL_SignalLock); return FALSE; } - UNLOCK(LOCAL_SignalLock); return TRUE; } diff --git a/C/sysbits.c b/C/sysbits.c index e096b60e6..917f5bd5f 100755 --- a/C/sysbits.c +++ b/C/sysbits.c @@ -1538,10 +1538,6 @@ ProcessSIGINT(void) #if !_MSC_VER && !defined(__MINGW32__) -#if HAVE_SIGNAL -static int snoozing = FALSE; -#endif - /* This function is called from the signal handler to process signals. We assume we are within the context of the signal handler, whatever that might be diff --git a/C/threads.c b/C/threads.c index 321b28e16..527e5777d 100755 --- a/C/threads.c +++ b/C/threads.c @@ -1038,9 +1038,12 @@ Yap_InitFirstWorkerThreadHandle(void) LOCAL_ThreadHandle.ref_count = 1; } +FILE *debugf; void Yap_InitThreadPreds(void) { + + Yap_InitCPred("$no_threads", 0, p_no_threads, 0); Yap_InitCPred("$max_workers", 1, p_max_workers, 0); Yap_InitCPred("$max_threads", 1, p_max_threads, 0); diff --git a/H/Yapproto.h b/H/Yapproto.h index 5610595cb..b081fc3bf 100755 --- a/H/Yapproto.h +++ b/H/Yapproto.h @@ -213,6 +213,10 @@ int Yap_growheap(int, size_t, void *); int Yap_growstack( size_t ); int Yap_growtrail(long, int); int Yap_growglobal(CELL **); +int Yap_locked_growheap(int, size_t, void *); +int Yap_locked_growstack( size_t ); +int Yap_locked_growtrail(long, int); +int Yap_locked_growglobal(CELL **); CELL **Yap_shift_visit(CELL **, CELL ***, CELL ***); #ifdef THREADS void Yap_CopyThreadStacks(int, int, int); @@ -223,7 +227,9 @@ Int Yap_total_gc_time(void); void Yap_init_gc(void); int Yap_is_gc_verbose(void); int Yap_gc(Int, CELL *, yamop *); +int Yap_locked_gc(Int, CELL *, yamop *); int Yap_gcl(UInt, Int, CELL *, yamop *); +int Yap_locked_gcl(UInt, Int, CELL *, yamop *); /* init.c */ #ifdef DEBUG diff --git a/H/pl-incl.h b/H/pl-incl.h index 55a44a7db..2e7e36454 100755 --- a/H/pl-incl.h +++ b/H/pl-incl.h @@ -231,19 +231,6 @@ typedef struct record * Record; #define MAXSIGNAL 64 -#define SIG_PROLOG_OFFSET 32 /* Start of Prolog signals */ - -#define SIG_EXCEPTION (SIG_PROLOG_OFFSET+0) -#ifdef O_ATOMGC -#define SIG_ATOM_GC (SIG_PROLOG_OFFSET+1) -#endif -#define SIG_GC (SIG_PROLOG_OFFSET+2) -#ifdef O_PLMT -#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET+3) -#endif -#define SIG_FREECLAUSES (SIG_PROLOG_OFFSET+4) -#define SIG_PLABORT (SIG_PROLOG_OFFSET+5) - #define LOCAL_OVERFLOW (-1) #define GLOBAL_OVERFLOW (-2) #define TRAIL_OVERFLOW (-3) diff --git a/H/pl-shared.h b/H/pl-shared.h index 83c02b726..2b38bac18 100755 --- a/H/pl-shared.h +++ b/H/pl-shared.h @@ -266,6 +266,19 @@ COMMON(int) debugmode(debug_type new, debug_type *old); COMMON(int) tracemode(debug_type new, debug_type *old); COMMON(void) Yap_setCurrentSourceLocation( void *rd ); +#define SIG_PROLOG_OFFSET 32 /* Start of Prolog signals */ + +#define SIG_EXCEPTION (SIG_PROLOG_OFFSET+0) +#ifdef O_ATOMGC +#define SIG_ATOM_GC (SIG_PROLOG_OFFSET+1) +#endif +#define SIG_GC (SIG_PROLOG_OFFSET+2) +#ifdef O_PLMT +#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET+3) +#endif +#define SIG_FREECLAUSES (SIG_PROLOG_OFFSET+4) +#define SIG_PLABORT (SIG_PROLOG_OFFSET+5) + extern int raiseSignal(PL_local_data_t *ld, int sig); #ifdef YATOM_H diff --git a/OPTYap/locks_pthread.h b/OPTYap/locks_pthread.h index f4fa59b6c..dbec9676d 100755 --- a/OPTYap/locks_pthread.h +++ b/OPTYap/locks_pthread.h @@ -20,17 +20,20 @@ //#define DEBUG_LOCKS 1 #if DEBUG_LOCKS +#include + int Yap_ThreadID( void ); extern int debug_locks; +extern FILE *debugf; #endif #define INIT_LOCK(LOCK_VAR) pthread_mutex_init(&(LOCK_VAR), NULL) #define DESTROY_LOCK(LOCK_VAR) pthread_mutex_destroy(&(LOCK_VAR)) #define TRY_LOCK(LOCK_VAR) pthread_mutex_trylock(&(LOCK_VAR)) #if DEBUG_LOCKS -#define LOCK(LOCK_VAR) (void)(debug_locks && fprintf(stderr,"[%d] %s:%d: LOCK(%p)\n", Yap_ThreadID(), \ - __BASE_FILE__, __LINE__,&(LOCK_VAR)) && pthread_mutex_lock(&(LOCK_VAR)) ) -#define UNLOCK(LOCK_VAR) (void)( debug_locks && fprintf(stderr,"[%d] %s:%d: UNLOCK(%p)\n", Yap_ThreadID(),__BASE_FILE__, __LINE__,&(LOCK_VAR)) && pthread_mutex_unlock(&(LOCK_VAR)) ) +#define LOCK(LOCK_VAR) (void)(fprintf(debugf,"[%d] %s:%d: LOCK(%p)\n", Yap_ThreadID(), \ + __BASE_FILE__, __LINE__,&(LOCK_VAR)) && pthread_mutex_lock(&(LOCK_VAR)) ) +#define UNLOCK(LOCK_VAR) (void)(fprintf(debugf, "[%d] %s:%d: UNLOCK(%p)\n", Yap_ThreadID(),__BASE_FILE__, __LINE__,&(LOCK_VAR)) && pthread_mutex_unlock(&(LOCK_VAR)) ) #else #define LOCK(LOCK_VAR) pthread_mutex_lock(&(LOCK_VAR)) #define UNLOCK(LOCK_VAR) pthread_mutex_unlock(&(LOCK_VAR)) diff --git a/console/yap.c b/console/yap.c index f9c546169..48dc0575d 100755 --- a/console/yap.c +++ b/console/yap.c @@ -131,6 +131,8 @@ exec_top_level(int BootMode, YAP_init_args *iap) YAP_Exit(EXIT_SUCCESS); } +FILE *debugf; + #ifdef LIGHT int _main (int argc, char **argv) @@ -143,7 +145,13 @@ main (int argc, char **argv) YAP_init_args init_args; int i; - +#if DEBUG_LOCKS + char buf[1024]; + sprintf(buf, "/tmp/yap%d", getpid()); + debugf= fopen(buf, "w"); + if (!debugf) fprintf(stderr,"ERROR %s\n", strerror(errno)); + setvbuf( debugf,NULL, _IOLBF, 1024); +#endif BootMode = init_standard_system(argc, argv, &init_args); if (BootMode == YAP_BOOT_ERROR) { fprintf(stderr,"[ FATAL ERROR: could not find saved state ]\n"); diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index 9d1e8c91f..023631e11 100755 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -2994,6 +2994,41 @@ FILE *Yap_FileDescriptorFromStream(Term t) return NULL; } +X_API int +PL_raise(int sig) +{ + CACHE_REGS + LOCK(LOCAL_SignalLock); + if (sig < SIG_PROLOG_OFFSET) { + Yap_signal(YAP_INT_SIGNAL); + UNLOCK(LOCAL_SignalLock); + return 1; + } else if (sig == SIG_PLABORT) { + Yap_signal(0x40); /* YAP_INT_SIGNAL */ + LOCK(LOCAL_SignalLock); + return 1; + } + UNLOCK(LOCAL_SignalLock); + return 0; +} + +int +raiseSignal(PL_local_data_t *ld, int sig) +{ +#if THREADS + CACHE_REGS + if (sig == SIG_THREAD_SIGNAL) { + LOCK(LOCAL_SignalLock); + Yap_signal(YAP_ITI_SIGNAL); + UNLOCK(LOCAL_SignalLock); + return TRUE; + } +#endif + fprintf(stderr, "Unsupported signal %d\n", sig); + return FALSE; +} + + #if THREADS void Yap_LockStream(IOSTREAM *s) {