diff --git a/C/adtdefs.c b/C/adtdefs.c index 3fed3e0f3..5869f063b 100644 --- a/C/adtdefs.c +++ b/C/adtdefs.c @@ -187,9 +187,6 @@ LookupAtom(char *atom) if (NOfAtoms > 2*AtomHashTableSize) { Yap_signal(YAP_CDOVF_SIGNAL); } - {extern int vsc_xstop; - if (ae == 0x81cf80c) vsc_xstop = 1; - } return na; } diff --git a/C/cdmgr.c b/C/cdmgr.c index e829a97dd..c521f21b0 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -254,15 +254,8 @@ decrease_ref_counter(yamop *ptr, yamop *b, yamop *e, yamop *sc) !(cl->ClRefCount) && !(cl->ClFlags & InUseMask)) { /* last ref to the clause */ -#if defined(YAPOR) || defined(THREADS) - /* can't do erase now without risking deadlocks */ - cl->ClRefCount++; - TRAIL_CLREF(cl); - UNLOCK(cl->ClLock); -#else UNLOCK(cl->ClLock); Yap_ErLogUpdCl(cl); -#endif } else { UNLOCK(cl->ClLock); } @@ -415,9 +408,9 @@ kill_first_log_iblock(LogUpdIndex *c, LogUpdIndex *parent, PredEntry *ap) LogUpdIndex *ncl; /* parent is always locked, now I lock myself */ LOCK(c->ClLock); - if (parent != NULL && - !(c->ClFlags & ErasedMask)) { + if (parent != NULL) { /* remove myself from parent */ + LOCK(parent->ClLock); if (c == parent->ChildIndex) { parent->ChildIndex = c->SiblingIndex; } else { @@ -427,14 +420,17 @@ kill_first_log_iblock(LogUpdIndex *c, LogUpdIndex *parent, PredEntry *ap) } tcl->SiblingIndex = c->SiblingIndex; } + UNLOCK(parent->ClLock); } /* make sure that a child cannot remove us */ c->ClRefCount++; ncl = c->ChildIndex; - while (ncl != NULL) { - LogUpdIndex *next = ncl->SiblingIndex; + /* kill children */ + while (ncl) { + UNLOCK(c->ClLock); kill_first_log_iblock(ncl, c, ap); - ncl = next; + LOCK(c->ClLock); + ncl = c->ChildIndex; } c->ClRefCount--; /* check if we are still the main index */ @@ -442,6 +438,7 @@ kill_first_log_iblock(LogUpdIndex *c, LogUpdIndex *parent, PredEntry *ap) ap->cs.p_code.TrueCodeOfPred == c->ClCode) { RemoveMainIndex(ap); } + /* decrease refs */ decrease_log_indices(c, (yamop *)&(ap->cs.p_code.ExpandCode)); #ifdef DEBUG { @@ -458,6 +455,8 @@ kill_first_log_iblock(LogUpdIndex *c, LogUpdIndex *parent, PredEntry *ap) #endif if (!((c->ClFlags & InUseMask) || c->ClRefCount)) { if (parent != NULL) { + /* sat bye bye */ + LOCK(parent->ClLock); parent->ClRefCount--; if (parent->ClFlags & ErasedMask && !(parent->ClFlags & InUseMask) && @@ -466,34 +465,35 @@ kill_first_log_iblock(LogUpdIndex *c, LogUpdIndex *parent, PredEntry *ap) if (parent->ClFlags & SwitchRootMask) { UNLOCK(parent->ClLock); kill_first_log_iblock(parent, NULL, ap); - LOCK(parent->ClLock); } else { - LOCK(parent->u.ParentIndex->ClLock); UNLOCK(parent->ClLock); kill_first_log_iblock(parent, parent->u.ParentIndex, ap); - LOCK(parent->ClLock); - UNLOCK(parent->u.ParentIndex->ClLock); } + } else { + UNLOCK(parent->ClLock); } } UNLOCK(c->ClLock); Yap_FreeCodeSpace((CODEADDR)c); } else { + c->ClFlags |= ErasedMask; + /* try to move up, so that we don't hold a switch table */ + if (parent != NULL && + parent->ClFlags & SwitchTableMask) { + + LOCK(parent->ClLock); + c->u.ParentIndex = parent->u.ParentIndex; + LOCK(parent->u.ParentIndex->ClLock); + parent->u.ParentIndex->ClRefCount++; + UNLOCK(parent->u.ParentIndex->ClLock); + parent->ClRefCount--; + UNLOCK(parent->ClLock); + } + c->ChildIndex = NULL; #ifdef DEBUG c->SiblingIndex = DBErasedIList; DBErasedIList = c; #endif - c->ClFlags |= ErasedMask; -#if !defined(THREADS) && !defined(YAPOR) - /* try to move up, so that we don't hold an index */ - if (parent != NULL && - parent->ClFlags & SwitchTableMask) { - c->u.ParentIndex = parent->u.ParentIndex; - parent->u.ParentIndex->ClRefCount++; - parent->ClRefCount--; - } -#endif - c->ChildIndex = NULL; UNLOCK(c->ClLock); } } @@ -512,9 +512,18 @@ Yap_kill_iblock(ClauseUnion *blk, ClauseUnion *parent_blk, PredEntry *ap) LogUpdIndex *c = (LogUpdIndex *)blk; if (parent_blk != NULL) { LogUpdIndex *cl = (LogUpdIndex *)parent_blk; +#if defined(THREADS) || defined(YAPOR) LOCK(cl->ClLock); - kill_first_log_iblock(c, cl, ap); + /* protect against attempts at erasing */ + cl->ClRefCount++; UNLOCK(cl->ClLock); +#endif + kill_first_log_iblock(c, cl, ap); +#if defined(THREADS) || defined(YAPOR) + LOCK(cl->ClLock); + cl->ClRefCount--; + UNLOCK(cl->ClLock); +#endif } else { kill_first_log_iblock(c, NULL, ap); } @@ -548,13 +557,23 @@ Yap_ErLogUpdIndex(LogUpdIndex *clau) return; } if (c->ClFlags & SwitchRootMask) { - kill_first_log_iblock(clau, NULL, c->u.pred); + kill_first_log_iblock(clau, NULL, c->u.pred); } else { while (!(c->ClFlags & SwitchRootMask)) c = c->u.ParentIndex; +#if defined(THREADS) || defined(YAPOR) LOCK(clau->u.ParentIndex->ClLock); - kill_first_log_iblock(clau, clau->u.ParentIndex, c->u.pred); + /* protect against attempts at erasing */ + clau->ClRefCount++; UNLOCK(clau->u.ParentIndex->ClLock); +#endif + kill_first_log_iblock(clau, clau->u.ParentIndex, c->u.pred); +#if defined(THREADS) || defined(YAPOR) + LOCK(clau->u.ParentIndex->ClLock); + /* protect against attempts at erasing */ + clau->ClRefCount--; + UNLOCK(clau->u.ParentIndex->ClLock); +#endif } } @@ -572,9 +591,19 @@ Yap_RemoveLogUpdIndex(LogUpdIndex *cl) while (!(pcl->ClFlags & SwitchRootMask)) { pcl = pcl->u.ParentIndex; } +#if defined(THREADS) || defined(YAPOR) LOCK(cl->u.ParentIndex->ClLock); - kill_first_log_iblock(cl, cl->u.ParentIndex, pcl->u.pred); + /* protect against attempts at erasing */ + cl->u.ParentIndex->ClRefCount++; UNLOCK(cl->u.ParentIndex->ClLock); +#endif + kill_first_log_iblock(cl, cl->u.ParentIndex, pcl->u.pred); +#if defined(THREADS) || defined(YAPOR) + LOCK(cl->u.ParentIndex->ClLock); + /* protect against attempts at erasing */ + cl->u.ParentIndex->ClRefCount--; + UNLOCK(cl->u.ParentIndex->ClLock); +#endif } } diff --git a/C/dbase.c b/C/dbase.c index 8eacb171d..684296605 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -3852,17 +3852,21 @@ EraseLogUpdCl(LogUpdClause *clau) PredEntry *ap; LOCK(clau->ClLock); ap = clau->ClPred; - WRITE_LOCK(ap->PRWLock); /* no need to erase what has been erased */ if (!(clau->ClFlags & ErasedMask)) { /* get ourselves out of the list */ if (clau->ClNext != NULL) { + LOCK(clau->ClNext->ClLock); clau->ClNext->ClPrev = clau->ClPrev; + UNLOCK(clau->ClNext->ClLock); } if (clau->ClPrev != NULL) { + LOCK(clau->ClPrev->ClLock); clau->ClPrev->ClNext = clau->ClNext; + UNLOCK(clau->ClPrev->ClLock); } + WRITE_LOCK(ap->PRWLock); if (clau->ClCode == ap->cs.p_code.FirstClause) { if (clau->ClNext == NULL) { ap->cs.p_code.FirstClause = NULL; @@ -3879,6 +3883,7 @@ EraseLogUpdCl(LogUpdClause *clau) } clau->ClFlags |= ErasedMask; ap->cs.p_code.NOfClauses--; + WRITE_UNLOCK(ap->PRWLock); #ifdef DEBUG { LogUpdClause *er_head = DBErasedList; @@ -3900,9 +3905,8 @@ EraseLogUpdCl(LogUpdClause *clau) LOCK(clau->ClLock); clau->ClRefCount--; } - complete_lu_erase(clau); UNLOCK(clau->ClLock); - WRITE_UNLOCK(ap->PRWLock); + complete_lu_erase(clau); } static void diff --git a/C/index.c b/C/index.c index bd2785f3d..613fb151f 100644 --- a/C/index.c +++ b/C/index.c @@ -4427,6 +4427,7 @@ replace_index_block(ClauseUnion *parent_block, yamop *cod, yamop *ncod, PredEntr ncl->ClRefCount = cl->ClRefCount; ncl->ChildIndex = cl->ChildIndex; ncl->u.ParentIndex = cl->u.ParentIndex; + INIT_LOCK(ncl->ClLock); if (c == cl) { parent_block->lui.ChildIndex = ncl; } else { @@ -4748,16 +4749,9 @@ cp_lu_trychain(yamop *codep, yamop *ocodep, yamop *ostart, int flag, PredEntry * if (tgl->ClFlags & ErasedMask && !(tgl->ClRefCount) && !(tgl->ClFlags & InUseMask)) { -#if defined(YAPOR) || defined(THREADS) - /* can't do erase now without risking deadlocks */ - tgl->ClRefCount++; - TRAIL_CLREF(tgl); - UNLOCK(tgl->ClLock); -#else /* last ref to the clause */ UNLOCK(tgl->ClLock); Yap_ErLogUpdCl(tgl); -#endif } else { UNLOCK(tgl->ClLock); } @@ -4800,15 +4794,8 @@ cp_lu_trychain(yamop *codep, yamop *ocodep, yamop *ostart, int flag, PredEntry * !(tgl->ClRefCount) && !(tgl->ClFlags & InUseMask)) { /* last ref to the clause */ -#if defined(YAPOR) || defined(THREADS) - /* can't do erase now without risking deadlocks */ - tgl->ClRefCount++; - TRAIL_CLREF(tgl); - UNLOCK(tgl->ClLock); -#else UNLOCK(tgl->ClLock); Yap_ErLogUpdCl(tgl); -#endif } else { UNLOCK(tgl->ClLock); } @@ -4868,10 +4855,8 @@ replace_lu_block(LogUpdIndex *blk, int flag, PredEntry *ap, yamop *code, int has ncl->ClRefCount = 0; ncl->u.ParentIndex = blk->u.ParentIndex; ncl->ChildIndex = NULL; -#if defined(YAPOR) || defined(THREADS) INIT_LOCK(ncl->ClLock); INIT_CLREF_COUNT(ncl); -#endif codep = start = ncl->ClCode; /* ok, we've allocated and set up things, now let's finish */ codep->opc = Yap_opcode(_enter_lu_pred); diff --git a/C/tracer.c b/C/tracer.c index 10a5585cc..0acc31a75 100644 --- a/C/tracer.c +++ b/C/tracer.c @@ -116,7 +116,8 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args) LOCK(heap_regs->low_level_trace_lock); vsc_count++; - if (vsc_count < 12000) { + if (vsc_count == 213471) vsc_xstop = 1; + if (vsc_count < 1200000) { UNLOCK(heap_regs->low_level_trace_lock); return; } diff --git a/H/clause.h b/H/clause.h index 53c9ac558..ec9f863d8 100644 --- a/H/clause.h +++ b/H/clause.h @@ -153,7 +153,7 @@ typedef union clause_obj { #define INIT_CLREF_COUNT(X) (X)->ClRefCount = 0 #define INC_CLREF_COUNT(X) (X)->ClRefCount++ #define DEC_CLREF_COUNT(X) (X)->ClRefCount-- -#define CL_IN_USE(X) ((X)->ClRefCount != 0) +#define CL_IN_USE(X) ((X)->ClRefCount) #else #define INIT_CLREF_COUNT(X) #define INC_CLREF_COUNT(X)