Exemplo n.º 1
0
TEST_END

TEST_BEGIN(test_stats_arenas_huge)
{
	unsigned arena;
	void *p;
	size_t sz, allocated;
	uint64_t epoch, nmalloc, ndalloc;
	int expected = config_stats ? 0 : ENOENT;

	arena = 0;
	assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
	    sizeof(arena)), 0, "Unexpected mallctl() failure");

	p = mallocx(chunksize, 0);
	assert_ptr_not_null(p, "Unexpected mallocx() failure");

	assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
	    0, "Unexpected mallctl() failure");

	sz = sizeof(size_t);
	assert_d_eq(mallctl("stats.arenas.0.huge.allocated", (void *)&allocated,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	sz = sizeof(uint64_t);
	assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", (void *)&nmalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", (void *)&ndalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");

	if (config_stats) {
		assert_zu_gt(allocated, 0,
		    "allocated should be greater than zero");
		assert_u64_gt(nmalloc, 0,
		    "nmalloc should be greater than zero");
		assert_u64_ge(nmalloc, ndalloc,
		    "nmalloc should be at least as large as ndalloc");
	}

	dallocx(p, 0);
}
Exemplo n.º 2
0
/*
 * Use a separate arena for xallocx() extension/contraction tests so that
 * internal allocation e.g. by heap profiling can't interpose allocations where
 * xallocx() would ordinarily be able to extend.
 */
static unsigned
arena_ind(void)
{
	static unsigned ind = 0;

	if (ind == 0) {
		size_t sz = sizeof(ind);
		assert_d_eq(mallctl("arenas.extend", (void *)&ind, &sz, NULL,
		    0), 0, "Unexpected mallctl failure creating arena");
	}

	return (ind);
}
Exemplo n.º 3
0
static size_t
get_max_size_class(void)
{
	unsigned nhchunks;
	size_t mib[4];
	size_t sz, miblen, max_size_class;

	sz = sizeof(unsigned);
	assert_d_eq(mallctl("arenas.nhchunks", (void *)&nhchunks, &sz, NULL, 0),
	    0, "Unexpected mallctl() error");

	miblen = sizeof(mib) / sizeof(size_t);
	assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() error");
	mib[2] = nhchunks - 1;

	sz = sizeof(size_t);
	assert_d_eq(mallctlbymib(mib, miblen, (void *)&max_size_class, &sz,
	    NULL, 0), 0, "Unexpected mallctlbymib() error");

	return (max_size_class);
}
Exemplo n.º 4
0
TEST_END

TEST_BEGIN(test_stats_huge)
{
	void *p;
	uint64_t epoch;
	size_t allocated;
	uint64_t nmalloc, ndalloc, nrequests;
	size_t sz;
	int expected = config_stats ? 0 : ENOENT;

	p = mallocx(large_maxclass+1, 0);
	assert_ptr_not_null(p, "Unexpected mallocx() failure");

	assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
	    0, "Unexpected mallctl() failure");

	sz = sizeof(size_t);
	assert_d_eq(mallctl("stats.arenas.0.huge.allocated", (void *)&allocated,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	sz = sizeof(uint64_t);
	assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", (void *)&nmalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", (void *)&ndalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", (void *)&nrequests,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");

	if (config_stats) {
		assert_zu_gt(allocated, 0,
		    "allocated should be greater than zero");
		assert_u64_ge(nmalloc, ndalloc,
		    "nmalloc should be at least as large as ndalloc");
		assert_u64_le(nmalloc, nrequests,
		    "nmalloc should no larger than nrequests");
	}

	dallocx(p, 0);
}
Exemplo n.º 5
0
TEST_END

TEST_BEGIN(test_hooks_null) {
	/* Null hooks should be ignored, not crash. */
	hooks_t hooks1 = {NULL, NULL, NULL, NULL};
	hooks_t hooks2 = {&test_alloc_hook, NULL, NULL, NULL};
	hooks_t hooks3 = {NULL, &test_dalloc_hook, NULL, NULL};
	hooks_t hooks4 = {NULL, NULL, &test_expand_hook, NULL};

	void *handle1 = hook_install(TSDN_NULL, &hooks1);
	void *handle2 = hook_install(TSDN_NULL, &hooks2);
	void *handle3 = hook_install(TSDN_NULL, &hooks3);
	void *handle4 = hook_install(TSDN_NULL, &hooks4);

	assert_ptr_ne(handle1, NULL, "Hook installation failed");
	assert_ptr_ne(handle2, NULL, "Hook installation failed");
	assert_ptr_ne(handle3, NULL, "Hook installation failed");
	assert_ptr_ne(handle4, NULL, "Hook installation failed");

	uintptr_t args_raw[4] = {10, 20, 30, 40};

	call_count = 0;
	hook_invoke_alloc(hook_alloc_malloc, NULL, 0, args_raw);
	assert_d_eq(call_count, 1, "Called wrong number of times");

	call_count = 0;
	hook_invoke_dalloc(hook_dalloc_free, NULL, args_raw);
	assert_d_eq(call_count, 1, "Called wrong number of times");

	call_count = 0;
	hook_invoke_expand(hook_expand_realloc, NULL, 0, 0, 0, args_raw);
	assert_d_eq(call_count, 1, "Called wrong number of times");

	hook_remove(TSDN_NULL, handle1);
	hook_remove(TSDN_NULL, handle2);
	hook_remove(TSDN_NULL, handle3);
	hook_remove(TSDN_NULL, handle4);
}
Exemplo n.º 6
0
TEST_END

TEST_BEGIN(test_arena_i_initialized) {
	unsigned narenas, i;
	size_t sz;
	size_t mib[3];
	size_t miblen = sizeof(mib) / sizeof(size_t);
	bool initialized;

	sz = sizeof(narenas);
	assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
	    0, "Unexpected mallctl() failure");

	assert_d_eq(mallctlnametomib("arena.0.initialized", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() failure");
	for (i = 0; i < narenas; i++) {
		mib[1] = i;
		sz = sizeof(initialized);
		assert_d_eq(mallctlbymib(mib, miblen, &initialized, &sz, NULL,
		    0), 0, "Unexpected mallctl() failure");
	}

	mib[1] = MALLCTL_ARENAS_ALL;
	sz = sizeof(initialized);
	assert_d_eq(mallctlbymib(mib, miblen, &initialized, &sz, NULL, 0), 0,
	    "Unexpected mallctl() failure");
	assert_true(initialized,
	    "Merged arena statistics should always be initialized");

	/* Equivalent to the above but using mallctl() directly. */
	sz = sizeof(initialized);
	assert_d_eq(mallctl(
	    "arena." STRINGIFY(MALLCTL_ARENAS_ALL) ".initialized",
	    (void *)&initialized, &sz, NULL, 0), 0,
	    "Unexpected mallctl() failure");
	assert_true(initialized,
	    "Merged arena statistics should always be initialized");
}
Exemplo n.º 7
0
TEST_END

static unsigned
get_nsizes_impl(const char *cmd)
{
	unsigned ret;
	size_t z;

	z = sizeof(unsigned);
	assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
	    "Unexpected mallctl(\"%s\", ...) failure", cmd);

	return (ret);
}
Exemplo n.º 8
0
TEST_END

TEST_BEGIN(test_arena_i_decay) {
	unsigned narenas;
	size_t sz = sizeof(unsigned);
	size_t mib[3];
	size_t miblen = 3;

	assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
	    "Unexpected mallctl() failure");

	assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
	    0, "Unexpected mallctl() failure");
	assert_d_eq(mallctlnametomib("arena.0.decay", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() failure");
	mib[1] = narenas;
	assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
	    "Unexpected mallctlbymib() failure");

	mib[1] = MALLCTL_ARENAS_ALL;
	assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
	    "Unexpected mallctlbymib() failure");
}
Exemplo n.º 9
0
TEST_END

