From f3fe74cb9f3f0d271cf808163c8d4aafa4715e61 Mon Sep 17 00:00:00 2001 From: vsc Date: Wed, 1 Jun 2005 13:53:46 +0000 Subject: [PATCH] improve bb routines to use the DB efficiently change interface between DB and BB. git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1318 b08c6af1-5177-4d33-ba66-4b1c6b8b522a --- C/bb.c | 139 ++++++++++++++++++++++++++--------------------------- C/dbase.c | 102 +++++++++++++++++++++++++++++++++------ C/heapgc.c | 2 +- H/Yatom.h | 2 +- H/clause.h | 4 ++ H/rheap.h | 29 ++++++----- 6 files changed, 176 insertions(+), 102 deletions(-) diff --git a/C/bb.c b/C/bb.c index b0e585b8d..44e6e9066 100644 --- a/C/bb.c +++ b/C/bb.c @@ -19,8 +19,7 @@ static char SccsId[] = "%W% %G%"; #endif #include "Yap.h" -#include "Yatom.h" -#include "Heap.h" +#include "clause.h" #ifndef NULL #define NULL (void *)0 #endif @@ -47,7 +46,7 @@ PutBBProp(AtomEntry *ae, Term mod) /* get BBentry for at; */ p->NextOfPE = ae->PropsOfAE; ae->PropsOfAE = AbsBBProp(p); p->ModuleOfBB = mod; - p->Element = NULL; + p->Element = 0L; p->KeyOfBB = AbsAtom(ae); p->KindOfPE = BBProperty; INIT_RWLOCK(p->BBRWLock); @@ -94,7 +93,7 @@ PutIntBBProp(Int key, Term mod) /* get BBentry for at; */ return(NULL); } p->ModuleOfBB = mod; - p->Element = NULL; + p->Element = 0L; p->KeyOfBB = (Atom)key; p->KindOfPE = BBProperty; p->NextOfPE = INT_BB_KEYS[hash_key]; @@ -246,20 +245,53 @@ FetchBBProp(Term t1, char *msg, Term mod) return(p); } +static Term +BBPut(Term t0, Term t2) +{ + if (!IsVarTerm(t0) && IsApplTerm(t0)) { + Yap_ErLogUpdCl((LogUpdClause *)DBRefOfTerm(t0)); + } + if (IsVarTerm(t2) || IsAtomOrIntTerm(t2)) { + return t2; + } else { + LogUpdClause *cl = Yap_new_ludbe(t2, NULL, 0); + + if (cl == NULL) { + return 0L; + } + return MkDBRefTerm((DBRef)cl); + } +} + static Int p_bb_put(void) { Term t1 = Deref(ARG1); BBProp p = AddBBProp(t1, "bb_put/2", CurrentModule); - if (p == NULL) + + if (p == NULL) { return(FALSE); - WRITE_LOCK(p->BBRWLock); - if (p->Element != NULL) { - Yap_ReleaseTermFromDB(p->Element); } - p->Element = Yap_StoreTermInDB(Deref(ARG2),2); + WRITE_LOCK(p->BBRWLock); + /* + if (p->Element) + fprintf(stderr,"putting %p, size %d\n", p, p->Element->NOfCells); + */ + p->Element = BBPut(p->Element, Deref(ARG2)); WRITE_UNLOCK(p->BBRWLock); - return(p->Element != NULL); + return (p->Element != 0L); +} + +static Term +BBGet(Term t, UInt arity) +{ + if (IsVarTerm(t)) { + return MkVarTerm(); + } else if (IsAtomOrIntTerm(t)) { + return t; + } else { + return Yap_LUInstance((LogUpdClause *)DBRefOfTerm(t), arity); + } } static Int @@ -267,27 +299,18 @@ p_bb_get(void) { Term t1 = Deref(ARG1); BBProp p = FetchBBProp(t1, "bb_get/2", CurrentModule); - Term out; - if (p == NULL || p->Element == NULL) + Term out, t0; + if (p == NULL || p->Element == 0L) return(FALSE); READ_LOCK(p->BBRWLock); - while ((out = Yap_FetchTermFromDB(p->Element)) == 0L) { - if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { - Yap_Error_TYPE = YAP_NO_ERROR; - if (!Yap_growglobal(NULL)) { - Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage); - return TermNil; - } - } else { - Yap_Error_TYPE = YAP_NO_ERROR; - if (!Yap_gc(2, ENV, P)) { - Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage); - return TermNil; - } - } - } - READ_UNLOCK(p->BBRWLock); - return(Yap_unify(ARG2,out)); + /* + if (p->Element) + fprintf(stderr,"getting %p, size %d\n", p, p->Element->NOfCells); + */ + t0 = p->Element; + READ_UNLOCK(p->BBRWLock); + out = BBGet(t0, 2); + return Yap_unify(ARG2,out); } static Int @@ -298,28 +321,16 @@ p_bb_delete(void) Term out; p = FetchBBProp(t1, "bb_delete/2", CurrentModule); - if (p == NULL || p->Element == NULL) + if (p == NULL || p->Element == 0L) return(FALSE); - while ((out = Yap_FetchTermFromDB(p->Element)) == 0L) { - if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { - Yap_Error_TYPE = YAP_NO_ERROR; - if (!Yap_growglobal(NULL)) { - Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage); - return TermNil; - } - } else { - Yap_Error_TYPE = YAP_NO_ERROR; - if (!Yap_gc(2, ENV, P)) { - Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage); - return TermNil; - } - } - } WRITE_LOCK(p->BBRWLock); - Yap_ReleaseTermFromDB(p->Element); - p->Element = NULL; + out = BBGet(p->Element,2); + if (!IsVarTerm(p->Element) && IsApplTerm(p->Element)) { + Yap_ErLogUpdCl((LogUpdClause *)DBRefOfTerm(p->Element)); + } + p->Element = 0L; WRITE_UNLOCK(p->BBRWLock); - return(Yap_unify(ARG2,out)); + return Yap_unify(ARG2,out); } static Int @@ -330,33 +341,17 @@ p_bb_update(void) Term out; p = FetchBBProp(t1, "bb_update/3", CurrentModule); - if (p == NULL || p->Element == NULL) - return(FALSE); + if (p == NULL || p->Element == 0L) + return FALSE; WRITE_LOCK(p->BBRWLock); - while ((out = Yap_FetchTermFromDB(p->Element)) == 0L) { - if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { - Yap_Error_TYPE = YAP_NO_ERROR; - if (!Yap_growglobal(NULL)) { - Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage); - return TermNil; - } - } else { - Yap_Error_TYPE = YAP_NO_ERROR; - if (!Yap_gc(3, ENV, P)) { - Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage); - return TermNil; - } - } + out = BBGet(p->Element, 3); + if (!Yap_unify(out,ARG2)) { + WRITE_UNLOCK(p->BBRWLock); + return FALSE; } - if (!Yap_unify(ARG2,out)) { - WRITE_UNLOCK(p->BBRWLock); - return(FALSE); - } - - Yap_ReleaseTermFromDB(p->Element); - p->Element = Yap_StoreTermInDB(Deref(ARG3),3); + p->Element = BBPut(p->Element, Deref(ARG3)); WRITE_UNLOCK(p->BBRWLock); - return(p->Element != NULL); + return (p->Element != 0L); } static Int diff --git a/C/dbase.c b/C/dbase.c index 73f671b37..ebe7aa019 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -1900,6 +1900,27 @@ new_lu_db_entry(Term t, PredEntry *pe) } +LogUpdClause * +Yap_new_ludbe(Term t, PredEntry *pe, UInt nargs) +{ + LogUpdClause *x; + + Yap_Error_Size = 0; + while ((x = new_lu_db_entry(t, pe)) == NULL) { + if (Yap_Error_TYPE == YAP_NO_ERROR) { + break; + } else { + XREGS[nargs+1] = t; + if (recover_from_record_error(nargs+1)) { + t = Deref(XREGS[nargs+1]); + } else { + return FALSE; + } + } + } + return x; +} + static LogUpdClause * record_lu(PredEntry *pe, Term t, int position) { @@ -4069,21 +4090,23 @@ EraseLogUpdCl(LogUpdClause *clau) UNLOCK(clau->ClPrev->ClLock); } UNLOCK(clau->ClLock); - if (clau->ClCode == ap->cs.p_code.FirstClause) { - if (clau->ClNext == NULL) { - ap->cs.p_code.FirstClause = NULL; - } else { - ap->cs.p_code.FirstClause = clau->ClNext->ClCode; + if (ap) { + if (clau->ClCode == ap->cs.p_code.FirstClause) { + if (clau->ClNext == NULL) { + ap->cs.p_code.FirstClause = NULL; + } else { + ap->cs.p_code.FirstClause = clau->ClNext->ClCode; + } } - } - if (clau->ClCode == ap->cs.p_code.LastClause) { - if (clau->ClPrev == NULL) { - ap->cs.p_code.LastClause = NULL; - } else { - ap->cs.p_code.LastClause = clau->ClPrev->ClCode; + if (clau->ClCode == ap->cs.p_code.LastClause) { + if (clau->ClPrev == NULL) { + ap->cs.p_code.LastClause = NULL; + } else { + ap->cs.p_code.LastClause = clau->ClPrev->ClCode; + } } + ap->cs.p_code.NOfClauses--; } - ap->cs.p_code.NOfClauses--; clau->ClFlags |= ErasedMask; #ifdef DEBUG #ifndef THREADS @@ -4102,10 +4125,12 @@ EraseLogUpdCl(LogUpdClause *clau) #endif /* we are holding a reference to the clause */ clau->ClRefCount++; - UNLOCK(clau->ClLock); - Yap_RemoveClauseFromIndex(ap, clau->ClCode); - /* release the extra reference */ - LOCK(clau->ClLock); + if (ap) { + UNLOCK(clau->ClLock); + Yap_RemoveClauseFromIndex(ap, clau->ClCode); + /* release the extra reference */ + LOCK(clau->ClLock); + } clau->ClRefCount--; #if defined(YAPOR) || defined(THREADS) if (WPP != ap || i_locked) { @@ -4669,6 +4694,51 @@ p_instance(void) } } +Term +Yap_LUInstance(LogUpdClause *cl, UInt arity) +{ + Term TermDB; + op_numbers opc = Yap_op_from_opcode(cl->ClCode->opc); + + LOCK(cl->ClLock); + if (opc == _unify_idb_term) { + TermDB = cl->ClSource->Entry; + } else { + while ((TermDB = GetDBTerm(cl->ClSource)) == 0L) { + /* oops, we are in trouble, not enough stack space */ + if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) { + UNLOCK(cl->ClLock); + Yap_Error_TYPE = YAP_NO_ERROR; + if (!Yap_growglobal(NULL)) { + Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage); + return 0L; + } + LOCK(cl->ClLock); + } else { + UNLOCK(cl->ClLock); + Yap_Error_TYPE = YAP_NO_ERROR; + if (!Yap_gcl(Yap_Error_Size, arity, ENV, P)) { + Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage); + return 0L; + } + LOCK(cl->ClLock); + } + } + } +#if defined(YAPOR) || defined(THREADS) + cl->ClRefCount++; + TRAIL_CLREF(cl); /* So that fail will erase it */ +#else + if (!(cl->ClFlags & InUseMask)) { + cl->ClFlags |= InUseMask; + TRAIL_CLREF(cl); + } +#endif + UNLOCK(cl->ClLock); + return TermDB; +} + + /* instance(+Ref,?Term) */ static Int p_instance_module(void) diff --git a/C/heapgc.c b/C/heapgc.c index 999ad9dbc..39c18137f 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -2764,7 +2764,7 @@ update_relocation_chain(CELL_PTR current, CELL_PTR dest) } #endif } -#else /* TAGS_FAST_OPS */ +#else /* !TAGS_FAST_OPS */ while (RMARKED(current)) { CELL current_tag; next = GET_NEXT(ccur); diff --git a/H/Yatom.h b/H/Yatom.h index 6b34ed741..592282a3b 100644 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -863,7 +863,7 @@ typedef struct Prop NextOfPE; /* used to chain properties */ PropFlags KindOfPE; /* kind of property */ Atom KeyOfBB; /* functor for this property */ - DBTerm *Element; /* blackboard element */ + Term Element; /* blackboard element */ #if defined(YAPOR) || defined(THREADS) rwlock_t BBRWLock; /* a read-write lock to protect the entry */ #endif diff --git a/H/clause.h b/H/clause.h index b651be8f1..39b0676fa 100644 --- a/H/clause.h +++ b/H/clause.h @@ -311,6 +311,10 @@ typedef enum { Int STD_PROTO(Yap_PredForCode,(yamop *, find_pred_type, Atom *, UInt *, Term *)); #ifdef DEBUG void STD_PROTO(Yap_bug_location,(yamop *)); + + +LogUpdClause *STD_PROTO(Yap_new_ludbe,(Term, PredEntry *, UInt)); +Term STD_PROTO(Yap_LUInstance,(LogUpdClause *, UInt)); #endif diff --git a/H/rheap.h b/H/rheap.h index 15811e9c0..223dcc9cd 100644 --- a/H/rheap.h +++ b/H/rheap.h @@ -11,8 +11,11 @@ * File: rheap.h * * comments: walk through heap code * * * -* Last rev: $Date: 2005-05-30 03:26:37 $,$Author: vsc $ * +* Last rev: $Date: 2005-06-01 13:53:46 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.49 2005/05/30 03:26:37 vsc +* add some atom gc fixes +* * Revision 1.48 2005/01/04 02:50:21 vsc * - allow MegaClauses with blobs * - change Diffs to be thread specific @@ -584,17 +587,6 @@ RestoreDB(DBEntry *pp) } } -/* Restores a DB structure, as it was saved in the heap */ -static void -RestoreBB(BlackBoardEntry *pp) -{ - if (pp->Element) { - pp->Element = DBTermAdjust(pp->Element); - RestoreDBTerm(pp->Element); - } - pp->KeyOfBB = AtomAdjust(pp->KeyOfBB); -} - #include "rclause.h" /* Restores a prolog clause, in its compiled form */ @@ -747,6 +739,19 @@ CleanSIndex(StaticIndex *idx) } +/* Restores a DB structure, as it was saved in the heap */ +static void +RestoreBB(BlackBoardEntry *pp) +{ + Term t = pp->Element; + if (t) { + if (!IsVarTerm(t) && !IsAtomicTerm(t)) { + RestoreLUClause((LogUpdClause *)DBRefOfTerm(t),NULL); + } + } + pp->KeyOfBB = AtomAdjust(pp->KeyOfBB); +} + static void restore_static_array(StaticArrayEntry *ae) {