gpiosim: use twalk() instead of twalk_r()
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Fri, 10 Feb 2023 21:11:11 +0000 (22:11 +0100)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tue, 14 Feb 2023 08:13:59 +0000 (09:13 +0100)
twalk_r() is a GNU extension for the binary search tree API. Musl libc
doesn't provide it and after inquiring with the maintainer it turned out
it won't provide it anytime soon as musl strives to only implement well
standardized functions.

In order to not limit building libgpiosim and tests to glibc only, let's
replace twalk_r() with twalk() and use global variables for the state.
It's not a big deal as we're already using a global root node and a mutex
to protect it.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
configure.ac
tests/gpiosim/gpiosim.c

index 2bd71b0c690800d108b39b2e035e71a58d015f3d..d42b089a97295f056f76b0c24785e625df893e56 100644 (file)
@@ -162,7 +162,7 @@ then
        AC_CHECK_FUNC([openat], [], [FUNC_NOT_FOUND_LIB([openat])])
        AC_CHECK_FUNC([mkdirat], [], [FUNC_NOT_FOUND_LIB([mkdirat])])
        AC_CHECK_FUNC([write], [], [FUNC_NOT_FOUND_LIB([write])])
-       AC_CHECK_FUNC([twalk_r], [], [FUNC_NOT_FOUND_LIB([twalk_r])])
+       AC_CHECK_FUNC([twalk], [], [FUNC_NOT_FOUND_LIB([twalk])])
        AC_CHECK_FUNC([tsearch], [], [FUNC_NOT_FOUND_LIB([tsearch])])
        AC_CHECK_FUNC([tdestroy], [], [FUNC_NOT_FOUND_LIB([tdestroy])])
        AC_CHECK_FUNC([tdelete], [], [FUNC_NOT_FOUND_LIB([tdelete])])
index f46adfa741979fa4c474e193da54fc8f9a57720f..88d79f418114f7bf2c12df4b6c00eb2d70b0827e 100644 (file)
@@ -23,6 +23,7 @@
 #include "gpiosim.h"
 
 #define GPIOSIM_API            __attribute__((visibility("default")))
+#define UNUSED                 __attribute__((unused))
 #define ARRAY_SIZE(x)          (sizeof(x) / sizeof(*(x)))
 #define MIN_KERNEL_VERSION     KERNEL_VERSION(5, 17, 4)
 
@@ -30,15 +31,15 @@ static pthread_mutex_t id_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_once_t id_init_once = PTHREAD_ONCE_INIT;
 static void *id_root;
 
-struct id_find_next_ctx {
+struct {
        int lowest;
        bool found;
-};
+} id_find_next_ctx;
 
-struct id_del_ctx {
+struct {
        int id;
        int *idp;
-};
+} id_del_ctx;
 
 static void id_cleanup(void)
 {
@@ -62,40 +63,38 @@ static int id_compare(const void *p1, const void *p2)
        return 0;
 }
 
-static void id_find_next(const void *node, VISIT which, void *data)
+static void id_find_next(const void *node, VISIT which, int depth UNUSED)
 {
-       struct id_find_next_ctx *ctx = data;
        int *id = *(int **)node;
 
-       if (ctx->found)
+       if (id_find_next_ctx.found)
                return;
 
        switch (which) {
        case postorder:
        case leaf:
-               if (*id != ctx->lowest)
-                       ctx->found = true;
+               if (*id != id_find_next_ctx.lowest)
+                       id_find_next_ctx.found = true;
                else
-                       ctx->lowest++;
+                       id_find_next_ctx.lowest++;
                break;
        default:
                break;
        };
 }
 
-static void id_del(const void *node, VISIT which, void *data)
+static void id_del(const void *node, VISIT which, int depth UNUSED)
 {
-       struct id_del_ctx *ctx = data;
        int *id = *(int **)node;
 
-       if (ctx->idp)
+       if (id_del_ctx.idp)
                return;
 
        switch (which) {
        case postorder:
        case leaf:
-               if (*id == ctx->id)
-                       ctx->idp = id;
+               if (*id == id_del_ctx.id)
+                       id_del_ctx.idp = id;
                break;
        default:
                break;
@@ -104,18 +103,17 @@ static void id_del(const void *node, VISIT which, void *data)
 
 static int id_alloc(void)
 {
-       struct id_find_next_ctx ctx;
        void *ret;
        int *id;
 
        pthread_once(&id_init_once, id_schedule_cleanup);
 
-       ctx.lowest = 0;
-       ctx.found = false;
-
        pthread_mutex_lock(&id_lock);
 
-       twalk_r(id_root, id_find_next, &ctx);
+       id_find_next_ctx.lowest = 0;
+       id_find_next_ctx.found = false;
+
+       twalk(id_root, id_find_next);
 
        id = malloc(sizeof(*id));
        if (!id) {
@@ -123,7 +121,7 @@ static int id_alloc(void)
                return -1;
        }
 
-       *id = ctx.lowest;
+       *id = id_find_next_ctx.lowest;
 
        ret = tsearch(id, &id_root, id_compare);
        if (!ret) {
@@ -140,17 +138,15 @@ static int id_alloc(void)
 
 static void id_free(int id)
 {
-       struct id_del_ctx ctx;
-
-       ctx.id = id;
-       ctx.idp = NULL;
+       id_del_ctx.id = id;
+       id_del_ctx.idp = NULL;
 
        pthread_mutex_lock(&id_lock);
 
-       twalk_r(id_root, id_del, &ctx);
-       if (ctx.idp) {
-               tdelete(ctx.idp, &id_root, id_compare);
-               free(ctx.idp);
+       twalk(id_root, id_del);
+       if (id_del_ctx.idp) {
+               tdelete(id_del_ctx.idp, &id_root, id_compare);
+               free(id_del_ctx.idp);
        }
 
        pthread_mutex_unlock(&id_lock);