Changeset: 4621230459b4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/4621230459b4
Modified Files:
        gdk/gdk_bat.c
        gdk/gdk_batop.c
        gdk/gdk_bbp.c
        gdk/gdk_utils.c
        sql/backends/monet5/sql_statistics.c
        sql/storage/bat/bat_storage.c
Branch: default
Log Message:

Remove some data races.
Don't use BBPlock during exit: we're the only thread at this time
anyway;
Use the heap lock instead of index lock in BATordered(_rev);
Don't set bat to read-only on every access in cs_bind_bat, but just make
sure it's already read-only before we get there.


diffs (240 lines):

diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1876,9 +1876,10 @@ BATsetcount(BAT *b, BUN cnt)
        MT_lock_set(&b->theaplock);
        b->batCount = cnt;
        b->batDirtydesc = true;
-       b->theap->dirty |= b->ttype != TYPE_void && b->theap->parentid == 
b->batCacheid && cnt > 0;
-       if (b->theap->parentid == b->batCacheid)
+       if (b->theap->parentid == b->batCacheid) {
+               b->theap->dirty |= b->ttype != TYPE_void && cnt > 0;
                b->theap->free = tailsize(b, cnt);
+       }
        if (b->ttype == TYPE_void)
                b->batCapacity = cnt;
        if (cnt <= 1) {
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -1863,12 +1863,15 @@ BATordered(BAT *b)
        if (b->tnosorted > 0 || !ATOMlinear(b->ttype))
                return false;
 
-       /* In order that multiple threads don't scan the same BAT at the
-        * same time (happens a lot with mitosis/mergetable), we use a
-        * lock.  We reuse the batIdxLock lock for this, not because this
-        * scanning interferes with heap reference counting, but because
-        * it's there, and not so likely to be used at the same time. */
-       MT_lock_set(&b->batIdxLock);
+       /* There are a few reasons why we need a lock here.  It may be
+        * that multiple threads call this functions at the same time
+        * (happens a lot with mitosis/mergetable), but we only need to
+        * scan the bat in one thread: the others can reap the rewards
+        * when that one thread is done.  Also, we need the heap to
+        * remain accessible (could have used bat_iterator for that),
+        * and, and this is the killer argument, we may need to make
+        * changes to the bat descriptor. */
+       MT_lock_set(&b->theaplock);
        BATiter bi = bat_iterator_nolock(b);
        if (!b->tsorted && b->tnosorted == 0) {
                b->batDirtydesc = true;
@@ -1969,7 +1972,7 @@ BATordered(BAT *b)
                }
        }
   doreturn:
-       MT_lock_unset(&b->batIdxLock);
+       MT_lock_unset(&b->theaplock);
        return b->tsorted;
 }
 
@@ -2015,7 +2018,7 @@ BATordered_rev(BAT *b)
                return is_oid_nil(b->tseqbase);
        if (BATtdense(b) || b->tnorevsorted > 0)
                return false;
-       MT_lock_set(&b->batIdxLock);
+       MT_lock_set(&b->theaplock);
        BATiter bi = bat_iterator_nolock(b);
        if (!b->trevsorted && b->tnorevsorted == 0) {
                b->batDirtydesc = true;
@@ -2059,7 +2062,7 @@ BATordered_rev(BAT *b)
                TRC_DEBUG(ALGO, "Fixed revsorted for " ALGOBATFMT " (" LLFMT " 
usec)\n", ALGOBATPAR(b), GDKusec() - t0);
        }
   doreturn:
-       MT_lock_unset(&b->batIdxLock);
+       MT_lock_unset(&b->theaplock);
        return b->trevsorted;
 }
 
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -1753,7 +1753,7 @@ BBPexit(void)
        bat i;
        bool skipped;
 