TEST_BEGIN(test_mallctlnametomib_short_mib) {
	size_t mib[4];
	size_t miblen;

	miblen = 3;
	mib[3] = 42;
	assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() failure");
	assert_zu_eq(miblen, 3, "Unexpected mib output length");
	assert_zu_eq(mib[3], 42,
	    "mallctlnametomib() wrote past the end of the input mib");
}
Exemplo n.º 10
0
static void
mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,
    int line)
{
	const char *thread_name_old;
	size_t sz;

	sz = sizeof(thread_name_old);
	assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz, NULL, 0),
	    0, "%s():%d: Unexpected mallctl failure reading thread.prof.name",
	    func, line);
	assert_str_eq(thread_name_old, thread_name_expected,
	    "%s():%d: Unexpected thread.prof.name value", func, line);
}
Exemplo n.º 11
0
static void
mallctl_bool_set(const char *name, bool old_expected, bool val_new,
    const char *func, int line)
{
	bool old;
	size_t sz;

	sz = sizeof(old);
	assert_d_eq(mallctl(name, &old, &sz, &val_new, sizeof(val_new)), 0,
	    "%s():%d: Unexpected mallctl failure reading/writing %s", func,
	    line, name);
	assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func,
	    line, name);
}
Exemplo n.º 12
0
TEST_END

TEST_BEGIN(test_manpage_example) {
	unsigned nbins, i;
	size_t mib[4];
	size_t len, miblen;

	len = sizeof(nbins);
	assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &len, NULL, 0), 0,
	    "Unexpected mallctl() failure");

	miblen = 4;
	assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() failure");
	for (i = 0; i < nbins; i++) {
		size_t bin_size;

		mib[2] = i;
		len = sizeof(bin_size);
		assert_d_eq(mallctlbymib(mib, miblen, (void *)&bin_size, &len,
		    NULL, 0), 0, "Unexpected mallctlbymib() failure");
		/* Do something with bin_size... */
	}
}
Exemplo n.º 13
0
TEST_END

