summaryrefslogtreecommitdiffstats
path: root/test/src
diff options
context:
space:
mode:
Diffstat (limited to 'test/src')
-rw-r--r--test/src/test.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/test/src/test.c b/test/src/test.c
index c5101d4..fe6dc60 100644
--- a/test/src/test.c
+++ b/test/src/test.c
@@ -1,10 +1,42 @@
#include "test/jemalloc_test.h"
+/* Test status state. */
+
static unsigned test_count = 0;
static test_status_t test_counts[test_status_count] = {0, 0, 0};
static test_status_t test_status = test_status_pass;
static const char * test_name = "";
+/* Reentrancy testing helpers. */
+
+#define NUM_REENTRANT_ALLOCS 20
+static bool reentrant = false;
+static bool hook_ran = false;
+static void *to_free[NUM_REENTRANT_ALLOCS];
+
+static void
+reentrancy_hook() {
+ hook_ran = true;
+ hooks_libc_hook = NULL;
+
+ void *to_free_local[NUM_REENTRANT_ALLOCS];
+ size_t alloc_size = 1;
+ for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) {
+ to_free[i] = malloc(alloc_size);
+ to_free_local[i] = malloc(alloc_size);
+ alloc_size *= 2;
+ }
+ for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) {
+ free(to_free_local[i]);
+ }
+}
+
+/* Actual test infrastructure. */
+bool
+test_is_reentrant() {
+ return reentrant;
+}
+
JEMALLOC_FORMAT_PRINTF(1, 2)
void
test_skip(const char *format, ...) {
@@ -49,11 +81,13 @@ p_test_init(const char *name) {
void
p_test_fini(void) {
test_counts[test_status]++;
- malloc_printf("%s: %s\n", test_name, test_status_string(test_status));
+ malloc_printf("%s: %s (%s)\n", test_name,
+ test_status_string(test_status),
+ reentrant ? "reentrant" : "non-reentrant");
}
static test_status_t
-p_test_impl(bool do_malloc_init, test_t *t, va_list ap) {
+p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) {
test_status_t ret;
if (do_malloc_init) {
@@ -71,10 +105,27 @@ p_test_impl(bool do_malloc_init, test_t *t, va_list ap) {
ret = test_status_pass;
for (; t != NULL; t = va_arg(ap, test_t *)) {
+ /* Non-reentrant run. */
+ reentrant = false;
t();
if (test_status > ret) {
ret = test_status;
}
+ /* Reentrant run. */
+ if (do_reentrant) {
+ reentrant = true;
+ hooks_libc_hook = &reentrancy_hook;
+ t();
+ if (test_status > ret) {
+ ret = test_status;
+ }
+ if (hook_ran) {
+ hook_ran = false;
+ for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) {
+ free(to_free[i]);
+ }
+ }
+ }
}
malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n",
@@ -95,7 +146,20 @@ p_test(test_t *t, ...) {
ret = test_status_pass;
va_start(ap, t);
- ret = p_test_impl(true, t, ap);
+ ret = p_test_impl(true, true, t, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+test_status_t
+p_test_no_reentrancy(test_t *t, ...) {
+ test_status_t ret;
+ va_list ap;
+
+ ret = test_status_pass;
+ va_start(ap, t);
+ ret = p_test_impl(true, false, t, ap);
va_end(ap);
return ret;
@@ -108,7 +172,11 @@ p_test_no_malloc_init(test_t *t, ...) {
ret = test_status_pass;
va_start(ap, t);
- ret = p_test_impl(false, t, ap);
+ /*
+ * We also omit reentrancy from bootstrapping tests, since we don't
+ * (yet) care about general reentrancy during bootstrapping.
+ */
+ ret = p_test_impl(false, false, t, ap);
va_end(ap);
return ret;