Blame memkind-1.10.1/jemalloc/test/src/test.c

Packit Service 7f3b24
#include "test/jemalloc_test.h"
Packit Service 7f3b24
Packit Service 7f3b24
/* Test status state. */
Packit Service 7f3b24
Packit Service 7f3b24
static unsigned		test_count = 0;
Packit Service 7f3b24
static test_status_t	test_counts[test_status_count] = {0, 0, 0};
Packit Service 7f3b24
static test_status_t	test_status = test_status_pass;
Packit Service 7f3b24
static const char *	test_name = "";
Packit Service 7f3b24
Packit Service 7f3b24
/* Reentrancy testing helpers. */
Packit Service 7f3b24
Packit Service 7f3b24
#define NUM_REENTRANT_ALLOCS 20
Packit Service 7f3b24
typedef enum {
Packit Service 7f3b24
	non_reentrant = 0,
Packit Service 7f3b24
	libc_reentrant = 1,
Packit Service 7f3b24
	arena_new_reentrant = 2
Packit Service 7f3b24
} reentrancy_t;
Packit Service 7f3b24
static reentrancy_t reentrancy;
Packit Service 7f3b24
Packit Service 7f3b24
static bool libc_hook_ran = false;
Packit Service 7f3b24
static bool arena_new_hook_ran = false;
Packit Service 7f3b24
Packit Service 7f3b24
static const char *
Packit Service 7f3b24
reentrancy_t_str(reentrancy_t r) {
Packit Service 7f3b24
	switch (r) {
Packit Service 7f3b24
	case non_reentrant:
Packit Service 7f3b24
		return "non-reentrant";
Packit Service 7f3b24
	case libc_reentrant:
Packit Service 7f3b24
		return "libc-reentrant";
Packit Service 7f3b24
	case arena_new_reentrant:
Packit Service 7f3b24
		return "arena_new-reentrant";
Packit Service 7f3b24
	default:
Packit Service 7f3b24
		unreachable();
Packit Service 7f3b24
	}
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static void
Packit Service 7f3b24
do_hook(bool *hook_ran, void (**hook)()) {
Packit Service 7f3b24
	*hook_ran = true;
Packit Service 7f3b24
	*hook = NULL;
Packit Service 7f3b24
Packit Service 7f3b24
	size_t alloc_size = 1;
Packit Service 7f3b24
	for (int i = 0; i < NUM_REENTRANT_ALLOCS; i++) {
Packit Service 7f3b24
		free(malloc(alloc_size));
Packit Service 7f3b24
		alloc_size *= 2;
Packit Service 7f3b24
	}
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static void
Packit Service 7f3b24
libc_reentrancy_hook() {
Packit Service 7f3b24
	do_hook(&libc_hook_ran, &test_hooks_libc_hook);
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static void
Packit Service 7f3b24
arena_new_reentrancy_hook() {
Packit Service 7f3b24
	do_hook(&arena_new_hook_ran, &test_hooks_arena_new_hook);
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
/* Actual test infrastructure. */
Packit Service 7f3b24
bool
Packit Service 7f3b24
test_is_reentrant() {
Packit Service 7f3b24
	return reentrancy != non_reentrant;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
JEMALLOC_FORMAT_PRINTF(1, 2)
Packit Service 7f3b24
void
Packit Service 7f3b24
test_skip(const char *format, ...) {
Packit Service 7f3b24
	va_list ap;
Packit Service 7f3b24
Packit Service 7f3b24
	va_start(ap, format);
Packit Service 7f3b24
	malloc_vcprintf(NULL, NULL, format, ap);
Packit Service 7f3b24
	va_end(ap);
Packit Service 7f3b24
	malloc_printf("\n");
Packit Service 7f3b24
	test_status = test_status_skip;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
JEMALLOC_FORMAT_PRINTF(1, 2)
Packit Service 7f3b24
void
Packit Service 7f3b24
test_fail(const char *format, ...) {
Packit Service 7f3b24
	va_list ap;
Packit Service 7f3b24
Packit Service 7f3b24
	va_start(ap, format);
Packit Service 7f3b24
	malloc_vcprintf(NULL, NULL, format, ap);
Packit Service 7f3b24
	va_end(ap);
Packit Service 7f3b24
	malloc_printf("\n");
Packit Service 7f3b24
	test_status = test_status_fail;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static const char *
Packit Service 7f3b24
test_status_string(test_status_t test_status) {
Packit Service 7f3b24
	switch (test_status) {
Packit Service 7f3b24
	case test_status_pass: return "pass";
Packit Service 7f3b24
	case test_status_skip: return "skip";
Packit Service 7f3b24
	case test_status_fail: return "fail";
Packit Service 7f3b24
	default: not_reached();
Packit Service 7f3b24
	}
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
void
Packit Service 7f3b24
p_test_init(const char *name) {
Packit Service 7f3b24
	test_count++;
Packit Service 7f3b24
	test_status = test_status_pass;
Packit Service 7f3b24
	test_name = name;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
void
Packit Service 7f3b24
p_test_fini(void) {
Packit Service 7f3b24
	test_counts[test_status]++;
Packit Service 7f3b24
	malloc_printf("%s (%s): %s\n", test_name, reentrancy_t_str(reentrancy),
Packit Service 7f3b24
	    test_status_string(test_status));
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static void
Packit Service 7f3b24
check_global_slow(test_status_t *status) {
Packit Service 7f3b24
#ifdef JEMALLOC_UNIT_TEST
Packit Service 7f3b24
	/*
Packit Service 7f3b24
	 * This check needs to peek into tsd internals, which is why it's only
Packit Service 7f3b24
	 * exposed in unit tests.
Packit Service 7f3b24
	 */
Packit Service 7f3b24
	if (tsd_global_slow()) {
Packit Service 7f3b24
		malloc_printf("Testing increased global slow count\n");
Packit Service 7f3b24
		*status = test_status_fail;
Packit Service 7f3b24
	}
Packit Service 7f3b24
#endif
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static test_status_t
Packit Service 7f3b24
p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) {
Packit Service 7f3b24
	test_status_t ret;
Packit Service 7f3b24
Packit Service 7f3b24
	if (do_malloc_init) {
Packit Service 7f3b24
		/*
Packit Service 7f3b24
		 * Make sure initialization occurs prior to running tests.
Packit Service 7f3b24
		 * Tests are special because they may use internal facilities
Packit Service 7f3b24
		 * prior to triggering initialization as a side effect of
Packit Service 7f3b24
		 * calling into the public API.
Packit Service 7f3b24
		 */
Packit Service 7f3b24
		if (nallocx(1, 0) == 0) {
Packit Service 7f3b24
			malloc_printf("Initialization error");
Packit Service 7f3b24
			return test_status_fail;
Packit Service 7f3b24
		}
Packit Service 7f3b24
	}
Packit Service 7f3b24
Packit Service 7f3b24
	ret = test_status_pass;
Packit Service 7f3b24
	for (; t != NULL; t = va_arg(ap, test_t *)) {
Packit Service 7f3b24
		/* Non-reentrant run. */
Packit Service 7f3b24
		reentrancy = non_reentrant;
Packit Service 7f3b24
		test_hooks_arena_new_hook = test_hooks_libc_hook = NULL;
Packit Service 7f3b24
		t();
Packit Service 7f3b24
		if (test_status > ret) {
Packit Service 7f3b24
			ret = test_status;
Packit Service 7f3b24
		}
Packit Service 7f3b24
		check_global_slow(&ret;;
Packit Service 7f3b24
		/* Reentrant run. */
Packit Service 7f3b24
		if (do_reentrant) {
Packit Service 7f3b24
			reentrancy = libc_reentrant;
Packit Service 7f3b24
			test_hooks_arena_new_hook = NULL;
Packit Service 7f3b24
			test_hooks_libc_hook = &libc_reentrancy_hook;
Packit Service 7f3b24
			t();
Packit Service 7f3b24
			if (test_status > ret) {
Packit Service 7f3b24
				ret = test_status;
Packit Service 7f3b24
			}
Packit Service 7f3b24
			check_global_slow(&ret;;
Packit Service 7f3b24
Packit Service 7f3b24
			reentrancy = arena_new_reentrant;
Packit Service 7f3b24
			test_hooks_libc_hook = NULL;
Packit Service 7f3b24
			test_hooks_arena_new_hook = &arena_new_reentrancy_hook;
Packit Service 7f3b24
			t();
Packit Service 7f3b24
			if (test_status > ret) {
Packit Service 7f3b24
				ret = test_status;
Packit Service 7f3b24
			}
Packit Service 7f3b24
			check_global_slow(&ret;;
Packit Service 7f3b24
		}
Packit Service 7f3b24
	}
Packit Service 7f3b24
Packit Service 7f3b24
	malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n",
Packit Service 7f3b24
	    test_status_string(test_status_pass),
Packit Service 7f3b24
	    test_counts[test_status_pass], test_count,
Packit Service 7f3b24
	    test_status_string(test_status_skip),
Packit Service 7f3b24
	    test_counts[test_status_skip], test_count,
Packit Service 7f3b24
	    test_status_string(test_status_fail),
Packit Service 7f3b24
	    test_counts[test_status_fail], test_count);
Packit Service 7f3b24
Packit Service 7f3b24
	return ret;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
test_status_t
Packit Service 7f3b24
p_test(test_t *t, ...) {
Packit Service 7f3b24
	test_status_t ret;
Packit Service 7f3b24
	va_list ap;
Packit Service 7f3b24
Packit Service 7f3b24
	ret = test_status_pass;
Packit Service 7f3b24
	va_start(ap, t);
Packit Service 7f3b24
	ret = p_test_impl(true, true, t, ap);
Packit Service 7f3b24
	va_end(ap);
Packit Service 7f3b24
Packit Service 7f3b24
	return ret;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
test_status_t
Packit Service 7f3b24
p_test_no_reentrancy(test_t *t, ...) {
Packit Service 7f3b24
	test_status_t ret;
Packit Service 7f3b24
	va_list ap;
Packit Service 7f3b24
Packit Service 7f3b24
	ret = test_status_pass;
Packit Service 7f3b24
	va_start(ap, t);
Packit Service 7f3b24
	ret = p_test_impl(true, false, t, ap);
Packit Service 7f3b24
	va_end(ap);
Packit Service 7f3b24
Packit Service 7f3b24
	return ret;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
test_status_t
Packit Service 7f3b24
p_test_no_malloc_init(test_t *t, ...) {
Packit Service 7f3b24
	test_status_t ret;
Packit Service 7f3b24
	va_list ap;
Packit Service 7f3b24
Packit Service 7f3b24
	ret = test_status_pass;
Packit Service 7f3b24
	va_start(ap, t);
Packit Service 7f3b24
	/*
Packit Service 7f3b24
	 * We also omit reentrancy from bootstrapping tests, since we don't
Packit Service 7f3b24
	 * (yet) care about general reentrancy during bootstrapping.
Packit Service 7f3b24
	 */
Packit Service 7f3b24
	ret = p_test_impl(false, false, t, ap);
Packit Service 7f3b24
	va_end(ap);
Packit Service 7f3b24
Packit Service 7f3b24
	return ret;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
void
Packit Service 7f3b24
p_test_fail(const char *prefix, const char *message) {
Packit Service 7f3b24
	malloc_cprintf(NULL, NULL, "%s%s\n", prefix, message);
Packit Service 7f3b24
	test_status = test_status_fail;
Packit Service 7f3b24
}