Changeset: ae6f967643e0 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ae6f967643e0
Modified Files:
        gdk/gdk_bat.c
        gdk/gdk_bbp.c
Branch: Jul2021
Log Message:

Do a bit more locking to prevent race conditions from happening.


diffs (130 lines):

diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -664,9 +664,6 @@ BATfree(BAT *b)
                return;
 
        /* deallocate all memory for a bat */
-       if (b->tident && !default_ident(b->tident))
-               GDKfree(b->tident);
-       b->tident = BATstring_t;
        MT_rwlock_rdlock(&b->thashlock);
        BUN nunique = BUN_NONE, nbucket = BUN_NONE;
        if (b->thash && b->thash != (Hash *) 1) {
@@ -678,6 +675,9 @@ BATfree(BAT *b)
        IMPSfree(b);
        OIDXfree(b);
        MT_lock_set(&b->theaplock);
+       if (b->tident && !default_ident(b->tident))
+               GDKfree(b->tident);
+       b->tident = BATstring_t;
        if (nunique != BUN_NONE) {
                BATsetprop_nolock(b, GDK_NUNIQUE, TYPE_oid, &(oid){nunique});
                BATsetprop_nolock(b, GDK_UNIQUE_ESTIMATE, TYPE_dbl, 
&(dbl){(dbl)nunique});
@@ -695,6 +695,7 @@ BATfree(BAT *b)
                assert((ATOMIC_GET(&b->theap->refs) & HEAPREFS) == 1);
                assert(b->theap->parentid == b->batCacheid);
                HEAPfree(b->theap, false);
+               b->theap = NULL;
        }
        /* wait until there are no other references to the heap; a
         * reference is possible in e.g. BBPsync that uses a
@@ -708,6 +709,7 @@ BATfree(BAT *b)
                assert((ATOMIC_GET(&b->tvheap->refs) & HEAPREFS) == 1);
                assert(b->tvheap->parentid == b->batCacheid);
                HEAPfree(b->tvheap, false);
+               b->tvheap = NULL;
        }
        MT_lock_unset(&b->theaplock);
 }
@@ -2076,12 +2078,14 @@ BATroles(BAT *b, const char *tnme)
 {
        if (b == NULL)
                return GDK_SUCCEED;
+       MT_lock_set(&b->theaplock);
        if (b->tident && !default_ident(b->tident))
                GDKfree(b->tident);
        if (tnme)
                b->tident = GDKstrdup(tnme);
        else
                b->tident = BATstring_t;
+       MT_lock_unset(&b->theaplock);
        return b->tident ? GDK_SUCCEED : GDK_FAIL;
 }
 
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -2658,6 +2658,7 @@ decref(bat i, bool logical, bool release
        bat tp = 0, tvp = 0;
        int farmid = 0;
        BAT *b;
+       bool locked = false;
 
        if (is_bat_nil(i))
                return -1;
@@ -2705,10 +2706,24 @@ decref(bat i, bool logical, bool release
                        GDKerror("%s: %s does not have pointer fixes.\n", func, 
BBP_logical(i));
                        assert(0);
                } else {
-                       assert(b == NULL || b->theap == NULL || 
BBP_refs(b->theap->parentid) > 0);
-                       assert(b == NULL || b->tvheap == NULL || 
BBP_refs(b->tvheap->parentid) > 0);
+#ifndef NDEBUG
+                       if (b) {
+                               MT_lock_set(&b->theaplock);
+                               locked = true;
+                               assert(b->theap == NULL || 
BBP_refs(b->theap->parentid) > 0);
+                               assert(b->tvheap == NULL || 
BBP_refs(b->tvheap->parentid) > 0);
+                       }
+#endif
                        refs = --BBP_refs(i);
                        if (b && refs == 0) {
+#ifdef NDEBUG
+                               /* if NDEBUG is not defined, we locked
+                                * the heaplock above, so we only lock
+                                * it here if NDEBUG *is* defined */
+                               MT_lock_set(&b->theaplock);
+                               locked = true;
+#endif
+                               assert(locked); /* just to be clear */
                                tp = VIEWtparent(b);
                                tvp = VIEWvtparent(b);
                                if (tp || tvp)
@@ -2717,7 +2732,10 @@ decref(bat i, bool logical, bool release
                }
        }
        if (b) {
-               MT_lock_set(&b->theaplock);
+               if (!locked) {
+                       MT_lock_set(&b->theaplock);
+                       locked = true;
+               }
                if (b->batCount > b->batInserted && !isVIEW(b)) {
                        /* if batCount is larger than batInserted and
                         * the dirty bits are off, it may be that a
@@ -2731,15 +2749,21 @@ decref(bat i, bool logical, bool release
                }
                if (b->theap)
                        farmid = b->theap->farmid;
-               MT_lock_unset(&b->theaplock);
        }
 
        /* we destroy transients asap and unload persistent bats only
         * if they have been made cold or are not dirty */
        unsigned chkflag = BBPSYNCING;
-       if (GDKvm_cursize() < GDK_vm_maxsize &&
-            ((b && b->theap ? b->theap->size : 0) + (b && b->tvheap ? 
b->tvheap->size : 0)) < (GDK_vm_maxsize - GDKvm_cursize()) / 32)
-               chkflag |= BBPHOT;
+       if (b && GDKvm_cursize() < GDK_vm_maxsize) {
+               if (!locked) {
+                       MT_lock_set(&b->theaplock);
+                       locked = true;
+               }
+               if (((b->theap ? b->theap->size : 0) + (b->tvheap ? 
b->tvheap->size : 0)) < (GDK_vm_maxsize - GDKvm_cursize()) / 32)
+                       chkflag |= BBPHOT;
+       }
+       if (locked)
+               MT_lock_unset(&b->theaplock);
        /* only consider unloading if refs is 0; if, in addition, lrefs
         * is 0, we can definitely unload, else only if some more
         * conditions are met */
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to