diff --git a/C/dbase.c b/C/dbase.c index 44ddfa0b4..2a04763c4 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -4944,6 +4944,42 @@ Yap_FetchTermFromDB(DBTerm *ref) return GetDBTerm(ref); } +Term +Yap_PopTermFromDB(DBTerm *ref) +{ + Term t = GetDBTerm(ref); + DBRef *cp = ref->DBRefs; + + if (cp) { + DBRef eref; + + while ((eref = *--cp) != NIL) { + if (eref->Flags & LogUpdMask) { + LogUpdClause *cl = (LogUpdClause *)eref; + cl->ClRefCount--; + if (cl->ClFlags & ErasedMask && + !(cl->ClFlags & InUseMask) && + !(cl->ClRefCount)) { + EraseLogUpdCl(cl); + } + } else { + LOCK(eref->lock); + eref->NOfRefsTo--; + if (eref->Flags & ErasedMask && + !(eref->Flags & InUseMask) && + eref->NOfRefsTo) { + UNLOCK(eref->lock); + ErDBE(eref); + } else { + UNLOCK(ref->lock); + } + } + } + } + Yap_FreeCodeSpace((char *)ref); + return t; +} + static DBTerm * StoreTermInDB(Term t, int nargs) { diff --git a/C/exec.c b/C/exec.c index ea8df1d3b..97c74c591 100644 --- a/C/exec.c +++ b/C/exec.c @@ -1463,6 +1463,31 @@ suspended_on_current_execution(Term t, Term t0) return t0 == ArgOfTerm(1, t1); } +static Term +get_term(DBTerm *dbt, Term t) +{ + if (dbt) { + while (!(t = Yap_PopTermFromDB(dbt))) { + if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { + Yap_Error_TYPE = YAP_NO_ERROR; + if (!Yap_growglobal(NULL)) { + t = MkAtomTerm(AtomOutOfStackError); + } + } else { + Yap_Error_TYPE = YAP_NO_ERROR; + if (!Yap_growstack(dbt->NOfCells*CellSize)) { + t = MkAtomTerm(AtomOutOfStackError); + } + } + } + if (t) { + B->cp_h = H; + } + } + return t; +} + + static Term clean_trail(Term t, DBTerm *dbt, Term t0) { @@ -1495,14 +1520,7 @@ clean_trail(Term t, DBTerm *dbt, Term t0) if (suspended_on_current_execution(val, t0)) { RESET_VARIABLE(&TrailTerm(pt1)); } else { - if (dbt) { - t = Yap_FetchTermFromDB(dbt); - if (t) { - B->cp_h = H; - } else { - t = MkAtomTerm(AtomDAbort); - } - } + t = get_term(dbt, t); Bind(pt, t); Yap_WakeUp(pt); return t; @@ -1524,14 +1542,7 @@ clean_trail(Term t, DBTerm *dbt, Term t0) #endif /* FROZEN_STACKS */ } } - if (dbt) { - t = Yap_FetchTermFromDB(dbt); - if (t) { - B->cp_h = H; - } else { - t = MkAtomTerm(AtomDAbort); - } - } + t = get_term(dbt, t); return t; } diff --git a/C/threads.c b/C/threads.c index 964f8b0ac..5861552da 100644 --- a/C/threads.c +++ b/C/threads.c @@ -185,7 +185,7 @@ thread_run(void *widp) start_thread(myworker_id); do { - t = tgs[0] = Yap_FetchTermFromDB(ThreadHandle[worker_id].tgoal); + t = tgs[0] = Yap_PopTermFromDB(ThreadHandle[worker_id].tgoal); if (t == 0) { if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { Yap_Error_TYPE = YAP_NO_ERROR; @@ -204,7 +204,6 @@ thread_run(void *widp) } } } while (t == 0); - Yap_ReleaseTermFromDB(ThreadHandle[myworker_id].tgoal); ThreadHandle[myworker_id].tgoal = NULL; tgs[1] = ThreadHandle[worker_id].tdetach; tgoal = Yap_MkApplTerm(FunctorThreadRun, 2, tgs); @@ -716,7 +715,8 @@ p_thread_atexit(void) return FALSE; } do { - t = Yap_FetchTermFromDB(ThreadHandle[worker_id].texit); + t = Yap_PopTermFromDB(ThreadHandle[worker_id].texit); + ThreadHandle[worker_id].texit = NULL; if (t == 0) { if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { Yap_Error_TYPE = YAP_NO_ERROR; diff --git a/H/Yatom.h b/H/Yatom.h index 8bcb14374..fd6063689 100644 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -1363,6 +1363,7 @@ void STD_PROTO (Yap_ErDBE, (DBRef)); DBTerm *STD_PROTO (Yap_StoreTermInDB, (Term, int)); DBTerm *STD_PROTO (Yap_StoreTermInDBPlusExtraSpace, (Term, UInt, UInt *)); Term STD_PROTO (Yap_FetchTermFromDB, (DBTerm *)); +Term STD_PROTO (Yap_PopTermFromDB, (DBTerm *)); void STD_PROTO (Yap_ReleaseTermFromDB, (DBTerm *)); /* init.c */