-       BBPlock();      /* stop all threads ever touching more descriptors */
+       //BBPlock();    /* stop all threads ever touching more descriptors */
 
        /* free all memory (just for leak-checking in Purify) */
        do {
@@ -2597,8 +2597,12 @@ bbpclear(bat i, bool lock)
                MT_lock_set(&GDKcacheLock);
 
        BBP_status_set(i, BBPUNLOADING);
+       if (lock)
+               MT_lock_set(&GDKswapLock(i));
        BBP_refs(i) = 0;
        BBP_lrefs(i) = 0;
+       if (lock)
+               MT_lock_unset(&GDKswapLock(i));
        if (!BBPtmpcheck(BBP_logical(i))) {
                MT_lock_set(&BBPnameLock);
                BBP_delete(i);
@@ -2977,6 +2981,8 @@ decref(bat i, bool logical, bool release
        /* 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 */
+       if (b)
+               MT_lock_set(&b->theaplock);
        if (BBP_refs(i) == 0 &&
            (BBP_lrefs(i) == 0 ||
             (b != NULL && b->theap != NULL
@@ -2999,6 +3005,8 @@ decref(bat i, bool logical, bool release
                swap = true;
        } /* else: bat cannot be swapped out */
        lrefs = BBP_lrefs(i);
+       if (b)
+               MT_lock_unset(&b->theaplock);
 
        /* unlock before re-locking in unload; as saving a dirty
         * persistent bat may take a long time */
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -950,7 +950,7 @@ GDKinit(opt *set, int setlen, bool embed
                }
        } else {
                /* BBP was locked by BBPexit() */
-               BBPunlock();
+               //BBPunlock();
        }
        GDKtracer_init(dbpath, dbtrace);
        errno = 0;
diff --git a/sql/backends/monet5/sql_statistics.c 
b/sql/backends/monet5/sql_statistics.c
--- a/sql/backends/monet5/sql_statistics.c
+++ b/sql/backends/monet5/sql_statistics.c
@@ -132,11 +132,8 @@ sql_analyze(Client cntxt, MalBlkPtr mb, 
                                        }
 
                                        /* Collect new sorted and revsorted 
properties */
-                                       /* At the moment the heap must be 
locked around the BATordered calls to prevent a race condition on it */
-                                       MT_lock_set(&b->theaplock);
                                        (void) BATordered(b);
                                        (void) BATordered_rev(b);
-                                       MT_lock_unset(&b->theaplock);
 
                                        /* Check for nils existence */
                                        (void) BATcount_no_nil(b, NULL);
diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c
--- a/sql/storage/bat/bat_storage.c
+++ b/sql/storage/bat/bat_storage.c
@@ -480,6 +480,7 @@ temp_dup_cs(column_storage *cs, ulng tid
        BAT *b = bat_new(type, 1024, TRANSIENT);
        if (!b)
                return LOG_ERR;
+       bat_set_access(b, BAT_READ);
        cs->bid = temp_create(b);
        bat_destroy(b);
        cs->uibid = e_bat(TYPE_oid);
@@ -988,7 +989,7 @@ cs_bind_bat( column_storage *cs, int acc
        b = temp_descriptor(cs->bid);
        if (b == NULL)
                return NULL;
-       bat_set_access(b, BAT_READ);
+       assert(b->batRestricted == BAT_READ);
        /* return slice */
        BAT *s = BATslice(b, 0, cnt);
        bat_destroy(b);
@@ -1176,6 +1177,7 @@ dict_append_bat(sql_trans *tr, sql_delta
                                }
                                if (cs->bid && !new)
                                        temp_destroy(cs->bid);
+                               bat_set_access(n, BAT_READ);
                                cs->bid = temp_create(n);
                                bat_destroy(n);
                                if (cs->ebid && !new)
@@ -1217,6 +1219,7 @@ dict_append_bat(sql_trans *tr, sql_delta
                                }
                                if (cs->bid && !new)
                                        temp_destroy(cs->bid);
+                               bat_set_access(n, BAT_READ);
                                cs->bid = temp_create(n);
                                bat_destroy(n);
                                cs->cleared = true;
@@ -1268,6 +1271,7 @@ for_append_bat(column_storage *cs, BAT *
                                return NULL;
                        if (cs->bid)
                                temp_destroy(cs->bid);
+                       bat_set_access(n, BAT_READ);
                        cs->bid = temp_create(n);
                        cs->ucnt = 0;
                        if (cs->uibid)
@@ -1702,6 +1706,7 @@ dict_append_val(sql_trans *tr, sql_delta
                                }
                                if (cs->bid && !new)
                                        temp_destroy(cs->bid);
+                               bat_set_access(n, BAT_READ);
                                cs->bid = temp_create(n);
                                bat_destroy(n);
                                if (cs->ebid && !new)
@@ -1738,6 +1743,7 @@ dict_append_val(sql_trans *tr, sql_delta
                                }
                                if (cs->bid)
                                        temp_destroy(cs->bid);
+                               bat_set_access(n, BAT_READ);
                                cs->bid = temp_create(n);
                                bat_destroy(n);
                                cs->cleared = true;
@@ -1773,6 +1779,7 @@ for_append_val(column_storage *cs, void 
                        /* TODO decompress updates if any */
                        if (cs->bid)
                                temp_destroy(cs->bid);
+                       bat_set_access(n, BAT_READ);
                        cs->bid = temp_create(n);
                        cs->st = ST_DEFAULT;
                        /* at append_col the column's storage type is cleared */
@@ -1881,7 +1888,7 @@ dup_cs(sql_trans *tr, column_storage *oc
        cs->ucnt = ocs->ucnt;
 
        if (temp) {
-               cs->bid = temp_copy(cs->bid, true, true);
+               cs->bid = temp_copy(cs->bid, true, false);
                if (cs->bid == BID_NIL)
                        return LOG_ERR;
        } else {
@@ -3526,7 +3533,7 @@ clear_cs(sql_trans *tr, column_storage *
                                cs->bid = temp_create(n); /* create empty copy 
*/
                                bat_destroy(n);
                        } else {
-                               bat nbid = temp_copy(cs->bid, true, temp); /* 
create empty copy */
+                               bat nbid = temp_copy(cs->bid, true, false); /* 
create empty copy */
 
                                if (nbid == BID_NIL)
                                        return BUN_NONE;
@@ -4774,6 +4781,7 @@ swap_bats(sql_trans *tr, sql_column *col
                temp_destroy(d->cs.uibid);
        if (d->cs.uvbid)
                temp_destroy(d->cs.uvbid);
+       bat_set_access(bn, BAT_READ);
        d->cs.bid = temp_create(bn);
        d->cs.uibid = 0;
        d->cs.uvbid = 0;
@@ -4804,6 +4812,7 @@ col_compress(sql_trans *tr, sql_column *
        d->cs.cleared = true;
        if (d->cs.bid)
                temp_destroy(d->cs.bid);
+       bat_set_access(o, BAT_READ);
        d->cs.bid = temp_create(o);
        if (u) {
                if (d->cs.ebid)
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to