TEST_BEGIN(test_stats_arenas_summary)
{
	unsigned arena;
	void *little, *large, *huge;
	uint64_t epoch;
	size_t sz;
	int expected = config_stats ? 0 : ENOENT;
	size_t mapped;
	uint64_t npurge, nmadvise, purged;

	arena = 0;
	assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
	    sizeof(arena)), 0, "Unexpected mallctl() failure");

	little = mallocx(SMALL_MAXCLASS, 0);
	assert_ptr_not_null(little, "Unexpected mallocx() failure");
	large = mallocx(large_maxclass, 0);
	assert_ptr_not_null(large, "Unexpected mallocx() failure");
	huge = mallocx(chunksize, 0);
	assert_ptr_not_null(huge, "Unexpected mallocx() failure");

	dallocx(little, 0);
	dallocx(large, 0);
	dallocx(huge, 0);

	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
	    "Unexpected mallctl() failure");

	assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
	    0, "Unexpected mallctl() failure");

	sz = sizeof(size_t);
	assert_d_eq(mallctl("stats.arenas.0.mapped", (void *)&mapped, &sz, NULL,
	    0), expected, "Unexepected mallctl() result");
	sz = sizeof(uint64_t);
	assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge, &sz, NULL,
	    0), expected, "Unexepected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.nmadvise", (void *)&nmadvise, &sz,
	    NULL, 0), expected, "Unexepected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.purged", (void *)&purged, &sz, NULL,
	    0), expected, "Unexepected mallctl() result");

	if (config_stats) {
		assert_u64_gt(npurge, 0,
		    "At least one purge should have occurred");
		assert_u64_le(nmadvise, purged,
		    "nmadvise should be no greater than purged");
	}
}
Exemplo n.º 14
0
TEST_END

TEST_BEGIN(test_max_background_threads) {
	test_skip_if(!have_background_thread);

	size_t max_n_thds;
	size_t opt_max_n_thds;
	size_t sz_m = sizeof(max_n_thds);
	assert_d_eq(mallctl("opt.max_background_threads",
	    &opt_max_n_thds, &sz_m, NULL, 0), 0,
	    "Failed to get opt.max_background_threads");
	assert_d_eq(mallctl("max_background_threads", &max_n_thds, &sz_m, NULL,
	    0), 0, "Failed to get max background threads");
	assert_zu_eq(opt_max_n_thds, max_n_thds,
	    "max_background_threads and "
	    "opt.max_background_threads should match");
	assert_d_eq(mallctl("max_background_threads", NULL, NULL, &max_n_thds,
	    sz_m), 0, "Failed to set max background threads");

	unsigned id;
	size_t sz_u = sizeof(unsigned);

	for (unsigned i = 0; i < 10 * ncpus; i++) {
		assert_d_eq(mallctl("arenas.create", &id, &sz_u, NULL, 0), 0,
		    "Failed to create arena");
	}

	bool enable = true;
	size_t sz_b = sizeof(bool);
	assert_d_eq(mallctl("background_thread", NULL, NULL, &enable, sz_b), 0,
	    "Failed to enable background threads");
	assert_zu_eq(n_background_threads, max_n_thds,
	    "Number of background threads should not change.\n");
	size_t new_max_thds = max_n_thds - 1;
	if (new_max_thds > 0) {
		assert_d_eq(mallctl("max_background_threads", NULL, NULL,
		    &new_max_thds, sz_m), 0,
		    "Failed to set max background threads");
		assert_zu_eq(n_background_threads, new_max_thds,
		    "Number of background threads should decrease by 1.\n");
	}
	new_max_thds = 1;
	assert_d_eq(mallctl("max_background_threads", NULL, NULL, &new_max_thds,
	    sz_m), 0, "Failed to set max background threads");
	assert_zu_eq(n_background_threads, new_max_thds,
	    "Number of background threads should be 1.\n");
}
Exemplo n.º 15
0
TEST_END

TEST_BEGIN(test_arena_i_dss) {
	const char *dss_prec_old, *dss_prec_new;
	size_t sz = sizeof(dss_prec_old);
	size_t mib[3];
	size_t miblen;

	miblen = sizeof(mib)/sizeof(size_t);
	assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() error");

	dss_prec_new = "disabled";
	assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz,
	    (void *)&dss_prec_new, sizeof(dss_prec_new)), 0,
	    "Unexpected mallctl() failure");
	assert_str_ne(dss_prec_old, "primary",
	    "Unexpected default for dss precedence");

	assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_new, &sz,
	    (void *)&dss_prec_old, sizeof(dss_prec_old)), 0,
	    "Unexpected mallctl() failure");

	assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, NULL,
	    0), 0, "Unexpected mallctl() failure");
	assert_str_ne(dss_prec_old, "primary",
	    "Unexpected value for dss precedence");

	mib[1] = narenas_total_get();
	dss_prec_new = "disabled";
	assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz,
	    (void *)&dss_prec_new, sizeof(dss_prec_new)), 0,
	    "Unexpected mallctl() failure");
	assert_str_ne(dss_prec_old, "primary",
	    "Unexpected default for dss precedence");

	assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_new, &sz,
	    (void *)&dss_prec_old, sizeof(dss_prec_new)), 0,
	    "Unexpected mallctl() failure");

	assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, NULL,
	    0), 0, "Unexpected mallctl() failure");
	assert_str_ne(dss_prec_old, "primary",
	    "Unexpected value for dss precedence");
}
Exemplo n.º 16
0
TEST_END

