Changeset: d0abd3472eda for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d0abd3472eda Modified Files: gdk/gdk_align.c gdk/gdk_bat.c gdk/gdk_batop.c gdk/gdk_heap.c gdk/gdk_imprints.c gdk/gdk_private.h gdk/gdk_strimps.c Branch: default Log Message:
Remove data race: put Heap.remove flag inside of atomic var .refs. diffs (220 lines): diff --git a/gdk/gdk_align.c b/gdk/gdk_align.c --- a/gdk/gdk_align.c +++ b/gdk/gdk_align.c @@ -165,6 +165,7 @@ BATmaterialize(BAT *b) { BUN cnt; Heap *tail; + Heap *h, *vh = NULL; BUN p, q; oid t, *x; @@ -210,7 +211,7 @@ BATmaterialize(BAT *b) ATOMIC_INIT(&tail->refs, 1); /* point of no return */ MT_lock_set(&b->theaplock); - assert(ATOMIC_GET(&b->theap->refs) > 0); + assert((ATOMIC_GET(&b->theap->refs) & HEAPREFS) > 0); /* can only look at tvheap when lock is held */ if (complex_cand(b)) { assert(b->batRole == TRANSIENT); @@ -245,10 +246,10 @@ BATmaterialize(BAT *b) } assert(n == q); } - HEAPdecref(b->tvheap, true); + vh = b->tvheap; b->tvheap = NULL; } - HEAPdecref(b->theap, false); + h = b->theap; b->theap = tail; b->tbaseoff = 0; b->theap->dirty = true; @@ -258,6 +259,9 @@ BATmaterialize(BAT *b) BATsetdims(b, 0); b->batDirtydesc = true; BATsetcount(b, b->batCount); + HEAPdecref(h, false); + if (vh) + HEAPdecref(vh, true); return GDK_SUCCEED; } diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c --- a/gdk/gdk_bat.c +++ b/gdk/gdk_bat.c @@ -682,12 +682,12 @@ BATfree(BAT *b) b->tunique_est = (double) nunique; } if (b->theap) { - assert(ATOMIC_GET(&b->theap->refs) == 1); + assert((ATOMIC_GET(&b->theap->refs) & HEAPREFS) == 1); assert(b->theap->parentid == b->batCacheid); HEAPfree(b->theap, false); } if (b->tvheap) { - assert(ATOMIC_GET(&b->tvheap->refs) == 1); + assert((ATOMIC_GET(&b->tvheap->refs) & HEAPREFS) == 1); assert(b->tvheap->parentid == b->batCacheid); HEAPfree(b->tvheap, false); } diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c --- a/gdk/gdk_batop.c +++ b/gdk/gdk_batop.c @@ -41,9 +41,10 @@ unshare_varsized_heap(BAT *b) ATOMIC_INIT(&h->refs, 1); MT_lock_set(&b->theaplock); int parent = b->tvheap->parentid; - HEAPdecref(b->tvheap, false); + Heap *oh = b->tvheap; b->tvheap = h; MT_lock_unset(&b->theaplock); + HEAPdecref(oh, false); BBPunshare(parent); BBPunfix(parent); } @@ -418,11 +419,12 @@ append_varsized_bat(BAT *b, BAT *n, stru return GDK_FAIL; } BBPunshare(b->tvheap->parentid); + ATOMIC_INIT(&h->refs, 1); MT_lock_set(&b->theaplock); - HEAPdecref(b->tvheap, false); - ATOMIC_INIT(&h->refs, 1); + Heap *oh = b->tvheap; b->tvheap = h; MT_lock_unset(&b->theaplock); + HEAPdecref(oh, false); } /* copy data from n to b */ r = BATcount(b); diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c --- a/gdk/gdk_heap.c +++ b/gdk/gdk_heap.c @@ -92,7 +92,8 @@ HEAPgrow(MT_Lock *lock, Heap **hp, size_ Heap *new; MT_lock_set(lock); - if (ATOMIC_GET(&(*hp)->refs) == 1) { + ATOMIC_BASE_TYPE refs = ATOMIC_GET(&(*hp)->refs); + if ((refs & HEAPREFS) == 1) { gdk_return rc = HEAPextend((*hp), size, mayshare); MT_lock_unset(lock); return rc; @@ -103,13 +104,12 @@ HEAPgrow(MT_Lock *lock, Heap **hp, size_ *new = (Heap) { .farmid = old->farmid, .dirty = true, - .remove = old->remove, .parentid = old->parentid, .wasempty = old->wasempty, }; memcpy(new->filename, old->filename, sizeof(new->filename)); if (HEAPalloc(new, size, 1, 1) == GDK_SUCCEED) { - ATOMIC_INIT(&new->refs, 1); + ATOMIC_INIT(&new->refs, 1 | (refs & HEAPREMOVE)); new->free = old->free; new->cleanhash = old->cleanhash; if (old->free > 0 && @@ -553,7 +553,6 @@ GDKupgradevarheap(BAT *b, var_t v, BUN c *new = (Heap) { .farmid = old->farmid, .dirty = true, - .remove = old->remove, .parentid = old->parentid, .wasempty = old->wasempty, }; @@ -564,7 +563,7 @@ GDKupgradevarheap(BAT *b, var_t v, BUN c } /* HEAPalloc initialized .free, so we need to set it after */ new->free = old->free << (shift - b->tshift); - ATOMIC_INIT(&new->refs, 1); + ATOMIC_INIT(&new->refs, 1 | (ATOMIC_GET(&old->refs) & HEAPREMOVE)); switch (width) { case 1: memcpy(new->base, old->base, n); @@ -722,11 +721,13 @@ HEAPfree(Heap *h, bool rmheap) void HEAPdecref(Heap *h, bool remove) { - h->remove |= remove; + if (remove) + ATOMIC_OR(&h->refs, HEAPREMOVE); + ATOMIC_BASE_TYPE refs = ATOMIC_DEC(&h->refs); //printf("dec ref(%d) %p %d\n", (int)h->refs, h, h->parentid); - if (ATOMIC_DEC(&h->refs) == 0) { + if ((refs & HEAPREFS) == 0) { ATOMIC_DESTROY(&h->refs); - HEAPfree(h, h->remove); + HEAPfree(h, (bool) (refs & HEAPREMOVE)); GDKfree(h); } } diff --git a/gdk/gdk_imprints.c b/gdk/gdk_imprints.c --- a/gdk/gdk_imprints.c +++ b/gdk/gdk_imprints.c @@ -797,10 +797,12 @@ void IMPSdecref(Imprints *imprints, bool remove) { TRC_DEBUG(ACCELERATOR, "Decrement ref count of %s\n", imprints->imprints.filename); - imprints->imprints.remove |= remove; - if (ATOMIC_DEC(&imprints->imprints.refs) == 0) { + if (remove) + ATOMIC_OR(&imprints->imprints.refs, HEAPREMOVE); + ATOMIC_BASE_TYPE refs = ATOMIC_DEC(&imprints->imprints.refs); + if ((refs & HEAPREFS) == 0) { ATOMIC_DESTROY(&imprints->imprints.refs); - HEAPfree(&imprints->imprints, imprints->imprints.remove); + HEAPfree(&imprints->imprints, (bool) (refs & HEAPREMOVE)); GDKfree(imprints); } } diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h --- a/gdk/gdk_private.h +++ b/gdk/gdk_private.h @@ -492,6 +492,9 @@ extern MT_Lock GDKtmLock; #define GDKswapLock(x) GDKbatLock[(x)&BBP_BATMASK].swap +#define HEAPREMOVE ((ATOMIC_BASE_TYPE) 1 << 63) +#define HEAPREFS (((ATOMIC_BASE_TYPE) 1 << 63) - 1) + /* when the number of updates to a BAT is less than 1 in this number, we * keep the unique_est property */ #define GDK_UNIQUE_ESTIMATE_KEEP_FRACTION 1000 diff --git a/gdk/gdk_strimps.c b/gdk/gdk_strimps.c --- a/gdk/gdk_strimps.c +++ b/gdk/gdk_strimps.c @@ -783,12 +783,14 @@ STRMPcreate(BAT *b, BAT *s) void STRMPdecref(Strimps *strimps, bool remove) { + if (remove) + ATOMIC_OR(&strimps->strimps.refs, HEAPREMOVE); + ATOMIC_BASE_TYPE refs = ATOMIC_DEC(&strimps->strimps.refs); TRC_DEBUG(ACCELERATOR, "Decrement ref count of %s to " BUNFMT "\n", - strimps->strimps.filename, (BUN) (ATOMIC_GET(&strimps->strimps.refs) - 1)); - strimps->strimps.remove |= remove; - if (ATOMIC_DEC(&strimps->strimps.refs) == 0) { + strimps->strimps.filename, (BUN) (refs & HEAPREFS)); + if ((refs & HEAPREFS) == 0) { ATOMIC_DESTROY(&strimps->strimps.refs); - HEAPfree(&strimps->strimps, strimps->strimps.remove); + HEAPfree(&strimps->strimps, (bool) (refs & HEAPREMOVE)); GDKfree(strimps); } @@ -797,10 +799,9 @@ STRMPdecref(Strimps *strimps, bool remov void STRMPincref(Strimps *strimps) { + ATOMIC_BASE_TYPE refs = ATOMIC_INC(&strimps->strimps.refs); TRC_DEBUG(ACCELERATOR, "Increment ref count of %s to " BUNFMT "\n", - strimps->strimps.filename, (BUN) (ATOMIC_GET(&strimps->strimps.refs) + 1)); - (void)ATOMIC_INC(&strimps->strimps.refs); - + strimps->strimps.filename, (BUN) (refs & HEAPREFS)); } void _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org