Changeset: 0aacfb64b8d2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0aacfb64b8d2
Modified Files:
        gdk/gdk_bbp.c
        gdk/gdk_heap.c
        gdk/gdk_private.h
        gdk/gdk_utils.c
        tools/mserver/mserver5.c
Branch: default
Log Message:

Merge with Jun2023 branch.


diffs (truncated from 326 to 300 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -1700,6 +1700,15 @@ BBPinit(void)
                fclose(fp);
        }
 
+       /* remove trailing free bats from potential free list (they will
+        * get added when needed) */
+       for (bat i = (bat) ATOMIC_GET(&BBPsize) - 1; i > 0; i--) {
+               if (BBP_desc(i) != NULL)
+                       break;
+               bbpsize--;
+       }
+       ATOMIC_SET(&BBPsize, bbpsize);
+
        /* add free bats to free list in such a way that low numbered
         * ones are at the head of the list */
        for (bat i = (bat) ATOMIC_GET(&BBPsize) - 1; i > 0; i--) {
@@ -2554,36 +2563,51 @@ BBPuncacheit(bat i, bool unloaddesc)
  * BBPclear removes a BAT from the BBP directory forever.
  */
 static inline void
-BBPhandover(Thread t, int n)
+BBPhandover(Thread t, uint32_t n)
 {
+       bat *p, bid;
        /* take one bat from our private free list and hand it over to
         * the global free list */
-       bat i = t->freebats;
-       bat bid = i;
-       if (i == 0)
-               return;
-       for (int j = 1; j < n; j++) {
-               if (BBP_next(i) == 0) {
-                       n = j;
-                       break;
-               }
-               i = BBP_next(i);
+       if (n >= t->nfreebats) {
+               bid = t->freebats;
+               t->freebats = 0;
+               t->nfreebats = 0;
+       } else {
+               p = &t->freebats;
+               for (uint32_t i = n; i < t->nfreebats; i++)
+                       p = &BBP_next(*p);
+               bid = *p;
+               *p = 0;
+               t->nfreebats -= n;
        }
-       t->freebats = BBP_next(i);
-       t->nfreebats -= n;
-       BBP_next(i) = 0;
-       bat *p = &BBP_free;
-       while (n > 0) {
+       p = &BBP_free;
+       while (bid != 0) {
                while (*p && *p < bid)
                        p = &BBP_next(*p);
-               i = BBP_next(bid);
+               bat i = BBP_next(bid);
                BBP_next(bid) = *p;
                *p = bid;
                bid = i;
-               n--;
        }
 }
 
+#ifndef NDEBUG
+extern void printlist(bat bid) __attribute__((__cold__));
+/* print a bat free list, pass start of free list as argument
+ * to be used from the debugger */
+void
+printlist(bat bid)
+{
+       int n = 0;
+       while (bid) {
+               printf("%d ", bid);
+               bid = BBP_next(bid);
+               n++;
+       }
+       printf("(%d)\n", n);
+}
+#endif
+
 static inline void
 bbpclear(bat i, bool lock)
 {
diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c
--- a/gdk/gdk_heap.c
+++ b/gdk/gdk_heap.c
@@ -157,6 +157,14 @@ HEAPalloc(Heap *h, size_t nitems, size_t
        h->free = 0;
        h->cleanhash = false;
 
+#ifdef SIZE_CHECK_IN_HEAPS_ONLY
+       if (GDKvm_cursize() + h->size >= GDK_vm_maxsize &&
+           !MT_thread_override_limits()) {
+               GDKerror("allocating too much memory (current: %zu, requested: 
%zu, limit: %zu)\n", GDKvm_cursize(), h->size, GDK_vm_maxsize);
+               return GDK_FAIL;
+       }
+#endif
+
        size_t allocated;
        if (GDKinmemory(h->farmid) ||
            ((allocated = GDKmem_cursize()) + h->size < GDK_mem_maxsize &&
@@ -255,6 +263,14 @@ HEAPextend(Heap *h, size_t size, bool ma
        }
        failure = "size > h->size";
 
+#ifdef SIZE_CHECK_IN_HEAPS_ONLY
+       if (GDKvm_cursize() + size - h->size >= GDK_vm_maxsize &&
+           !MT_thread_override_limits()) {
+               GDKerror("allocating too much memory (current: %zu, requested: 
%zu, limit: %zu)\n", GDKvm_cursize(), size - h->size, GDK_vm_maxsize);
+               return GDK_FAIL;
+       }
+#endif
+
        if (h->storage != STORE_MEM) {
                char *p;
                char *path;
@@ -826,6 +842,14 @@ HEAPload_intern(Heap *h, const char *nme
        GDKfree(srcpath);
        GDKfree(dstpath);
 
+#ifdef SIZE_CHECK_IN_HEAPS_ONLY
+       if (GDKvm_cursize() + h->size >= GDK_vm_maxsize &&
+           !MT_thread_override_limits()) {
+               GDKerror("allocating too much memory (current: %zu, requested: 
%zu, limit: %zu)\n", GDKvm_cursize(), h->size, GDK_vm_maxsize);
+               return GDK_FAIL;
+       }
+#endif
+
        size_t size = h->size;
        QryCtx *qc = NULL;
        if (h->storage != STORE_MEM)
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -23,6 +23,9 @@
 /* persist strimp heaps for persistent BATs */
 #define PERSISTENTSTRIMP 1
 
+/* only check whether we exceed gdk_vm_maxsize when allocating heaps */
+/* #define SIZE_CHECK_IN_HEAPS_ONLY 1 */
+
 #include "gdk_system_private.h"
 
 enum heaptype {
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -1927,12 +1927,14 @@ GDKmalloc_internal(size_t size, bool cle
                return NULL;
        }
 #endif
+#ifndef SIZE_CHECK_IN_HEAPS_ONLY
        if (size > SMALL_MALLOC &&
            GDKvm_cursize() + size >= GDK_vm_maxsize &&
            !MT_thread_override_limits()) {
                GDKerror("allocating too much memory\n");
                return NULL;
        }
+#endif
 
        /* pad to multiple of eight bytes and add some extra space to
         * write real size in front; when debugging, also allocate
@@ -2030,11 +2032,14 @@ GDKfree(void *s)
        asize = ((size_t *) s)[-1]; /* how much allocated last */
 
 #if !defined(NDEBUG) && !defined(SANITIZER)
+       size_t *p = s;
        assert((asize & 2) == 0);   /* check against duplicate free */
+       size_t size = p[-2];
+       assert(((size + 7) & ~7) + MALLOC_EXTRA_SPACE + DEBUG_SPACE == asize);
        /* check for out-of-bounds writes */
-       for (size_t i = ((size_t *) s)[-2]; i < asize - MALLOC_EXTRA_SPACE; i++)
+       for (size_t i = size; i < asize - MALLOC_EXTRA_SPACE; i++)
                assert(((char *) s)[i] == '\xBD');
-       ((size_t *) s)[-1] |= 2; /* indicate area is freed */
+       p[-1] |= 2;             /* indicate area is freed */
 
        /* overwrite memory that is to be freed with a pattern that
         * will help us recognize access to already freed memory in
@@ -2064,6 +2069,7 @@ GDKrealloc(void *s, size_t size)
        nsize = (size + 7) & ~7;
        asize = os[-1];         /* how much allocated last */
 
+#ifndef SIZE_CHECK_IN_HEAPS_ONLY
        if (size > SMALL_MALLOC &&
            nsize > asize &&
            GDKvm_cursize() + nsize - asize >= GDK_vm_maxsize &&
@@ -2071,10 +2077,12 @@ GDKrealloc(void *s, size_t size)
                GDKerror("allocating too much memory\n");
                return NULL;
        }
+#endif
 #if !defined(NDEBUG) && !defined(SANITIZER)
        assert((asize & 2) == 0);   /* check against duplicate free */
        /* check for out-of-bounds writes */
-       osize = os[-2]; /* how much asked for last */
+       osize = os[-2];         /* how much asked for last */
+       assert(((osize + 7) & ~7) + MALLOC_EXTRA_SPACE + DEBUG_SPACE == asize);
        for (size_t i = osize; i < asize - MALLOC_EXTRA_SPACE; i++)
                assert(((char *) s)[i] == '\xBD');
        /* if shrinking, write debug pattern into to-be-freed memory */
@@ -2087,6 +2095,8 @@ GDKrealloc(void *s, size_t size)
        if (s == NULL) {
 #if !defined(NDEBUG) && !defined(SANITIZER)
                os[-1] &= ~2;   /* not freed after all */
+               assert(os[-1] == asize);
+               assert(os[-2] == osize);
 #endif
                GDKsyserror("realloc failed; memory requested: %zu, memory in 
use: %zu, virtual memory in use: %zu\n", size, GDKmem_cursize(), 
GDKvm_cursize());;
                return NULL;
@@ -2139,11 +2149,13 @@ GDKmmap(const char *path, int mode, size
 {
        void *ret;
 
+#ifndef SIZE_CHECK_IN_HEAPS_ONLY
        if (GDKvm_cursize() + len >= GDK_vm_maxsize &&
            !MT_thread_override_limits()) {
                GDKerror("requested too much virtual memory; memory requested: 
%zu, memory in use: %zu, virtual memory in use: %zu\n", len, GDKmem_cursize(), 
GDKvm_cursize());
                return NULL;
        }
+#endif
        ret = MT_mmap(path, mode, len);
        if (ret != NULL)
                meminc(len);
@@ -2170,12 +2182,14 @@ GDKmremap(const char *path, int mode, vo
 {
        void *ret;
 
+#ifndef SIZE_CHECK_IN_HEAPS_ONLY
        if (*new_size > old_size &&
            GDKvm_cursize() + *new_size - old_size >= GDK_vm_maxsize &&
            !MT_thread_override_limits()) {
                GDKerror("requested too much virtual memory; memory requested: 
%zu, memory in use: %zu, virtual memory in use: %zu\n", *new_size, 
GDKmem_cursize(), GDKvm_cursize());
                return NULL;
        }
+#endif
        ret = MT_mremap(path, mode, old_address, old_size, new_size);
        if (ret != NULL) {
                memdec(old_size);
diff --git a/monetdb5/mal/mal_session.c b/monetdb5/mal/mal_session.c
--- a/monetdb5/mal/mal_session.c
+++ b/monetdb5/mal/mal_session.c
@@ -916,6 +916,11 @@ optimizeMALBlock(Client cntxt, MalBlkPtr
                if (getModuleId(p) == optimizerRef && p->fcn && p->token != 
REMsymbol) {
                        actions++;
                        msg = (*(str (*)(Client, MalBlkPtr, MalStkPtr, 
InstrPtr))p->fcn)(cntxt, mb, 0, p);
+                       if (mb->errors) {
+                               freeException(msg);
+                               msg = mb->errors;
+                               mb->errors = NULL;
+                       }
                        if (msg) {
                                str place = getExceptionPlace(msg);
                                str nmsg = NULL;
diff --git a/monetdb5/optimizer/opt_wrapper.c b/monetdb5/optimizer/opt_wrapper.c
--- a/monetdb5/optimizer/opt_wrapper.c
+++ b/monetdb5/optimizer/opt_wrapper.c
@@ -111,8 +111,11 @@ OPTwrapper(Client cntxt, MalBlkPtr mb, M
        if( p == NULL)
                throw(MAL, "opt_wrapper", SQLSTATE(HY002) "missing optimizer 
statement");
 
-       if( mb->errors)
-               throw(MAL, "opt_wrapper", SQLSTATE(42000) "MAL block contains 
errors");
+       if (mb->errors) {
+               msg = mb->errors;
+               mb->errors = NULL;
+               return msg;
+       }
        fcnnme = getFunctionId(p);
 
        if( p && p->argc > 1 ){
@@ -147,6 +150,10 @@ OPTwrapper(Client cntxt, MalBlkPtr mb, M
        for (i = 0; codes[i].nme != NULL; i++) {
                if (strcmp(codes[i].nme, id) == 0) {
                        msg = (str)(*codes[i].fcn)(cntxt, mb, stk, p);
+                       if (mb->errors) {
+                               msg = mb->errors;
+                               mb->errors = NULL;
+                       }
                        clk = GDKusec() - clk;
                        MT_lock_set(&codeslock);
                        codes[i].timing += clk;
diff --git a/tools/mserver/mserver5.c b/tools/mserver/mserver5.c
--- a/tools/mserver/mserver5.c
+++ b/tools/mserver/mserver5.c
@@ -436,7 +436,7 @@ main(int argc, char **av)
                                        optarg[optarglen - 1] == '\\'))
                                        optarg[--optarglen] = '\0';
                                dbpath = absolute_path(optarg);
-                               if( dbpath == NULL)
+                               if (dbpath == NULL)
                                        fprintf(stderr, "#error: can not 
allocate memory for dbpath\n");
                                else
                                        setlen = mo_add_option(&set, setlen, 
opt_cmdline, "gdk_dbpath", dbpath);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to