TEST_BEGIN(test_hooks_realloc_as_malloc_or_free) {
	hooks_t hooks = {&test_alloc_hook, &test_dalloc_hook,
		&test_expand_hook, (void *)123};
	void *handle = hook_install(TSDN_NULL, &hooks);
	assert_ptr_ne(handle, NULL, "Hook installation failed");

	void *volatile ptr;

	/* realloc(NULL, size) as malloc */
	reset();
	ptr = realloc(NULL, 1);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_realloc, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)NULL, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong argument");
	free(ptr);

	/* realloc(ptr, 0) as free */
	ptr = malloc(1);
	reset();
	realloc(ptr, 0);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_dalloc_realloc, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong pointer freed");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");
	assert_u64_eq((uintptr_t)0, arg_args_raw[1], "Wrong raw arg");

	/* realloc(NULL, 0) as malloc(0) */
	reset();
	ptr = realloc(NULL, 0);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_realloc, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)NULL, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)0, arg_args_raw[1], "Wrong argument");
	free(ptr);

	hook_remove(TSDN_NULL, handle);
}
Exemplo n.º 17
0
TEST_END

TEST_BEGIN(test_hooks_dalloc_simple) {
	/* "Simple" in the sense that we're not in a realloc variant. */
	hooks_t hooks = {NULL, &test_dalloc_hook, NULL, (void *)123};
	void *handle = hook_install(TSDN_NULL, &hooks);
	assert_ptr_ne(handle, NULL, "Hook installation failed");

	void *volatile ptr;

	/* free() */
	reset();
	ptr = malloc(1);
	free(ptr);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_dalloc_free, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong pointer freed");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");

	/* dallocx() */
	reset();
	ptr = malloc(1);
	dallocx(ptr, MALLOCX_TCACHE_NONE);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_dalloc_dallocx, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong pointer freed");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");
	assert_u64_eq((uintptr_t)MALLOCX_TCACHE_NONE, arg_args_raw[1],
	    "Wrong raw arg");

	/* sdallocx() */
	reset();
	ptr = malloc(1);
	sdallocx(ptr, 1, MALLOCX_TCACHE_NONE);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_dalloc_sdallocx, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong pointer freed");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");
	assert_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong raw arg");
	assert_u64_eq((uintptr_t)MALLOCX_TCACHE_NONE, arg_args_raw[2],
	    "Wrong raw arg");

	hook_remove(TSDN_NULL, handle);
}
Exemplo n.º 18
0
TEST_END

TEST_BEGIN(test_stats_arenas_lruns)
{
	unsigned arena;
	void *p;
	uint64_t epoch, nmalloc, ndalloc, nrequests;
	size_t curruns, sz;
	int expected = config_stats ? 0 : ENOENT;

	arena = 0;
	assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
	    sizeof(arena)), 0, "Unexpected mallctl() failure");

	p = mallocx(LARGE_MINCLASS, 0);
	assert_ptr_not_null(p, "Unexpected mallocx() failure");

	assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
	    0, "Unexpected mallctl() failure");

	sz = sizeof(uint64_t);
	assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", (void *)&nmalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", (void *)&ndalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests",
	    (void *)&nrequests, &sz, NULL, 0), expected,
	    "Unexpected mallctl() result");
	sz = sizeof(size_t);
	assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", (void *)&curruns,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");

	if (config_stats) {
		assert_u64_gt(nmalloc, 0,
		    "nmalloc should be greater than zero");
		assert_u64_ge(nmalloc, ndalloc,
		    "nmalloc should be at least as large as ndalloc");
		assert_u64_gt(nrequests, 0,
		    "nrequests should be greater than zero");
		assert_u64_gt(curruns, 0,
		    "At least one run should be currently allocated");
	}

	dallocx(p, 0);
}
Exemplo n.º 19
0
TEST_END

