mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH RFC 2/3] test: self: add talloc selftest
Date: Mon, 27 Oct 2025 08:54:33 +0100	[thread overview]
Message-ID: <20251027075438.2480311-2-a.fatoum@barebox.org> (raw)
In-Reply-To: <20251027075438.2480311-1-a.fatoum@barebox.org>

This self test exercises the hierarchical properties of talloc.

Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
 test/self/Kconfig  |   6 ++
 test/self/Makefile |   1 +
 test/self/talloc.c | 153 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 160 insertions(+)
 create mode 100644 test/self/talloc.c

diff --git a/test/self/Kconfig b/test/self/Kconfig
index fa2911fa649a..23c82b4f2c93 100644
--- a/test/self/Kconfig
+++ b/test/self/Kconfig
@@ -47,6 +47,7 @@ config SELFTEST_ENABLE_ALL
 	select SELFTEST_IDR
 	select SELFTEST_TLV
 	select SELFTEST_DM
+	select SELFTEST_TALLOC
 	help
 	  Selects all self-tests compatible with current configuration
 
@@ -55,6 +56,11 @@ config SELFTEST_MALLOC
 	help
 	  Tests barebox memory allocator
 
+config SELFTEST_TALLOC
+	bool "talloc() selftest"
+	help
+	  Tests barebox talloc allocator
+
 config SELFTEST_PRINTF
 	bool "printf selftest"
 	help
diff --git a/test/self/Makefile b/test/self/Makefile
index 3d74bf9e98ad..3afaada5f54a 100644
--- a/test/self/Makefile
+++ b/test/self/Makefile
@@ -2,6 +2,7 @@
 
 obj-$(CONFIG_SELFTEST) += core.o
 obj-$(CONFIG_SELFTEST_MALLOC) += malloc.o
+obj-$(CONFIG_SELFTEST_TALLOC) += talloc.o
 obj-$(CONFIG_SELFTEST_PRINTF) += printf.o
 CFLAGS_printf.o += -Wno-format-security -Wno-format
 obj-$(CONFIG_SELFTEST_PROGRESS_NOTIFIER) += progress-notifier.o
diff --git a/test/self/talloc.c b/test/self/talloc.c
new file mode 100644
index 000000000000..1322269af498
--- /dev/null
+++ b/test/self/talloc.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) "talloc: " fmt
+
+#include <common.h>
+#include <stdlib.h>
+#include <bselftest.h>
+#include <talloc.h>
+#include <linux/sizes.h>
+#include <linux/bitops.h>
+
+BSELFTEST_GLOBALS();
+
+static bool __selftest_check(bool cond, const char *func, int line)
+{
+	total_tests ++;
+	if (cond)
+		return true;
+
+	pr_err("assertion failure at %s:%d\n", func, line);
+
+	failed_tests++;
+	return false;
+}
+#define selftest_check(cond) __selftest_check((cond), __func__, __LINE__)
+
+#define STRESS_ALLOCS  1024
+#define STRESS_ITERS   5000
+
+static void talloc_basic_tests(void)
+{
+	void *root, *a, *b, *c;
+	void *tmp;
+
+	root = talloc_size(NULL, 0);
+	selftest_check(root == ZERO_SIZE_PTR);
+
+	root = talloc_new(NULL);
+	if (!selftest_check(!ZERO_OR_NULL_PTR(root)))
+		return;
+
+	a = talloc_size(root, 128);
+	selftest_check(a);
+
+	selftest_check(talloc_parent(a) == root);
+
+	b = talloc_zero_size(root, 256);
+	selftest_check(b && memchr_inv(b, 0x00, 256) == NULL);
+
+	c = talloc_strdup(root, "barebox talloc test");
+	selftest_check(c);
+
+	tmp = talloc_realloc_size(talloc_parent(a), a, 512);
+	if (selftest_check(tmp))
+		a = tmp;
+
+	selftest_check(talloc_parent(a) == root);
+
+	selftest_check(talloc_total_blocks(root) == 4);
+
+	/* Free child and verify parent is intact */
+	talloc_free(a);
+	selftest_check(talloc_total_blocks(root) == 3);
+
+	talloc_free(b);
+	selftest_check(talloc_total_blocks(root) == 2);
+
+	talloc_free(c);
+	selftest_check(talloc_total_blocks(root) == 1);
+
+	talloc_free(root);
+}
+
+static void talloc_hierarchy_tests(void)
+{
+	void *root = talloc_new(NULL);
+	void *lvl1, *lvl2, *lvl3;
+
+	lvl1 = talloc_new(root);
+	lvl2 = talloc_new(lvl1);
+	lvl3 = talloc_size(lvl2, 64);
+
+	selftest_check(lvl1 && lvl2 && lvl3);
+
+	selftest_check(talloc_parent(lvl3) == lvl2);
+
+	talloc_free(lvl1); /* should free all children */
+	selftest_check(talloc_total_blocks(root) == 1);
+
+	talloc_free(root);
+}
+
+static void talloc_stress_tests(void)
+{
+	void *root = talloc_new(NULL);
+	void *ptrs[STRESS_ALLOCS];
+
+	memset(ptrs, 0, sizeof(ptrs));
+
+	for (int iter = 0; iter < STRESS_ITERS; iter++) {
+		int idx = prandom_u32_max(STRESS_ALLOCS);
+		if (ptrs[idx]) {
+			talloc_free(ptrs[idx]);
+			ptrs[idx] = NULL;
+		} else {
+			size_t sz = prandom_u32_max(4096) + 1;
+			ptrs[idx] = talloc_size(root, sz);
+			if (selftest_check(ptrs[idx]) &&
+			    prandom_u32_max(8) == 0) {
+				/* Occasionally realloc to a different size */
+				size_t new_sz = prandom_u32_max(8192) + 1;
+				void *tmp = talloc_realloc_size(NULL,
+								ptrs[idx], new_sz);
+				if (selftest_check(tmp))
+					ptrs[idx] = tmp;
+			}
+		}
+	}
+
+	for (int i = 0; i < STRESS_ALLOCS; i++) {
+		if (ptrs[i])
+			talloc_free(ptrs[i]);
+	}
+	talloc_free(root);
+}
+
+static void talloc_corner_cases(void)
+{
+	void *root = talloc_new(NULL);
+	void *large;
+
+	talloc_free(NULL);
+
+	void *realloc_null = talloc_realloc_size(NULL, NULL, 128);
+	selftest_check(realloc_null);
+	talloc_free(realloc_null);
+
+	/* Large alloc test (may fail gracefully if memory-constrained) */
+	large = talloc_size(root, 1024 * 1024 * 10);
+	if (selftest_check(large))
+		talloc_free(large);
+
+	talloc_free(root);
+}
+
+static void test_talloc(void)
+{
+	talloc_basic_tests();
+	talloc_hierarchy_tests();
+	talloc_stress_tests();
+	talloc_corner_cases();
+}
+bselftest(core, test_talloc);
-- 
2.47.3




  reply	other threads:[~2025-10-27  7:55 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-27  7:54 [PATCH RFC 1/3] lib: add talloc for overlaying a tree onto allocations Ahmad Fatoum
2025-10-27  7:54 ` Ahmad Fatoum [this message]
2025-10-27  7:54 ` [PATCH RFC 3/3] hush: fix memory leaks Ahmad Fatoum
2025-10-28  9:42 ` [PATCH RFC 1/3] lib: add talloc for overlaying a tree onto allocations Sascha Hauer
2025-10-28 10:26   ` Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251027075438.2480311-2-a.fatoum@barebox.org \
    --to=a.fatoum@barebox.org \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox