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]

Reply via email to