TEST_BEGIN(test_mallctlbymib_errors) {
	uint64_t epoch;
	size_t sz;
	size_t mib[1];
	size_t miblen;

	miblen = sizeof(mib)/sizeof(size_t);
	assert_d_eq(mallctlnametomib("version", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() failure");

	assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, "0.0.0",
	    strlen("0.0.0")), EPERM, "mallctl() should return EPERM on "
	    "attempt to write read-only value");

	miblen = sizeof(mib)/sizeof(size_t);
	assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0,
	    "Unexpected mallctlnametomib() failure");

	assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch,
	    sizeof(epoch)-1), EINVAL,
	    "mallctlbymib() should return EINVAL for input size mismatch");
	assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch,
	    sizeof(epoch)+1), EINVAL,
	    "mallctlbymib() should return EINVAL for input size mismatch");

	sz = sizeof(epoch)-1;
	assert_d_eq(mallctlbymib(mib, miblen, (void *)&epoch, &sz, NULL, 0),
	    EINVAL,
	    "mallctlbymib() should return EINVAL for output size mismatch");
	sz = sizeof(epoch)+1;
	assert_d_eq(mallctlbymib(mib, miblen, (void *)&epoch, &sz, NULL, 0),
	    EINVAL,
	    "mallctlbymib() should return EINVAL for output size mismatch");
}
Exemplo n.º 20
0
TEST_END

TEST_BEGIN(test_thread_arena) {
	unsigned old_arena_ind, new_arena_ind, narenas;

	const char *opa;
	size_t sz = sizeof(opa);
	assert_d_eq(mallctl("opt.percpu_arena", &opa, &sz, NULL, 0), 0,
	    "Unexpected mallctl() failure");

	sz = sizeof(unsigned);
	assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
	    0, "Unexpected mallctl() failure");
	assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect");

	if (strcmp(opa, "disabled") == 0) {
		new_arena_ind = narenas - 1;
		assert_d_eq(mallctl("thread.arena", (void *)&old_arena_ind, &sz,
		    (void *)&new_arena_ind, sizeof(unsigned)), 0,
		    "Unexpected mallctl() failure");
		new_arena_ind = 0;
		assert_d_eq(mallctl("thread.arena", (void *)&old_arena_ind, &sz,
		    (void *)&new_arena_ind, sizeof(unsigned)), 0,
		    "Unexpected mallctl() failure");
	} else {
		assert_d_eq(mallctl("thread.arena", (void *)&old_arena_ind, &sz,
		    NULL, 0), 0, "Unexpected mallctl() failure");
		new_arena_ind = percpu_arena_ind_limit(opt_percpu_arena) - 1;
		if (old_arena_ind != new_arena_ind) {
			assert_d_eq(mallctl("thread.arena",
			    (void *)&old_arena_ind, &sz, (void *)&new_arena_ind,
			    sizeof(unsigned)), EPERM, "thread.arena ctl "
			    "should not be allowed with percpu arena");
		}
	}
}
Exemplo n.º 21
0
void *
thd_start(void *arg)
{
	int err;
	size_t sz;
	bool e0, e1;

	sz = sizeof(bool);
	if ((err = mallctl("thread.tcache.enabled", &e0, &sz, NULL, 0))) {
		if (err == ENOENT) {
			assert_false(config_tcache,
			    "ENOENT should only be returned if tcache is "
			    "disabled");
		}
		goto label_ENOENT;
	}

	if (e0) {
		e1 = false;
		assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz),
		    0, "Unexpected mallctl() error");
		assert_true(e0, "tcache should be enabled");
	}

	e1 = true;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_false(e0, "tcache should be disabled");

	e1 = true;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_true(e0, "tcache should be enabled");

	e1 = false;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_true(e0, "tcache should be enabled");

	e1 = false;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_false(e0, "tcache should be disabled");

	free(malloc(1));
	e1 = true;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_false(e0, "tcache should be disabled");

	free(malloc(1));
	e1 = true;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_true(e0, "tcache should be enabled");

	free(malloc(1));
	e1 = false;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_true(e0, "tcache should be enabled");

	free(malloc(1));
	e1 = false;
	assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
	    "Unexpected mallctl() error");
	assert_false(e0, "tcache should be disabled");

	free(malloc(1));
	return (NULL);
label_ENOENT:
	test_skip("\"thread.tcache.enabled\" mallctl not available");
	return (NULL);
}
Exemplo n.º 22
0
TEST_END

