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 -- [email protected]
To unsubscribe send an email to [email protected]