Changeset: 685daba84b0a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/685daba84b0a
Modified Files:
        gdk/gdk.h
        gdk/gdk_align.c
        gdk/gdk_bat.c
        gdk/gdk_batop.c
        gdk/gdk_bbp.c
        gdk/gdk_hash.c
        gdk/gdk_hash.h
        gdk/gdk_imprints.c
        gdk/gdk_join.c
        gdk/gdk_logger.c
        gdk/gdk_logger_old.c
        gdk/gdk_orderidx.c
        gdk/gdk_select.c
        monetdb5/mal/mal_authorize.c
        monetdb5/modules/mal/tokenizer.c
Branch: default
Log Message:

Use read-write locks for indexes (only really used in hash).
This is somewhat experimental: we need to test the impact of this
change.
The change not only involves using read-write locks, but also using
the parent bats for hashes in select and join (different from before)
and ignoring the dirty bit on persistent bats for deciding whether to
build a hash on the bat.


diffs (truncated from 1014 to 300 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -772,7 +772,7 @@ typedef struct BAT {
        COLrec T;               /* column info */
        MT_Lock theaplock;      /* lock protecting heap reference changes */
 
-       MT_Lock batIdxLock;     /* lock to manipulate indexes */
+       MT_RWLock batIdxLock;   /* lock to manipulate indexes */
 } BAT;
 
 typedef struct BATiter {
diff --git a/gdk/gdk_align.c b/gdk/gdk_align.c
--- a/gdk/gdk_align.c
+++ b/gdk/gdk_align.c
@@ -142,7 +142,7 @@ VIEWcreate(oid seq, BAT *b)
                }
                HEAPdecref(bn->theap, false);
                MT_lock_destroy(&bn->theaplock);
-               MT_lock_destroy(&bn->batIdxLock);
+               MT_rwlock_destroy(&bn->batIdxLock);
                GDKfree(bn);
                return NULL;
        }
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -142,7 +142,7 @@ BATcreatedesc(oid hseq, int tt, bool hea
        snprintf(name, sizeof(name), "heaplock%d", bn->batCacheid); /* fits */
        MT_lock_init(&bn->theaplock, name);
        snprintf(name, sizeof(name), "BATlock%d", bn->batCacheid); /* fits */
-       MT_lock_init(&bn->batIdxLock, name);
+       MT_rwlock_init(&bn->batIdxLock, name);
        bn->batDirtydesc = true;
        return bn;
       bailout:
@@ -247,7 +247,7 @@ COLnew(oid hseq, int tt, BUN cap, role_t
        if (bn->tvheap)
                HEAPdecref(bn->tvheap, true);
        MT_lock_destroy(&bn->theaplock);
-       MT_lock_destroy(&bn->batIdxLock);
+       MT_rwlock_destroy(&bn->batIdxLock);
        GDKfree(bn);
        return NULL;
 }
@@ -631,7 +631,7 @@ BATdestroy(BAT *b)
        GDKfree(b->tvheap);
        PROPdestroy(b);
        MT_lock_destroy(&b->theaplock);
-       MT_lock_destroy(&b->batIdxLock);
+       MT_rwlock_destroy(&b->batIdxLock);
        GDKfree(b->theap);
        GDKfree(b);
 }
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -1835,12 +1835,12 @@ 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 hash lock for this, not because
-        * this scanning interferes with hashes, but because it's
-        * there, and not so likely to be used at the same time. */
-       MT_lock_set(&b->batIdxLock);
+       /* 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 theaplock 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->theaplock);
        if (!b->tsorted && b->tnosorted == 0) {
                b->batDirtydesc = true;
                switch (ATOMbasetype(b->ttype)) {
@@ -1907,7 +1907,7 @@ BATordered(BAT *b)
                }
        }
   doreturn:
-       MT_lock_unset(&b->batIdxLock);
+       MT_lock_unset(&b->theaplock);
        return b->tsorted;
 }
 
@@ -1953,7 +1953,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);
        if (!b->trevsorted && b->tnorevsorted == 0) {
                b->batDirtydesc = true;
                switch (ATOMbasetype(b->ttype)) {
@@ -1997,7 +1997,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;
 }
 
@@ -2204,7 +2204,7 @@ BATsort(BAT **sorted, BAT **order, BAT *
        mkorderidx = (g == NULL && !reverse && !nilslast && pb != NULL && 
(order || !pb->batTransient));
        if (g == NULL && !reverse && !nilslast &&
            pb != NULL && !BATcheckorderidx(pb)) {
-               MT_lock_set(&pb->batIdxLock);
+               MT_rwlock_wrlock(&pb->batIdxLock);
                if (pb->torderidx == NULL) {
                        /* no index created while waiting for lock */
                        if (mkorderidx) /* keep lock when going to create */
@@ -2214,7 +2214,7 @@ BATsort(BAT **sorted, BAT **order, BAT *
                        mkorderidx = false;
                }
                if (!orderidxlock)
-                       MT_lock_unset(&pb->batIdxLock);
+                       MT_rwlock_wrunlock(&pb->batIdxLock);
        } else {
                mkorderidx = false;
        }
@@ -2441,7 +2441,7 @@ BATsort(BAT **sorted, BAT **order, BAT *
                                GDKfree(m);
                        }
                        if (orderidxlock)
-                               MT_lock_unset(&pb->batIdxLock);
+                               MT_rwlock_wrunlock(&pb->batIdxLock);
                        goto error;
                }
                bn->tsorted = !reverse && !nilslast;
@@ -2464,7 +2464,7 @@ BATsort(BAT **sorted, BAT **order, BAT *
                }
        }
        if (orderidxlock)