TEST_BEGIN(test_tcache) {
#define NTCACHES	10
	unsigned tis[NTCACHES];
	void *ps[NTCACHES];
	void *qs[NTCACHES];
	unsigned i;
	size_t sz, psz, qsz;

	psz = 42;
	qsz = nallocx(psz, 0) + 1;

	/* Create tcaches. */
	for (i = 0; i < NTCACHES; i++) {
		sz = sizeof(unsigned);
		assert_d_eq(mallctl("tcache.create", (void *)&tis[i], &sz, NULL,
		    0), 0, "Unexpected mallctl() failure, i=%u", i);
	}

	/* Exercise tcache ID recycling. */
	for (i = 0; i < NTCACHES; i++) {
		assert_d_eq(mallctl("tcache.destroy", NULL, NULL,
		    (void *)&tis[i], sizeof(unsigned)), 0,
		    "Unexpected mallctl() failure, i=%u", i);
	}
	for (i = 0; i < NTCACHES; i++) {
		sz = sizeof(unsigned);
		assert_d_eq(mallctl("tcache.create", (void *)&tis[i], &sz, NULL,
		    0), 0, "Unexpected mallctl() failure, i=%u", i);
	}

	/* Flush empty tcaches. */
	for (i = 0; i < NTCACHES; i++) {
		assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&tis[i],
		    sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
		    i);
	}

	/* Cache some allocations. */
	for (i = 0; i < NTCACHES; i++) {
		ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));
		assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u",
		    i);
		dallocx(ps[i], MALLOCX_TCACHE(tis[i]));

		qs[i] = mallocx(qsz, MALLOCX_TCACHE(tis[i]));
		assert_ptr_not_null(qs[i], "Unexpected mallocx() failure, i=%u",
		    i);
		dallocx(qs[i], MALLOCX_TCACHE(tis[i]));
	}

	/* Verify that tcaches allocate cached regions. */
	for (i = 0; i < NTCACHES; i++) {
		void *p0 = ps[i];
		ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));
		assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u",
		    i);
		assert_ptr_eq(ps[i], p0,
		    "Expected mallocx() to allocate cached region, i=%u", i);
	}

	/* Verify that reallocation uses cached regions. */
	for (i = 0; i < NTCACHES; i++) {
		void *q0 = qs[i];
		qs[i] = rallocx(ps[i], qsz, MALLOCX_TCACHE(tis[i]));
		assert_ptr_not_null(qs[i], "Unexpected rallocx() failure, i=%u",
		    i);
		assert_ptr_eq(qs[i], q0,
		    "Expected rallocx() to allocate cached region, i=%u", i);
		/* Avoid undefined behavior in case of test failure. */
		if (qs[i] == NULL) {
			qs[i] = ps[i];
		}
	}
	for (i = 0; i < NTCACHES; i++) {
		dallocx(qs[i], MALLOCX_TCACHE(tis[i]));
	}

	/* Flush some non-empty tcaches. */
	for (i = 0; i < NTCACHES/2; i++) {
		assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&tis[i],
		    sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
		    i);
	}

	/* Destroy tcaches. */
	for (i = 0; i < NTCACHES; i++) {
		assert_d_eq(mallctl("tcache.destroy", NULL, NULL,
		    (void *)&tis[i], sizeof(unsigned)), 0,
		    "Unexpected mallctl() failure, i=%u", i);
	}
}
Exemplo n.º 23
0
TEST_END

TEST_BEGIN(test_stats_arenas_bins)
{
	unsigned arena;
	void *p;
	size_t sz, curruns, curregs;
	uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;
	uint64_t nruns, nreruns;
	int expected = config_stats ? 0 : ENOENT;

	arena = 0;
	assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
	    sizeof(arena)), 0, "Unexpected mallctl() failure");

	p = mallocx(arena_bin_info[0].reg_size, 0);
	assert_ptr_not_null(p, "Unexpected mallocx() failure");

	assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
	    config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");

	assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
	    0, "Unexpected mallctl() failure");

	sz = sizeof(uint64_t);
	assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", (void *)&nmalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", (void *)&ndalloc,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests",
	    (void *)&nrequests, &sz, NULL, 0), expected,
	    "Unexpected mallctl() result");
	sz = sizeof(size_t);
	assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", (void *)&curregs,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");

	sz = sizeof(uint64_t);
	assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", (void *)&nfills,
	    &sz, NULL, 0), config_tcache ? expected : ENOENT,
	    "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", (void *)&nflushes,
	    &sz, NULL, 0), config_tcache ? expected : ENOENT,
	    "Unexpected mallctl() result");

	assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", (void *)&nruns, &sz,
	    NULL, 0), expected, "Unexpected mallctl() result");
	assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", (void *)&nreruns,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
	sz = sizeof(size_t);
	assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", (void *)&curruns,
	    &sz, NULL, 0), expected, "Unexpected mallctl() result");

	if (config_stats) {
		assert_u64_gt(nmalloc, 0,
		    "nmalloc should be greater than zero");
		assert_u64_ge(nmalloc, ndalloc,
		    "nmalloc should be at least as large as ndalloc");
		assert_u64_gt(nrequests, 0,
		    "nrequests should be greater than zero");
		assert_zu_gt(curregs, 0,
		    "allocated should be greater than zero");
		if (config_tcache) {
			assert_u64_gt(nfills, 0,
			    "At least one fill should have occurred");
			assert_u64_gt(nflushes, 0,
			    "At least one flush should have occurred");
		}
		assert_u64_gt(nruns, 0,
		    "At least one run should have been allocated");
		assert_zu_gt(curruns, 0,
		    "At least one run should be currently allocated");
	}

	dallocx(p, 0);
}
Exemplo n.º 24
0
TEST_END

