Changeset: bf17d5c6f4b7 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bf17d5c6f4b7
Modified Files:
gdk/gdk_align.c
gdk/gdk_bat.c
gdk/gdk_bbp.c
gdk/gdk_private.h
gdk/gdk_storage.c
Branch: default
Log Message:
Check for errors higher up in the code instead of producing a fatal error.
When we can't extend the BBP for some reason (too many IDs or no
memory), return an error.
diffs (222 lines):
diff --git a/gdk/gdk_align.c b/gdk/gdk_align.c
--- a/gdk/gdk_align.c
+++ b/gdk/gdk_align.c
@@ -183,7 +183,14 @@ VIEWcreate_(oid seq, BAT *b, int slice_v
bn->timprints = NULL;
/* Order OID index */
bn->torderidx = NULL;
- BBPcacheit(bn, 1); /* enter in BBP */
+ if (BBPcacheit(bn, 1) != GDK_SUCCEED) { /* enter in BBP */
+ if (tp)
+ BBPunshare(tp);
+ if (bn->tvheap)
+ BBPunshare(bn->tvheap->parentid);
+ GDKfree(bn);
+ return NULL;
+ }
return bn;
}
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -101,7 +101,10 @@ BATcreatedesc(oid hseq, int tt, int heap
/*
* add to BBP
*/
- BBPinsert(bn);
+ if (BBPinsert(bn) == 0) {
+ GDKfree(bn);
+ return NULL;
+ }
/*
* Default zero for order oid index
*/
@@ -204,7 +207,10 @@ BATnewstorage(oid hseq, int tt, BUN cap,
goto bailout;
}
DELTAinit(bn);
- BBPcacheit(bn, 1);
+ if (BBPcacheit(bn, 1) != GDK_SUCCEED) {
+ GDKfree(bn->tvheap);
+ goto bailout;
+ }
return bn;
bailout:
HEAPfree(&bn->theap, 1);
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -333,19 +333,23 @@ BBPselectfarm(int role, int type, enum h
* BBPextend must take the trimlock, as it is called when other BBP
* locks are held and it will allocate memory.
*/
-static void
+static gdk_return
BBPextend(int idx, int buildhash)
{
- if ((bat) ATOMIC_GET(BBPsize, BBPsizeLock) >= N_BBPINIT * BBPINIT)
- GDKfatal("BBPextend: trying to extend BAT pool beyond the "
+ if ((bat) ATOMIC_GET(BBPsize, BBPsizeLock) >= N_BBPINIT * BBPINIT) {
+ GDKerror("BBPextend: trying to extend BAT pool beyond the "
"limit (%d)\n", N_BBPINIT * BBPINIT);
+ return GDK_FAIL;
+ }
/* make sure the new size is at least BBPsize large */
while (BBPlimit < (bat) ATOMIC_GET(BBPsize, BBPsizeLock)) {
assert(BBP[BBPlimit >> BBPINITLOG] == NULL);
BBP[BBPlimit >> BBPINITLOG] = GDKzalloc(BBPINIT *
sizeof(BBPrec));
- if (BBP[BBPlimit >> BBPINITLOG] == NULL)
- GDKfatal("BBPextend: failed to extend BAT pool\n");
+ if (BBP[BBPlimit >> BBPINITLOG] == NULL) {
+ GDKerror("BBPextend: failed to extend BAT pool\n");
+ return GDK_FAIL;
+ }
BBPlimit += BBPINIT;
}
@@ -358,6 +362,7 @@ BBPextend(int idx, int buildhash)
BBP_free(i) = 0;
BBPinithash(idx);
}
+ return GDK_SUCCEED;
}
static inline char *
@@ -1973,7 +1978,7 @@ BBPgetsubdir(str s, bat i)
* increasing BBPsize (up to BBPlimit) or extending the BBP (which
* increases BBPlimit). Every time this function is called we start
* searching in a following free list (variable "last"). */
-static void
+static gdk_return
maybeextend(int idx)
{
int t, m;
@@ -2004,14 +2009,31 @@ maybeextend(int idx)
} else {
/* let the longest list alone, get a fresh entry */
if ((bat) ATOMIC_ADD(BBPsize, 1, BBPsizeLock) >= BBPlimit) {
- BBPextend(idx, TRUE);
+ if (BBPextend(idx, TRUE) != GDK_SUCCEED) {
+ /* undo add */
+ ATOMIC_SUB(BBPsize, 1, BBPsizeLock);
+ /* couldn't extend; if there is any
+ * free entry, take it from the
+ * longest list after all */
+ if (l > 0) {
+ i = BBP_free(m);
+ BBP_free(m) = BBP_next(i);
+ BBP_next(i) = 0;
+ BBP_free(idx) = i;
+ } else {
+ /* nothing available */
+ return GDK_FAIL;
+ }
+ }
} else {
BBP_free(idx) = (bat) ATOMIC_GET(BBPsize, BBPsizeLock)
- 1;
}
}
last = (last + 1) & BBP_THREADMASK;
+ return GDK_SUCCEED;
}
+/* return new BAT id (> 0); return 0 on failure */
bat
BBPinsert(BAT *bn)
{
@@ -2031,6 +2053,7 @@ BBPinsert(BAT *bn)
/* find an empty slot */
if (BBP_free(idx) <= 0) {
/* we need to extend the BBP */
+ gdk_return r = GDK_SUCCEED;
if (lock) {
/* we must take all locks in a consistent
* order so first unset the one we've already
@@ -2043,13 +2066,20 @@ BBPinsert(BAT *bn)
/* check again in case some other thread extended
* while we were waiting */
if (BBP_free(idx) <= 0) {
- maybeextend(idx);
+ r = maybeextend(idx);
}
MT_lock_unset(&GDKnameLock);
if (lock)
for (i = BBP_THREADMASK; i >= 0; i--)
if (i != idx)
MT_lock_unset(&GDKcacheLock(i));
+ if (r != GDK_SUCCEED) {
+ if (lock) {
+ MT_lock_unset(&GDKcacheLock(idx));
+ MT_lock_unset(&GDKtrimLock(idx));
+ }
+ return 0;
+ }
}
i = BBP_free(idx);
assert(i > 0);
@@ -2101,7 +2131,7 @@ BBPinsert(BAT *bn)
return i;
}
-void
+gdk_return
BBPcacheit(BAT *bn, int lock)
{
bat i = bn->batCacheid;
@@ -2114,6 +2144,8 @@ BBPcacheit(BAT *bn, int lock)
assert(i > 0);
} else {
i = BBPinsert(bn); /* bat was not previously entered */
+ if (i == 0)
+ return GDK_FAIL;
if (bn->tvheap)
bn->tvheap->parentid = i;
}
@@ -2130,6 +2162,7 @@ BBPcacheit(BAT *bn, int lock)
if (lock)
MT_lock_unset(&GDKswapLock(i));
+ return GDK_SUCCEED;
}
/*
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -71,7 +71,8 @@ enum heaptype {
__attribute__((__visibility__("hidden")));
__hidden size_t BATvmsize(BAT *b, int dirty)
__attribute__((__visibility__("hidden")));
-__hidden void BBPcacheit(BAT *bn, int lock)
+__hidden gdk_return BBPcacheit(BAT *bn, int lock)
+ __attribute__ ((__warn_unused_result__))
__attribute__((__visibility__("hidden")));
void BBPdump(void); /* never called: for debugging only */
__hidden void BBPexit(void)
@@ -81,6 +82,7 @@ void BBPdump(void); /* never called: fo
__hidden void BBPinit(void)
__attribute__((__visibility__("hidden")));
__hidden bat BBPinsert(BAT *bn)
+ __attribute__ ((__warn_unused_result__))
__attribute__((__visibility__("hidden")));
__hidden int BBPselectfarm(int role, int type, enum heaptype hptype)
__attribute__((__visibility__("hidden")));
diff --git a/gdk/gdk_storage.c b/gdk/gdk_storage.c
--- a/gdk/gdk_storage.c
+++ b/gdk/gdk_storage.c
@@ -822,7 +822,12 @@ BATload_intern(bat bid, int lock)
b->theap.parentid = 0;
/* load succeeded; register it in BBP */
- BBPcacheit(b, lock);
+ if (BBPcacheit(b, lock) != GDK_SUCCEED) {
+ HEAPfree(&b->theap, 0);
+ if (b->tvheap)
+ HEAPfree(b->tvheap, 0);
+ return NULL;
+ }
if ((b->batRestricted == BAT_WRITE && (GDKdebug & CHECKMASK)) ||
(GDKdebug & PROPMASK)) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list