-               MT_lock_unset(&pb->batIdxLock);
+               MT_rwlock_wrunlock(&pb->batIdxLock);
        bn->theap->dirty = true;
        bn->tnosorted = 0;
        bn->tnorevsorted = 0;
@@ -2723,7 +2723,7 @@ BATgetprop(BAT *b, enum prop_t idx)
 {
        PROPrec *p;
 
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        p = BATgetprop_nolock(b, idx);
        if (p == NULL) {
                /* if looking for the min/max value, we may be able to
@@ -2747,7 +2747,7 @@ BATgetprop(BAT *b, enum prop_t idx)
                        break;
                }
        }
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
        return p;
 }
 
@@ -2755,18 +2755,18 @@ PROPrec *
 BATsetprop(BAT *b, enum prop_t idx, int type, const void *v)
 {
        PROPrec *p;
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        p = BATsetprop_nolock(b, idx, type, v);
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
        return p;
 }
 
 void
 BATrmprop(BAT *b, enum prop_t idx)
 {
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        BATrmprop_nolock(b, idx);
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
 }
 
 
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -647,7 +647,7 @@ BBPreadEntries(FILE *fp, unsigned bbpver
                snprintf(name, sizeof(name), "heaplock%d", bn->batCacheid); /* 
fits */
                MT_lock_init(&bn->theaplock, name);
                snprintf(name, sizeof(name), "BATlock%d", bn->batCacheid); /* 
fits */
-               MT_lock_init(&bn->batIdxLock, name);
+               MT_rwlock_init(&bn->batIdxLock, name);
                ATOMIC_INIT(&bn->theap->refs, 1);
 
                if (base > (uint64_t) GDK_oid_max) {
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -429,7 +429,7 @@ BATcheckhash(BAT *b)
        if (b->thash == (Hash *) 1) {
                /* but when we want to change it, we need the lock */
                TRC_DEBUG_IF(ACCELERATOR) t = GDKusec();
-               MT_lock_set(&b->batIdxLock);
+               MT_rwlock_wrlock(&b->batIdxLock);
                TRC_DEBUG_IF(ACCELERATOR) t = GDKusec() - t;
                /* if still 1 now that we have the lock, we can update */
                if (b->thash == (Hash *) 1) {
@@ -536,7 +536,7 @@ BATcheckhash(BAT *b)
                                                                b->thash = h;
                                                                
TRC_DEBUG(ACCELERATOR,
                                                                          
ALGOBATFMT ": reusing persisted hash\n", ALGOBATPAR(b));
-                                                               
MT_lock_unset(&b->batIdxLock);
+                                                               
MT_rwlock_wrunlock(&b->batIdxLock);
                                                                return true;
                                                        }
                                                        /* if h->nil==h->nbucket
@@ -568,7 +568,7 @@ BATcheckhash(BAT *b)
                        GDKfree(h);
                        GDKclrerr();    /* we're not currently interested in 
errors */
                }
-               MT_lock_unset(&b->batIdxLock);
+               MT_rwlock_wrunlock(&b->batIdxLock);
        }
        ret = b->thash != NULL;
        if (ret)
@@ -655,9 +655,9 @@ BAThashsync(void *arg)
        /* we could check whether b->thash == NULL before getting the
         * lock, and only lock if it isn't; however, it's very
         * unlikely that that is the case, so we don't */
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_rdlock(&b->batIdxLock);
        BAThashsave(b, true);
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_rdunlock(&b->batIdxLock);
        BBPunfix(b->batCacheid);
 }
 #endif
@@ -1002,12 +1002,12 @@ BAThash(BAT *b)
        if (BATcheckhash(b)) {
                return GDK_SUCCEED;
        }
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        if (b->thash == NULL) {
                struct canditer ci;
                canditer_init(&ci, b, NULL);
                if ((b->thash = BAThash_impl(b, &ci, "thash")) == NULL) {
-                       MT_lock_unset(&b->batIdxLock);
+                       MT_rwlock_wrunlock(&b->batIdxLock);
                        return GDK_FAIL;
                }
 #ifdef PERSISTENTHASH
@@ -1016,7 +1016,7 @@ BAThash(BAT *b)
                        BBPfix(b->batCacheid);
                        char name[MT_NAME_LEN];
                        snprintf(name, sizeof(name), "hashsync%d", 
b->batCacheid);
-                       MT_lock_unset(&b->batIdxLock);
+                       MT_rwlock_wrunlock(&b->batIdxLock);
                        if (MT_create_thread(&tid, BAThashsync, b,
                                             MT_THR_DETACHED,
                                             name) < 0) {
@@ -1029,7 +1029,7 @@ BAThash(BAT *b)
                                        "NOT persisting hash %d\n", 
b->batCacheid);
 #endif
        }
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
        return GDK_SUCCEED;
 }
 
@@ -1115,9 +1115,9 @@ HASHappend_locked(BAT *b, BUN i, const v
 void
 HASHappend(BAT *b, BUN i, const void *v)
 {
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        HASHappend_locked(b, i, v);
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
 }
 
 /* insert value v at position p into the hash table of b */
@@ -1186,9 +1186,9 @@ HASHinsert_locked(BAT *b, BUN p, const v
 void
 HASHinsert(BAT *b, BUN p, const void *v)
 {
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        HASHinsert_locked(b, p, v);
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
 }
 
 /* delete value v at position p from the hash table of b */
@@ -1258,9 +1258,9 @@ HASHdelete_locked(BAT *b, BUN p, const v
 void
 HASHdelete(BAT *b, BUN p, const void *v)
 {
-       MT_lock_set(&b->batIdxLock);
+       MT_rwlock_wrlock(&b->batIdxLock);
        HASHdelete_locked(b, p, v);
-       MT_lock_unset(&b->batIdxLock);
+       MT_rwlock_wrunlock(&b->batIdxLock);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to