TEST_BEGIN(test_malloc_strtoumax)
{
	struct test_s {
		const char *input;
		const char *expected_remainder;
		int base;
		int expected_errno;
		const char *expected_errno_name;
		uintmax_t expected_x;
	};
#define	ERR(e)	e, #e
#define	UMAX(x)	((uintmax_t)x##ULL)
	struct test_s tests[] = {
		{"0",		"0",	-1,	ERR(EINVAL),	UINTMAX_MAX},
		{"0",		"0",	1,	ERR(EINVAL),	UINTMAX_MAX},
		{"0",		"0",	37,	ERR(EINVAL),	UINTMAX_MAX},

		{"",		"",	0,	ERR(EINVAL),	UINTMAX_MAX},
		{"+",		"+",	0,	ERR(EINVAL),	UINTMAX_MAX},
		{"++3",		"++3",	0,	ERR(EINVAL),	UINTMAX_MAX},
		{"-",		"-",	0,	ERR(EINVAL),	UINTMAX_MAX},

		{"42",		"",	0,	ERR(0),		UMAX(42)},
		{"+42",		"",	0,	ERR(0),		UMAX(42)},
		{"-42",		"",	0,	ERR(0),		UMAX(-42)},
		{"042",		"",	0,	ERR(0),		UMAX(042)},
		{"+042",	"",	0,	ERR(0),		UMAX(042)},
		{"-042",	"",	0,	ERR(0),		UMAX(-042)},
		{"0x42",	"",	0,	ERR(0),		UMAX(0x42)},
		{"+0x42",	"",	0,	ERR(0),		UMAX(0x42)},
		{"-0x42",	"",	0,	ERR(0),		UMAX(-0x42)},

		{"0",		"",	0,	ERR(0),		UMAX(0)},
		{"1",		"",	0,	ERR(0),		UMAX(1)},

		{"42",		"",	0,	ERR(0),		UMAX(42)},
		{" 42",		"",	0,	ERR(0),		UMAX(42)},
		{"42 ",		" ",	0,	ERR(0),		UMAX(42)},
		{"0x",		"x",	0,	ERR(0),		UMAX(0)},
		{"42x",		"x",	0,	ERR(0),		UMAX(42)},

		{"07",		"",	0,	ERR(0),		UMAX(7)},
		{"010",		"",	0,	ERR(0),		UMAX(8)},
		{"08",		"8",	0,	ERR(0),		UMAX(0)},
		{"0_",		"_",	0,	ERR(0),		UMAX(0)},

		{"0x",		"x",	0,	ERR(0),		UMAX(0)},
		{"0X",		"X",	0,	ERR(0),		UMAX(0)},
		{"0xg",		"xg",	0,	ERR(0),		UMAX(0)},
		{"0XA",		"",	0,	ERR(0),		UMAX(10)},

		{"010",		"",	10,	ERR(0),		UMAX(10)},
		{"0x3",		"x3",	10,	ERR(0),		UMAX(0)},

		{"12",		"2",	2,	ERR(0),		UMAX(1)},
		{"78",		"8",	8,	ERR(0),		UMAX(7)},
		{"9a",		"a",	10,	ERR(0),		UMAX(9)},
		{"9A",		"A",	10,	ERR(0),		UMAX(9)},
		{"fg",		"g",	16,	ERR(0),		UMAX(15)},
		{"FG",		"G",	16,	ERR(0),		UMAX(15)},
		{"0xfg",	"g",	16,	ERR(0),		UMAX(15)},
		{"0XFG",	"G",	16,	ERR(0),		UMAX(15)},
		{"z_",		"_",	36,	ERR(0),		UMAX(35)},
		{"Z_",		"_",	36,	ERR(0),		UMAX(35)}
	};
#undef ERR
#undef UMAX
	unsigned i;

	for (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) {
		struct test_s *test = &tests[i];
		int err;
		uintmax_t result;
		char *remainder;

		set_errno(0);
		result = malloc_strtoumax(test->input, &remainder, test->base);
		err = get_errno();
		assert_d_eq(err, test->expected_errno,
		    "Expected errno %s for \"%s\", base %d",
		    test->expected_errno_name, test->input, test->base);
		assert_str_eq(remainder, test->expected_remainder,
		    "Unexpected remainder for \"%s\", base %d",
		    test->input, test->base);
		if (err == 0) {
			assert_ju_eq(result, test->expected_x,
			    "Unexpected result for \"%s\", base %d",
			    test->input, test->base);
		}
	}
}
Exemplo n.º 25
0
static void
assert_args_raw(uintptr_t *args_raw_expected, int nargs) {
	int cmp = memcmp(args_raw_expected, arg_args_raw,
	    sizeof(uintptr_t) * nargs);
	assert_d_eq(cmp, 0, "Raw args mismatch");
}
Exemplo n.º 26
0
TEST_END

