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

Reply via email to