Changeset: 9717c895f5e3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/9717c895f5e3
Modified Files:
gdk/gdk_system.c
gdk/gdk_system_private.h
gdk/gdk_utils.c
geom/monetdb5/geom_atoms.c
sql/backends/monet5/sql_cast.c
sql/backends/monet5/sql_result.c
sql/backends/monet5/sql_result.h
Branch: Dec2025
Log Message:
Assert that lockless allocators are only used in a single thread.
Fixed a couple of incorrect usages.
Also, only count allocator uses only in debug mode.
diffs (227 lines):
diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -978,6 +978,9 @@ MT_create_thread(MT_Id *t, void (*f) (vo
GDKerror("Creating thread allocator failed\n");
return -1;
}
+#ifndef NDEBUG
+ self->ma->self = self->tid;
+#endif
MT_lock_set(&thread_init_lock);
/* remember the list of callback functions we need to call for
* this thread (i.e. anything registered so far) */
diff --git a/gdk/gdk_system_private.h b/gdk/gdk_system_private.h
--- a/gdk/gdk_system_private.h
+++ b/gdk/gdk_system_private.h
@@ -57,13 +57,16 @@ struct allocator {
size_t usedmem; /* total used memory */
size_t objects; /* number of objects */
size_t inuse; /* number of objects in use*/
- size_t free_obj_hits; /* number of object reuse*/
void *freelist; /* first free object */
- size_t frees;
size_t tmp_used; /* counter for temp usage */
exception_buffer eb;
MT_Lock lock; /* lock for thread-safe allocations */
bool use_lock;
+#ifndef NDEBUG
+ MT_Id self;
+ size_t free_obj_hits; /* number of objects reused */
+ size_t frees; /* number of objects freed */
+#endif
char name[MT_NAME_LEN]; /* Name (only for display!) */
};
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -2014,7 +2014,7 @@ GDKmremap(const char *path, int mode, vo
if ((a)->use_lock) { \
MT_lock_set(&(a)->lock); \
__alloc_locked = true; \
- }
+ } else assert((a)->self == MT_getpid());
#define COND_UNLOCK_ALLOCATOR(a) \
if (__alloc_locked) { \
@@ -2111,7 +2111,9 @@ ma_use_freed_obj(allocator *sa, size_t s
} else {
sa->freelist = curr->n;
}
+#ifndef NDEBUG
sa->free_obj_hits += 1;
+#endif
sa->inuse += 1;
COND_UNLOCK_ALLOCATOR(sa);
return curr;
@@ -2184,7 +2186,9 @@ ma_reset(allocator *sa)
sa->size = MA_NUM_BLOCKS;
sa->blks[0] = sa->first_blk;
sa->used = offset;
+#ifndef NDEBUG
sa->frees = 0;
+#endif
sa->nr = 1;
sa->freelist = NULL;
sa->objects = 0;
@@ -2337,13 +2341,16 @@ create_allocator(const char *name, bool
.nr = 1,
.usedmem = MA_BLOCK_SIZE,
.freelist = NULL,
- .frees = 0,
.used = offset,
.objects = 0,
.inuse = 0,
- .free_obj_hits = 0,
.tmp_used = 0,
.use_lock = use_lock,
+#ifndef NDEBUG
+ .frees = 0,
+ .free_obj_hits = 0,
+ .self = MT_getpid(),
+#endif
};
sa->blks[0] = first_blk;
eb_init(&sa->eb);
@@ -2521,7 +2528,9 @@ ma_free(allocator *sa, void *obj)
ma_free_obj(sa, ptr, sz);
else
ma_free_blk(sa, ptr);
+#ifndef NDEBUG
sa->frees++;
+#endif
COND_UNLOCK_ALLOCATOR(sa);
}
@@ -2532,7 +2541,7 @@ ma_info(allocator *a, char *buf, size_t
int pos = 0;
buf[0] = 0;
if (a != NULL) {
- COND_LOCK_ALLOCATOR(a);
+ MT_lock_set(&a->lock);
pos = snprintf(buf, bufsize, "%s%s: used %zu%s, nr %zu, usedmem
%zu%s",
pref ? pref : "", a->name,
a->used, humansize(a->used, (char[24]){0}, 24),
@@ -2547,7 +2556,7 @@ ma_info(allocator *a, char *buf, size_t
if (a->tmp_used > 0 && (size_t) pos < bufsize)
pos += snprintf(buf + pos, bufsize - pos,
", tmp_used %zu", a->tmp_used);
- COND_UNLOCK_ALLOCATOR(a);
+ MT_lock_unset(&a->lock);
}
return pos;
}
diff --git a/geom/monetdb5/geom_atoms.c b/geom/monetdb5/geom_atoms.c
--- a/geom/monetdb5/geom_atoms.c
+++ b/geom/monetdb5/geom_atoms.c
@@ -626,7 +626,7 @@ wkbMBR(Client ctx, mbr **geomMBR, wkb **
GEOSGeom geosGeometry;
str ret = MAL_SUCCEED;
bit empty;
- allocator *ma = ctx->ma;
+ allocator *ma = ctx->curprg->def->ma;
assert(ma);
//check if the geometry is nil
diff --git a/sql/backends/monet5/sql_cast.c b/sql/backends/monet5/sql_cast.c
--- a/sql/backends/monet5/sql_cast.c
+++ b/sql/backends/monet5/sql_cast.c
@@ -49,9 +49,9 @@ str_buf_initial_capacity(sql_class eclas
}
static inline str
-SQLstr_cast_any_type(str *r, size_t *rlen, mvc *m, sql_class eclass, int d,
int s, int has_tz, const void *p, int tpe, int len)
+SQLstr_cast_any_type(allocator *ma, str *r, size_t *rlen, mvc *m, sql_class
eclass, int d, int s, int has_tz, const void *p, int tpe, int len)
{
- ssize_t sz = convert2str(m, eclass, d, s, has_tz, p, tpe, r, rlen);
+ ssize_t sz = convert2str(ma, m, eclass, d, s, has_tz, p, tpe, r, rlen);
if ((len > 0 && sz > (ssize_t) len) || sz < 0)
throw(SQL, "str_cast", SQLSTATE(22001) "value too long for type
(var)char(%d)", len);
return MAL_SUCCEED;
@@ -83,7 +83,7 @@ SQLstr_cast(Client cntxt, MalBlkPtr mb,
size_t rlen = MAX(str_buf_initial_capacity(eclass, digits),
strlen(str_nil) + 1); /* don't reallocate on str_nil */
if (!(r = ma_alloc(mb->ma, rlen)))
throw(SQL, "calc.str_cast", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
- if ((msg = SQLstr_cast_any_type(&r, &rlen, m, eclass, d, s,
has_tz, p, tpe, digits)) != MAL_SUCCEED) {
+ if ((msg = SQLstr_cast_any_type(mb->ma, &r, &rlen, m, eclass,
d, s, has_tz, p, tpe, digits)) != MAL_SUCCEED) {
// GDKfree(r);
return msg;
}
@@ -207,7 +207,7 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
oid p = (canditer_next_dense(&ci) - off);
const void *v = BUNtail(bi, p);
- if ((msg = SQLstr_cast_any_type(&r, &rlen, m,
eclass, d1, s1, has_tz, v, tpe, digits)) != MAL_SUCCEED)
+ if ((msg = SQLstr_cast_any_type(mb->ma, &r,
&rlen, m, eclass, d1, s1, has_tz, v, tpe, digits)) != MAL_SUCCEED)
goto bailout1;
if (tfastins_nocheckVAR(dst, i, r) !=
GDK_SUCCEED) {
msg = createException(SQL,
"batcalc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL);
@@ -241,7 +241,7 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
oid p = (canditer_next(&ci) - off);
const void *v = BUNtail(bi, p);
- if ((msg = SQLstr_cast_any_type(&r, &rlen, m,
eclass, d1, s1, has_tz, v, tpe, digits)) != MAL_SUCCEED)
+ if ((msg = SQLstr_cast_any_type(mb->ma, &r,
&rlen, m, eclass, d1, s1, has_tz, v, tpe, digits)) != MAL_SUCCEED)
goto bailout1;
if (tfastins_nocheckVAR(dst, i, r) !=
GDK_SUCCEED) {
msg = createException(SQL,
"batcalc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL);
diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c
--- a/sql/backends/monet5/sql_result.c
+++ b/sql/backends/monet5/sql_result.c
@@ -1069,7 +1069,7 @@ mvc_send_hge(stream *s, hge cnt)
#endif
ssize_t
-convert2str(mvc *m, sql_class eclass, int d, int sc, int has_tz, const void
*p, int mtype, char **buf, size_t *len)
+convert2str(allocator *ma, mvc *m, sql_class eclass, int d, int sc, int
has_tz, const void *p, int mtype, char **buf, size_t *len)
{
ssize_t l = 0;
@@ -1077,21 +1077,21 @@ convert2str(mvc *m, sql_class eclass, in
(*buf)[0] = '\200';
(*buf)[1] = 0;
} else if (eclass == EC_DEC) {
- l = dec_tostr(m->sa, (void *) (ptrdiff_t) sc, buf, len, mtype,
p);
+ l = dec_tostr(ma, (void *) (ptrdiff_t) sc, buf, len, mtype, p);
} else if (eclass == EC_TIME || eclass == EC_TIME_TZ) {
struct time_res ts_res;
ts_res.has_tz = has_tz;
ts_res.fraction = d ? d - 1 : 0;
ts_res.timezone = m->timezone;
- l = sql_time_tostr(m->sa, (void *) &ts_res, buf, len, mtype, p);
+ l = sql_time_tostr(ma, (void *) &ts_res, buf, len, mtype, p);
} else if (eclass == EC_TIMESTAMP || eclass == EC_TIMESTAMP_TZ) {
struct time_res ts_res;
ts_res.has_tz = has_tz;
ts_res.fraction = d ? d - 1 : 0;
ts_res.timezone = m->timezone;
- l = sql_timestamp_tostr(m->sa, (void *) &ts_res, buf, len,
mtype, p);
+ l = sql_timestamp_tostr(ma, (void *) &ts_res, buf, len, mtype,
p);
} else if (eclass == EC_SEC) {
- l = dec_tostr(m->sa, (void *) (ptrdiff_t) 3, buf, len, mtype,
p);
+ l = dec_tostr(ma, (void *) (ptrdiff_t) 3, buf, len, mtype, p);
} else if (eclass == EC_BIT) {
bit b = *(bit *) p;
if (*len == 0 || *len > 5) {
@@ -1108,7 +1108,7 @@ convert2str(mvc *m, sql_class eclass, in
l = 1;
}
} else {
- l = (*BATatoms[mtype].atomToStr) (m->sa, buf, len, p, false);
+ l = (*BATatoms[mtype].atomToStr) (ma, buf, len, p, false);
}
return l;
}
diff --git a/sql/backends/monet5/sql_result.h b/sql/backends/monet5/sql_result.h
--- a/sql/backends/monet5/sql_result.h
+++ b/sql/backends/monet5/sql_result.h
@@ -47,7 +47,7 @@ extern int mvc_result_value(backend *be,
*/
extern const char *mvc_export_error(backend *be, stream *s, int err_code);
-extern ssize_t convert2str(mvc *m, sql_class eclass, int d, int sc, int
has_tz, const void *p, int mtype, char **buf, size_t *len);
+extern ssize_t convert2str(allocator *ma, mvc *m, sql_class eclass, int d, int
sc, int has_tz, const void *p, int mtype, char **buf, size_t *len);
extern int mvc_export(mvc *m, stream *s, res_table *t, BUN nr);
#endif /* sql_result_H */
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]