static void
do_realloc_test(void *(*ralloc)(void *, size_t, int), int flags,
    int expand_type, int dalloc_type) {
	hooks_t hooks = {&test_alloc_hook, &test_dalloc_hook,
		&test_expand_hook, (void *)123};
	void *handle = hook_install(TSDN_NULL, &hooks);
	assert_ptr_ne(handle, NULL, "Hook installation failed");

	void *volatile ptr;
	void *volatile ptr2;

	/* Realloc in-place, small. */
	ptr = malloc(129);
	reset();
	ptr2 = ralloc(ptr, 130, flags);
	assert_ptr_eq(ptr, ptr2, "Small realloc moved");

	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, expand_type, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong address");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)130, arg_args_raw[1], "Wrong argument");
	free(ptr);

	/*
	 * Realloc in-place, large.  Since we can't guarantee the large case
	 * across all platforms, we stay resilient to moving results.
	 */
	ptr = malloc(2 * 1024 * 1024);
	free(ptr);
	ptr2 = malloc(1 * 1024 * 1024);
	reset();
	ptr = ralloc(ptr2, 2 * 1024 * 1024, flags);
	/* ptr is the new address, ptr2 is the old address. */
	if (ptr == ptr2) {
		assert_d_eq(call_count, 1, "Hook not called");
		assert_d_eq(arg_type, expand_type, "Wrong hook type");
	} else {
		assert_d_eq(call_count, 2, "Wrong hooks called");
		assert_ptr_eq(ptr, arg_result, "Wrong address");
		assert_d_eq(arg_type, dalloc_type, "Wrong hook type");
	}
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_ptr_eq(ptr2, arg_address, "Wrong address");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)ptr2, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)2 * 1024 * 1024, arg_args_raw[1],
	    "Wrong argument");
	free(ptr);

	/* Realloc with move, small. */
	ptr = malloc(8);
	reset();
	ptr2 = ralloc(ptr, 128, flags);
	assert_ptr_ne(ptr, ptr2, "Small realloc didn't move");

	assert_d_eq(call_count, 2, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, dalloc_type, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong address");
	assert_ptr_eq(ptr2, arg_result, "Wrong address");
	assert_u64_eq((uintptr_t)ptr2, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)128, arg_args_raw[1], "Wrong argument");
	free(ptr2);

	/* Realloc with move, large. */
	ptr = malloc(1);
	reset();
	ptr2 = ralloc(ptr, 2 * 1024 * 1024, flags);
	assert_ptr_ne(ptr, ptr2, "Large realloc didn't move");

	assert_d_eq(call_count, 2, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, dalloc_type, "Wrong hook type");
	assert_ptr_eq(ptr, arg_address, "Wrong address");
	assert_ptr_eq(ptr2, arg_result, "Wrong address");
	assert_u64_eq((uintptr_t)ptr2, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)2 * 1024 * 1024, arg_args_raw[1],
	    "Wrong argument");
	free(ptr2);

	hook_remove(TSDN_NULL, handle);
}
Exemplo n.º 27
0
TEST_END

TEST_BEGIN(test_hooks_alloc_simple) {
	/* "Simple" in the sense that we're not in a realloc variant. */
	hooks_t hooks = {&test_alloc_hook, NULL, NULL, (void *)123};
	void *handle = hook_install(TSDN_NULL, &hooks);
	assert_ptr_ne(handle, NULL, "Hook installation failed");

	/* Stop malloc from being optimized away. */
	volatile int err;
	void *volatile ptr;

	/* malloc */
	reset();
	ptr = malloc(1);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_malloc, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
	free(ptr);

	/* posix_memalign */
	reset();
	err = posix_memalign((void **)&ptr, 1024, 1);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_posix_memalign,
	    "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)err, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)&ptr, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)1024, arg_args_raw[1], "Wrong argument");
	assert_u64_eq((uintptr_t)1, arg_args_raw[2], "Wrong argument");
	free(ptr);

	/* aligned_alloc */
	reset();
	ptr = aligned_alloc(1024, 1);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_aligned_alloc,
	    "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)1024, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong argument");
	free(ptr);

	/* calloc */
	reset();
	ptr = calloc(11, 13);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_calloc, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)11, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)13, arg_args_raw[1], "Wrong argument");
	free(ptr);

	/* memalign */
#ifdef JEMALLOC_OVERRIDE_MEMALIGN
	reset();
	ptr = memalign(1024, 1);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_memalign, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)1024, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong argument");
	free(ptr);
#endif /* JEMALLOC_OVERRIDE_MEMALIGN */

	/* valloc */
#ifdef JEMALLOC_OVERRIDE_VALLOC
	reset();
	ptr = valloc(1);
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_valloc, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
	free(ptr);
#endif /* JEMALLOC_OVERRIDE_VALLOC */

	/* mallocx */
	reset();
	ptr = mallocx(1, MALLOCX_LG_ALIGN(10));
	assert_d_eq(call_count, 1, "Hook not called");
	assert_ptr_eq(arg_extra, (void *)123, "Wrong extra");
	assert_d_eq(arg_type, (int)hook_alloc_mallocx, "Wrong hook type");
	assert_ptr_eq(ptr, arg_result, "Wrong result");
	assert_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
	    "Wrong raw result");
	assert_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
	assert_u64_eq((uintptr_t)MALLOCX_LG_ALIGN(10), arg_args_raw[1],
	    "Wrong flags");
	free(ptr);

	hook_remove(TSDN_NULL, handle);
}