Test uthread scheduling.

Signed-off-by: Jerome Forissier <[email protected]>
---
 lib/uthread.c      |  3 ++-
 test/lib/Makefile  |  1 +
 test/lib/uthread.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletion(-)
 create mode 100644 test/lib/uthread.c

diff --git a/lib/uthread.c b/lib/uthread.c
index bb132001fb6..1f8e6d0fa80 100644
--- a/lib/uthread.c
+++ b/lib/uthread.c
@@ -76,10 +76,11 @@ err:
 
 void uthread_free_all(void)
 {
+       struct uthread *main = &main_thread;
        struct uthread *next;
        struct uthread *tmp;
 
-       list_for_each_entry_safe(next, tmp, &current->list, list) {
+       list_for_each_entry_safe(next, tmp, &main->list, list) {
                list_del(&next->list);
                uthread_free(next);
        }
diff --git a/test/lib/Makefile b/test/lib/Makefile
index bf04685dae1..c991dff1c63 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_CRC8) += test_crc8.o
 obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o
 obj-$(CONFIG_UT_TIME) += time.o
 obj-$(CONFIG_$(XPL_)UT_UNICODE) += unicode.o
+obj-$(CONFIG_UTHREAD) += uthread.o
 obj-$(CONFIG_LIB_UUID) += uuid.o
 else
 obj-$(CONFIG_SANDBOX) += kconfig_spl.o
diff --git a/test/lib/uthread.c b/test/lib/uthread.c
new file mode 100644
index 00000000000..c9d030dc778
--- /dev/null
+++ b/test/lib/uthread.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Linaro Limited
+ *
+ * Unit test for uthread
+ */
+
+#include <stdbool.h>
+#include <test/lib.h>
+#include <test/ut.h>
+#include <uthread.h>
+
+static int count;
+
+static void worker(void *arg)
+{
+       int loops = (int)(unsigned long)arg;
+       int i;
+
+       for (i = 0; i < loops; i++) {
+               count++;
+               uthread_schedule();
+       }
+}
+
+static int lib_uthread(struct unit_test_state *uts)
+{
+       int i;
+
+       count = 0;
+       ut_assertok(uthread_create(worker, (void *)5, 0));
+       ut_assertok(uthread_create(worker, (void *)10, 0));
+       /*
+        * The first call is expected to schedule the first worker, which will
+        * schedule the second one, which will schedule back to the main thread
+        * (here). Therefore count should be 2.
+        */
+       ut_assert(uthread_schedule());
+       ut_asserteq(2, count);
+       /* Four more calls should bring the count to 10 */
+       for (i = 0; i < 4; i++)
+               ut_assert(uthread_schedule());
+       ut_asserteq(10, count);
+       /* This one allows the first worker to exit */
+       ut_assert(uthread_schedule());
+       /* Five more calls for the second worker to finish incrementing  */
+       for (i = 0; i < 5; i++)
+               ut_assert(uthread_schedule());
+       ut_asserteq(15, count);
+       /* Plus one call to let the second worker return from its entry point */
+       ut_assert(uthread_schedule());
+       /* Now both tasks should be done, schedule should return false */
+       ut_assert(!uthread_schedule());
+       uthread_free_all();
+
+       return 0;
+}
+LIB_TEST(lib_uthread, 0);
-- 
2.43.0

Reply via email to