Changeset: 60c9b0a73ffc for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/60c9b0a73ffc
Modified Files:
        gdk/gdk.h
        gdk/gdk_bbp.c
        gdk/gdk_hash.c
        gdk/gdk_heap.c
        gdk/gdk_imprints.c
        gdk/gdk_orderidx.c
        gdk/gdk_private.h
        gdk/gdk_storage.c
Branch: Jul2021
Log Message:

Don't keep lock while saving bat, use iterator instead.


diffs (truncated from 393 to 300 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -918,6 +918,7 @@ typedef struct BATiter {
        uint8_t shift;
        int8_t type;
        oid tseq;
+       BUN hfree, vhfree;
        union {
                oid tvid;
                bool tmsk;
@@ -944,6 +945,8 @@ bat_iterator(BAT *b)
                        .shift = b->tshift,
                        .type = b->ttype,
                        .tseq = b->tseqbase,
+                       .hfree = b->theap->free,
+                       .vhfree = b->tvheap ? b->tvheap->free : 0,
 #ifndef NDEBUG
                        .locked = true,
 #endif
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -3293,25 +3293,22 @@ BBPsync(int cnt, bat *restrict subcommit
 
                while (++idx < cnt) {
                        bat i = subcommit ? subcommit[idx] : idx;
-                       BAT *d = BBP_desc(i);
-
-                       if (d)
-                               MT_lock_set(&d->theaplock);
+                       /* BBP_desc(i) may be NULL */
+                       BATiter bi = bat_iterator(BBP_desc(i));
+
                        if (BBP_status(i) & BBPPERSISTENT) {
                                BAT *b = dirty_bat(&i, subcommit != NULL);
                                if (i <= 0) {
-                                       if (d)
-                                               MT_lock_unset(&d->theaplock);
+                                       bat_iterator_end(&bi);
                                        break;
                                }
                                if (b)
-                                       ret = BATsave_locked(b);
+                                       ret = BATsave_locked(b, &bi);
                        }
                        if (ret == GDK_SUCCEED) {
                                n = BBPdir_step(i, sizes ? sizes[idx] : 
BUN_NONE, n, buf, sizeof(buf), &obbpf, nbbpf);
                        }
-                       if (d)
-                               MT_lock_unset(&d->theaplock);
+                       bat_iterator_end(&bi);
                        if (n == -2)
                                break;
                        /* we once again have a saved heap */
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -605,8 +605,8 @@ BAThashsave_intern(BAT *b, bool dosync)
                 * mean time */
                if (!b->theap->dirty &&
                    ((size_t *) h->heapbckt.base)[4] == BATcount(b) &&
-                   HEAPsave(&h->heaplink, h->heaplink.filename, NULL, dosync) 
== GDK_SUCCEED &&
-                   HEAPsave(hp, hp->filename, NULL, dosync) == GDK_SUCCEED) {
+                   HEAPsave(&h->heaplink, h->heaplink.filename, NULL, dosync, 
h->heaplink.free) == GDK_SUCCEED &&
+                   HEAPsave(hp, hp->filename, NULL, dosync, hp->free) == 
GDK_SUCCEED) {
                        h->heaplink.dirty = false;
                        hp->dirty = false;
                        rc = HASHfix(h, true, dosync);
diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c
--- a/gdk/gdk_heap.c
+++ b/gdk/gdk_heap.c
@@ -72,7 +72,7 @@ HEAPcreatefile(int farmid, size_t *maxsz
 }
 
 static gdk_return HEAPload_intern(Heap *h, const char *nme, const char *ext, 
const char *suffix, bool trunc);
-static gdk_return HEAPsave_intern(Heap *h, const char *nme, const char *ext, 
const char *suffix, bool dosync);
+static gdk_return HEAPsave_intern(Heap *h, const char *nme, const char *ext, 
const char *suffix, bool dosync, BUN free);
 
 static char *
 decompose_filename(str nme)
@@ -202,6 +202,9 @@ HEAPalloc(Heap *h, size_t nitems, size_t
 gdk_return
 HEAPextend(Heap *h, size_t size, bool mayshare)
 {
+       if (size <= h->size)
+               return GDK_SUCCEED;     /* nothing to do */
+
        char nme[sizeof(h->filename)], *ext;
        const char *failure = "None";
 
@@ -212,9 +215,6 @@ HEAPextend(Heap *h, size_t size, bool ma
                strcpy_len(nme, h->filename, sizeof(nme));
                ext = decompose_filename(nme);
        }
-       if (size <= h->size)
-               return GDK_SUCCEED;     /* nothing to do */
-
        failure = "size > h->size";
 
        if (h->storage != STORE_MEM) {
@@ -313,7 +313,7 @@ HEAPextend(Heap *h, size_t size, bool ma
                                failure = "h->storage == STORE_MEM && can_map 
&& fd >= 0 && HEAPload() != GDK_SUCCEED";
                                /* couldn't allocate, now first save data to
                                 * file */
-                               if (HEAPsave_intern(&bak, nme, ext, ".tmp", 
false) != GDK_SUCCEED) {
+                               if (HEAPsave_intern(&bak, nme, ext, ".tmp", 
false, bak.free) != GDK_SUCCEED) {
                                        failure = "h->storage == STORE_MEM && 
can_map && fd >= 0 && HEAPsave_intern() != GDK_SUCCEED";
                                        goto failed;
                                }
@@ -839,7 +839,7 @@ HEAPload(Heap *h, const char *nme, const
  * safe on stable storage.
  */
 static gdk_return
-HEAPsave_intern(Heap *h, const char *nme, const char *ext, const char *suffix, 
bool dosync)
+HEAPsave_intern(Heap *h, const char *nme, const char *ext, const char *suffix, 
bool dosync, BUN free)
 {
        storage_t store = h->newstorage;
        long_str extension;
@@ -849,13 +849,13 @@ HEAPsave_intern(Heap *h, const char *nme
                GDKerror("no heap to save\n");
                return GDK_FAIL;
        }
-       if (h->free == 0) {
+       if (free == 0) {
                /* nothing to see, please move on */
                h->wasempty = true;
                TRC_DEBUG(HEAP,
                          "not saving: "
                          "(%s.%s,storage=%d,free=%zu,size=%zu,dosync=%s)\n",
-                         nme?nme:"", ext, (int) h->newstorage, h->free, 
h->size,
+                         nme?nme:"", ext, (int) h->newstorage, free, h->size,
                          dosync?"true":"false");
                return GDK_SUCCEED;
        }
@@ -870,18 +870,21 @@ HEAPsave_intern(Heap *h, const char *nme
        }
        TRC_DEBUG(HEAP,
                  "(%s.%s,storage=%d,free=%zu,size=%zu,dosync=%s)\n",
-                 nme?nme:"", ext, (int) h->newstorage, h->free, h->size,
+                 nme?nme:"", ext, (int) h->newstorage, free, h->size,
                  dosync?"true":"false");
-       rc = GDKsave(h->farmid, nme, ext, h->base, h->free, store, dosync);
+       h->dirty = free != h->free;
+       rc = GDKsave(h->farmid, nme, ext, h->base, free, store, dosync);
        if (rc == GDK_SUCCEED)
                h->wasempty = false;
+       else
+               h->dirty = true;
        return rc;
 }
 
 gdk_return
-HEAPsave(Heap *h, const char *nme, const char *ext, bool dosync)
+HEAPsave(Heap *h, const char *nme, const char *ext, bool dosync, BUN free)
 {
-       return HEAPsave_intern(h, nme, ext, ".new", dosync);
+       return HEAPsave_intern(h, nme, ext, ".new", dosync, free);
 }
 
 /*
diff --git a/gdk/gdk_imprints.c b/gdk/gdk_imprints.c
--- a/gdk/gdk_imprints.c
+++ b/gdk/gdk_imprints.c
@@ -389,7 +389,7 @@ BATimpsync(void *arg)
        MT_lock_set(&b->batIdxLock);
        if ((imprints = b->timprints) != NULL) {
                Heap *hp = &imprints->imprints;
-               if (HEAPsave(hp, hp->filename, NULL, true) == GDK_SUCCEED) {
+               if (HEAPsave(hp, hp->filename, NULL, true, hp->free) == 
GDK_SUCCEED) {
                        if (hp->storage == STORE_MEM) {
                                if ((fd = GDKfdlocate(hp->farmid, hp->filename, 
"rb+", NULL)) >= 0) {
                                        /* add version number */
diff --git a/gdk/gdk_orderidx.c b/gdk/gdk_orderidx.c
--- a/gdk/gdk_orderidx.c
+++ b/gdk/gdk_orderidx.c
@@ -25,7 +25,7 @@ BATidxsync(void *arg)
 
        MT_lock_set(&b->batIdxLock);
        if ((hp = b->torderidx) != NULL) {
-               if (HEAPsave(hp, hp->filename, NULL, true) == GDK_SUCCEED) {
+               if (HEAPsave(hp, hp->filename, NULL, true, hp->free) == 
GDK_SUCCEED) {
                        if (hp->storage == STORE_MEM) {
                                if ((fd = GDKfdlocate(hp->farmid, hp->filename, 
"rb+", NULL)) >= 0) {
                                        ((oid *) hp->base)[0] |= (oid) 1 << 24;
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -81,7 +81,7 @@ void BATrmprop(BAT *b, enum prop_t idx)
        __attribute__((__visibility__("hidden")));
 void BATrmprop_nolock(BAT *b, enum prop_t idx)
        __attribute__((__visibility__("hidden")));
-gdk_return BATsave_locked(BAT *bd)
+gdk_return BATsave_locked(BAT *bd, BATiter *bi)
        __attribute__((__visibility__("hidden")));
 void BATsetdims(BAT *b)
        __attribute__((__visibility__("hidden")));
@@ -208,7 +208,7 @@ gdk_return HEAPload(Heap *h, const char 
        __attribute__((__visibility__("hidden")));
 void HEAP_recover(Heap *, const var_t *, BUN)
        __attribute__((__visibility__("hidden")));
-gdk_return HEAPsave(Heap *h, const char *nme, const char *ext, bool dosync)
+gdk_return HEAPsave(Heap *h, const char *nme, const char *ext, bool dosync, 
BUN free)
        __attribute__((__warn_unused_result__))
        __attribute__((__visibility__("hidden")));
 gdk_return HEAPshrink(Heap *h, size_t size)
diff --git a/gdk/gdk_storage.c b/gdk/gdk_storage.c
--- a/gdk/gdk_storage.c
+++ b/gdk/gdk_storage.c
@@ -758,51 +758,56 @@ BATmsync(BAT *b)
 #endif /* DISABLE_MSYNC */
 }
 
+static inline const char *
+gettailnamebi(const BATiter *bi)
+{
+       if (bi->type != TYPE_str)
+               return "tail";
+       switch (bi->width) {
+       case 1:
+               return "tail1";
+       case 2:
+               return "tail2";
+#if SIZEOF_VAR_T == 8
+       case 4:
+               return "tail4";
+#endif
+       default:
+               return "tail";
+       }
+}
+
 gdk_return
-BATsave_locked(BAT *bd)
+BATsave_locked(BAT *b, BATiter *bi)
 {
        gdk_return err = GDK_SUCCEED;
        const char *nme;
-       bool dosync = (BBP_status(bd->batCacheid) & BBPPERSISTENT) != 0;
+       bool dosync = (BBP_status(b->batCacheid) & BBPPERSISTENT) != 0;
 
-       assert(!GDKinmemory(bd->theap->farmid));
-       BATcheck(bd, GDK_FAIL);
+       assert(!GDKinmemory(b->theap->farmid));
+       BATcheck(b, GDK_FAIL);
 
-       assert(bd->batCacheid > 0);
+       assert(b->batCacheid > 0);
        /* views cannot be saved, but make an exception for
         * force-remapped views */
-       if (isVIEW(bd)) {
-               GDKerror("%s is a view on %s; cannot be saved\n", BATgetId(bd), 
BBP_logical(VIEWtparent(bd)));
+       if (isVIEW(b)) {
+               GDKerror("%s is a view on %s; cannot be saved\n", BATgetId(b), 
BBP_logical(VIEWtparent(b)));
                return GDK_FAIL;
        }
-       if (!BATdirty(bd)) {
+       if (!BATdirty(b)) {
                return GDK_SUCCEED;
        }
 
-       /* copy the descriptor to a local variable in order to let our
-        * messing in the BAT descriptor not affect other threads that
-        * only read it. */
-       BAT bs = *bd;
-       BAT *b = &bs;
-       Heap hs = *bd->theap;
-       HEAPincref(&hs);
-       b->theap = &hs;
-       Heap vhs;
-       if (b->tvheap) {
-               vhs = *bd->tvheap;
-               HEAPincref(&vhs);
-               b->tvheap = &vhs;
-       }
-
        /* start saving data */
        nme = BBP_physical(b->batCacheid);
-       if (b->ttype != TYPE_void && b->theap->base == NULL) {
-               assert(BBP_status(bd->batCacheid) & BBPSWAPPED);
+       const char *tail = gettailnamebi(bi);
+       if (bi->type != TYPE_void && bi->h->base == NULL) {
+               assert(BBP_status(b->batCacheid) & BBPSWAPPED);
                if (dosync && !(GDKdebug & NOSYNCMASK)) {
-                       int fd = GDKfdlocate(b->theap->farmid, nme, "rb+", 
gettailname(b));
+                       int fd = GDKfdlocate(bi->h->farmid, nme, "rb+", tail);
                        if (fd < 0) {
-                               GDKsyserror("cannot open file %s.%s for 
sync\n", nme,
-                                           gettailname(b));
+                               GDKsyserror("cannot open file %s.%s for sync\n",
+                                           nme, tail);
                                err = GDK_FAIL;
                        } else {
                                if (
@@ -814,12 +819,12 @@ BATsave_locked(BAT *bd)
                                        fsync(fd) < 0
 #endif
                                        )
-                                       GDKsyserror("sync failed for %s.%s\n", 
nme,
-                                                   gettailname(b));
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to