Reformat the codebase with the clang-format 18.

This commit is contained in:
guangli-dai 2025-06-13 12:31:12 -07:00 committed by Guangli Dai
parent 0a6215c171
commit f1bba4a87c
346 changed files with 18286 additions and 17770 deletions

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,5 @@ TEST_END
int
main(void) {
return test_no_malloc_init(
test_a0);
return test_no_malloc_init(test_a0);
}

View file

@ -4,11 +4,11 @@
#include "jemalloc/internal/ticker.h"
static nstime_monotonic_t *nstime_monotonic_orig;
static nstime_update_t *nstime_update_orig;
static nstime_update_t *nstime_update_orig;
static unsigned nupdates_mock;
static nstime_t time_mock;
static bool monotonic_mock;
static bool monotonic_mock;
static bool
nstime_monotonic_mock(void) {
@ -28,26 +28,27 @@ TEST_BEGIN(test_decay_ticks) {
test_skip_if(opt_hpa);
ticker_geom_t *decay_ticker;
unsigned tick0, tick1, arena_ind;
size_t sz, large0;
void *p;
unsigned tick0, tick1, arena_ind;
size_t sz, large0;
void *p;
sz = sizeof(size_t);
expect_d_eq(mallctl("arenas.lextent.0.size", (void *)&large0, &sz, NULL,
0), 0, "Unexpected mallctl failure");
expect_d_eq(
mallctl("arenas.lextent.0.size", (void *)&large0, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
/* Set up a manually managed arena for test. */
arena_ind = do_arena_create(0, 0);
/* Migrate to the new arena, and get the ticker. */
unsigned old_arena_ind;
size_t sz_arena_ind = sizeof(old_arena_ind);
size_t sz_arena_ind = sizeof(old_arena_ind);
expect_d_eq(mallctl("thread.arena", (void *)&old_arena_ind,
&sz_arena_ind, (void *)&arena_ind, sizeof(arena_ind)), 0,
"Unexpected mallctl() failure");
&sz_arena_ind, (void *)&arena_ind, sizeof(arena_ind)),
0, "Unexpected mallctl() failure");
decay_ticker = tsd_arena_decay_tickerp_get(tsd_fetch());
expect_ptr_not_null(decay_ticker,
"Unexpected failure getting decay ticker");
expect_ptr_not_null(
decay_ticker, "Unexpected failure getting decay ticker");
/*
* Test the standard APIs using a large size class, since we can't
@ -80,8 +81,8 @@ TEST_BEGIN(test_decay_ticks) {
expect_d_eq(posix_memalign(&p, sizeof(size_t), large0), 0,
"Unexpected posix_memalign() failure");
tick1 = ticker_geom_read(decay_ticker);
expect_u32_ne(tick1, tick0,
"Expected ticker to tick during posix_memalign()");
expect_u32_ne(
tick1, tick0, "Expected ticker to tick during posix_memalign()");
free(p);
/* aligned_alloc(). */
@ -89,8 +90,8 @@ TEST_BEGIN(test_decay_ticks) {
p = aligned_alloc(sizeof(size_t), large0);
expect_ptr_not_null(p, "Unexpected aligned_alloc() failure");
tick1 = ticker_geom_read(decay_ticker);
expect_u32_ne(tick1, tick0,
"Expected ticker to tick during aligned_alloc()");
expect_u32_ne(
tick1, tick0, "Expected ticker to tick during aligned_alloc()");
free(p);
/* realloc(). */
@ -118,7 +119,7 @@ TEST_BEGIN(test_decay_ticks) {
*/
{
unsigned i;
size_t allocx_sizes[2];
size_t allocx_sizes[2];
allocx_sizes[0] = large0;
allocx_sizes[1] = 1;
@ -163,7 +164,8 @@ TEST_BEGIN(test_decay_ticks) {
tick1 = ticker_geom_read(decay_ticker);
expect_u32_ne(tick1, tick0,
"Expected ticker to tick during sdallocx() "
"(sz=%zu)", sz);
"(sz=%zu)",
sz);
}
}
@ -172,18 +174,19 @@ TEST_BEGIN(test_decay_ticks) {
* using an explicit tcache.
*/
unsigned tcache_ind, i;
size_t tcache_sizes[2];
size_t tcache_sizes[2];
tcache_sizes[0] = large0;
tcache_sizes[1] = 1;
size_t tcache_max, sz_tcache_max;
sz_tcache_max = sizeof(tcache_max);
expect_d_eq(mallctl("arenas.tcache_max", (void *)&tcache_max,
&sz_tcache_max, NULL, 0), 0, "Unexpected mallctl() failure");
&sz_tcache_max, NULL, 0),
0, "Unexpected mallctl() failure");
sz = sizeof(unsigned);
expect_d_eq(mallctl("tcache.create", (void *)&tcache_ind, &sz,
NULL, 0), 0, "Unexpected mallctl failure");
expect_d_eq(mallctl("tcache.create", (void *)&tcache_ind, &sz, NULL, 0),
0, "Unexpected mallctl failure");
for (i = 0; i < sizeof(tcache_sizes) / sizeof(size_t); i++) {
sz = tcache_sizes[i];
@ -195,13 +198,14 @@ TEST_BEGIN(test_decay_ticks) {
tick1 = ticker_geom_read(decay_ticker);
expect_u32_ne(tick1, tick0,
"Expected ticker to tick during tcache fill "
"(sz=%zu)", sz);
"(sz=%zu)",
sz);
/* tcache flush. */
dallocx(p, MALLOCX_TCACHE(tcache_ind));
tick0 = ticker_geom_read(decay_ticker);
expect_d_eq(mallctl("tcache.flush", NULL, NULL,
(void *)&tcache_ind, sizeof(unsigned)), 0,
"Unexpected mallctl failure");
(void *)&tcache_ind, sizeof(unsigned)),
0, "Unexpected mallctl failure");
tick1 = ticker_geom_read(decay_ticker);
/* Will only tick if it's in tcache. */
@ -231,11 +235,11 @@ decay_ticker_helper(unsigned arena_ind, int flags, bool dirty, ssize_t dt,
* cached slab were to repeatedly come and go during looping, it could
* prevent the decay backlog ever becoming empty.
*/
void *p = do_mallocx(1, flags);
void *p = do_mallocx(1, flags);
uint64_t dirty_npurge1, muzzy_npurge1;
do {
for (unsigned i = 0; i < ARENA_DECAY_NTICKS_PER_UPDATE / 2;
i++) {
i++) {
void *q = do_mallocx(1, flags);
dallocx(q, flags);
}
@ -244,14 +248,15 @@ decay_ticker_helper(unsigned arena_ind, int flags, bool dirty, ssize_t dt,
nstime_add(&time_mock, &update_interval);
nstime_update(&time);
} while (nstime_compare(&time, &deadline) <= 0 && ((dirty_npurge1 ==
dirty_npurge0 && muzzy_npurge1 == muzzy_npurge0) ||
!terminate_asap));
} while (nstime_compare(&time, &deadline) <= 0
&& ((dirty_npurge1 == dirty_npurge0
&& muzzy_npurge1 == muzzy_npurge0)
|| !terminate_asap));
dallocx(p, flags);
if (config_stats) {
expect_u64_gt(dirty_npurge1 + muzzy_npurge1, dirty_npurge0 +
muzzy_npurge0, "Expected purging to occur");
expect_u64_gt(dirty_npurge1 + muzzy_npurge1,
dirty_npurge0 + muzzy_npurge0, "Expected purging to occur");
}
#undef NINTERVALS
}
@ -260,11 +265,11 @@ TEST_BEGIN(test_decay_ticker) {
test_skip_if(is_background_thread_enabled());
test_skip_if(opt_hpa);
#define NPS 2048
ssize_t ddt = opt_dirty_decay_ms;
ssize_t mdt = opt_muzzy_decay_ms;
ssize_t ddt = opt_dirty_decay_ms;
ssize_t mdt = opt_muzzy_decay_ms;
unsigned arena_ind = do_arena_create(ddt, mdt);
int flags = (MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE);
void *ps[NPS];
int flags = (MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE);
void *ps[NPS];
/*
* Allocate a bunch of large objects, pause the clock, deallocate every
@ -274,8 +279,9 @@ TEST_BEGIN(test_decay_ticker) {
*/
size_t large;
size_t sz = sizeof(size_t);
expect_d_eq(mallctl("arenas.lextent.0.size", (void *)&large, &sz, NULL,
0), 0, "Unexpected mallctl failure");
expect_d_eq(
mallctl("arenas.lextent.0.size", (void *)&large, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
do_purge(arena_ind);
uint64_t dirty_npurge0 = get_arena_dirty_npurge(arena_ind);
@ -302,9 +308,9 @@ TEST_BEGIN(test_decay_ticker) {
"Expected nstime_update() to be called");
}
decay_ticker_helper(arena_ind, flags, true, ddt, dirty_npurge0,
muzzy_npurge0, true);
decay_ticker_helper(arena_ind, flags, false, ddt+mdt, dirty_npurge0,
decay_ticker_helper(
arena_ind, flags, true, ddt, dirty_npurge0, muzzy_npurge0, true);
decay_ticker_helper(arena_ind, flags, false, ddt + mdt, dirty_npurge0,
muzzy_npurge0, false);
do_arena_destroy(arena_ind);
@ -319,16 +325,17 @@ TEST_BEGIN(test_decay_nonmonotonic) {
test_skip_if(is_background_thread_enabled());
test_skip_if(opt_hpa);
#define NPS (SMOOTHSTEP_NSTEPS + 1)
int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
void *ps[NPS];
int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
void *ps[NPS];
uint64_t npurge0 = 0;
uint64_t npurge1 = 0;
size_t sz, large0;
size_t sz, large0;
unsigned i, nupdates0;
sz = sizeof(size_t);
expect_d_eq(mallctl("arenas.lextent.0.size", (void *)&large0, &sz, NULL,
0), 0, "Unexpected mallctl failure");
expect_d_eq(
mallctl("arenas.lextent.0.size", (void *)&large0, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
expect_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl failure");
@ -380,15 +387,15 @@ TEST_BEGIN(test_decay_now) {
unsigned arena_ind = do_arena_create(0, 0);
expect_zu_eq(get_arena_pdirty(arena_ind), 0, "Unexpected dirty pages");
expect_zu_eq(get_arena_pmuzzy(arena_ind), 0, "Unexpected muzzy pages");
size_t sizes[] = {16, PAGE<<2, HUGEPAGE<<2};
size_t sizes[] = {16, PAGE << 2, HUGEPAGE << 2};
/* Verify that dirty/muzzy pages never linger after deallocation. */
for (unsigned i = 0; i < sizeof(sizes)/sizeof(size_t); i++) {
for (unsigned i = 0; i < sizeof(sizes) / sizeof(size_t); i++) {
size_t size = sizes[i];
generate_dirty(arena_ind, size);
expect_zu_eq(get_arena_pdirty(arena_ind), 0,
"Unexpected dirty pages");
expect_zu_eq(get_arena_pmuzzy(arena_ind), 0,
"Unexpected muzzy pages");
expect_zu_eq(
get_arena_pdirty(arena_ind), 0, "Unexpected dirty pages");
expect_zu_eq(
get_arena_pmuzzy(arena_ind), 0, "Unexpected muzzy pages");
}
do_arena_destroy(arena_ind);
}
@ -399,12 +406,12 @@ TEST_BEGIN(test_decay_never) {
test_skip_if(opt_hpa);
unsigned arena_ind = do_arena_create(-1, -1);
int flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
int flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
expect_zu_eq(get_arena_pdirty(arena_ind), 0, "Unexpected dirty pages");
expect_zu_eq(get_arena_pmuzzy(arena_ind), 0, "Unexpected muzzy pages");
size_t sizes[] = {16, PAGE<<2, HUGEPAGE<<2};
void *ptrs[sizeof(sizes)/sizeof(size_t)];
for (unsigned i = 0; i < sizeof(sizes)/sizeof(size_t); i++) {
size_t sizes[] = {16, PAGE << 2, HUGEPAGE << 2};
void *ptrs[sizeof(sizes) / sizeof(size_t)];
for (unsigned i = 0; i < sizeof(sizes) / sizeof(size_t); i++) {
ptrs[i] = do_mallocx(sizes[i], flags);
}
/* Verify that each deallocation generates additional dirty pages. */
@ -419,7 +426,7 @@ TEST_BEGIN(test_decay_never) {
expect_zu_eq(pdirty_prev, 0, "Unexpected dirty pages");
}
expect_zu_eq(pmuzzy_prev, 0, "Unexpected muzzy pages");
for (unsigned i = 0; i < sizeof(sizes)/sizeof(size_t); i++) {
for (unsigned i = 0; i < sizeof(sizes) / sizeof(size_t); i++) {
dallocx(ptrs[i], flags);
size_t pdirty = get_arena_pdirty(arena_ind);
size_t pmuzzy = get_arena_pmuzzy(arena_ind);
@ -434,10 +441,6 @@ TEST_END
int
main(void) {
return test(
test_decay_ticks,
test_decay_ticker,
test_decay_nonmonotonic,
test_decay_now,
test_decay_never);
return test(test_decay_ticks, test_decay_ticker,
test_decay_nonmonotonic, test_decay_now, test_decay_never);
}

View file

@ -1,5 +1,5 @@
#ifndef ARENA_RESET_PROF_C_
#include "test/jemalloc_test.h"
# include "test/jemalloc_test.h"
#endif
#include "jemalloc/internal/extent_mmap.h"
@ -10,7 +10,7 @@
static unsigned
get_nsizes_impl(const char *cmd) {
unsigned ret;
size_t z;
size_t z;
z = sizeof(unsigned);
expect_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
@ -37,12 +37,12 @@ get_size_impl(const char *cmd, size_t ind) {
size_t miblen = 4;
z = sizeof(size_t);
expect_d_eq(mallctlnametomib(cmd, mib, &miblen),
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
expect_d_eq(mallctlnametomib(cmd, mib, &miblen), 0,
"Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
mib[2] = ind;
z = sizeof(size_t);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0), 0,
"Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
return ret;
}
@ -61,8 +61,8 @@ get_large_size(size_t ind) {
static size_t
vsalloc(tsdn_t *tsdn, const void *ptr) {
emap_full_alloc_ctx_t full_alloc_ctx;
bool missing = emap_full_alloc_ctx_try_lookup(tsdn, &arena_emap_global,
ptr, &full_alloc_ctx);
bool missing = emap_full_alloc_ctx_try_lookup(
tsdn, &arena_emap_global, ptr, &full_alloc_ctx);
if (missing) {
return 0;
}
@ -84,20 +84,21 @@ vsalloc(tsdn_t *tsdn, const void *ptr) {
static unsigned
do_arena_create(extent_hooks_t *h) {
unsigned arena_ind;
size_t sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz,
(void *)(h != NULL ? &h : NULL), (h != NULL ? sizeof(h) : 0)), 0,
"Unexpected mallctl() failure");
size_t sz = sizeof(unsigned);
expect_d_eq(
mallctl("arenas.create", (void *)&arena_ind, &sz,
(void *)(h != NULL ? &h : NULL), (h != NULL ? sizeof(h) : 0)),
0, "Unexpected mallctl() failure");
return arena_ind;
}
static void
do_arena_reset_pre(unsigned arena_ind, void ***ptrs, unsigned *nptrs) {
#define NLARGE 32
#define NLARGE 32
unsigned nsmall, nlarge, i;
size_t sz;
int flags;
tsdn_t *tsdn;
size_t sz;
int flags;
tsdn_t *tsdn;
flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
@ -132,14 +133,14 @@ do_arena_reset_pre(unsigned arena_ind, void ***ptrs, unsigned *nptrs) {
static void
do_arena_reset_post(void **ptrs, unsigned nptrs, unsigned arena_ind) {
tsdn_t *tsdn;
tsdn_t *tsdn;
unsigned i;
tsdn = tsdn_fetch();
if (have_background_thread) {
malloc_mutex_lock(tsdn,
&background_thread_info_get(arena_ind)->mtx);
malloc_mutex_lock(
tsdn, &background_thread_info_get(arena_ind)->mtx);
}
/* Verify allocations no longer exist. */
for (i = 0; i < nptrs; i++) {
@ -147,8 +148,8 @@ do_arena_reset_post(void **ptrs, unsigned nptrs, unsigned arena_ind) {
"Allocation should no longer exist");
}
if (have_background_thread) {
malloc_mutex_unlock(tsdn,
&background_thread_info_get(arena_ind)->mtx);
malloc_mutex_unlock(
tsdn, &background_thread_info_get(arena_ind)->mtx);
}
free(ptrs);
@ -159,7 +160,7 @@ do_arena_reset_destroy(const char *name, unsigned arena_ind) {
size_t mib[3];
size_t miblen;
miblen = sizeof(mib)/sizeof(size_t);
miblen = sizeof(mib) / sizeof(size_t);
expect_d_eq(mallctlnametomib(name, mib, &miblen), 0,
"Unexpected mallctlnametomib() failure");
mib[1] = (size_t)arena_ind;
@ -179,7 +180,7 @@ do_arena_destroy(unsigned arena_ind) {
TEST_BEGIN(test_arena_reset) {
unsigned arena_ind;
void **ptrs;
void **ptrs;
unsigned nptrs;
arena_ind = do_arena_create(NULL);
@ -191,23 +192,25 @@ TEST_END
static bool
arena_i_initialized(unsigned arena_ind, bool refresh) {
bool initialized;
bool initialized;
size_t mib[3];
size_t miblen, sz;
if (refresh) {
uint64_t epoch = 1;
expect_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
sizeof(epoch)), 0, "Unexpected mallctl() failure");
expect_d_eq(
mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
}
miblen = sizeof(mib)/sizeof(size_t);
miblen = sizeof(mib) / sizeof(size_t);
expect_d_eq(mallctlnametomib("arena.0.initialized", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure");
mib[1] = (size_t)arena_ind;
sz = sizeof(initialized);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&initialized, &sz, NULL,
0), 0, "Unexpected mallctlbymib() failure");
expect_d_eq(
mallctlbymib(mib, miblen, (void *)&initialized, &sz, NULL, 0), 0,
"Unexpected mallctlbymib() failure");
return initialized;
}
@ -220,7 +223,7 @@ TEST_END
TEST_BEGIN(test_arena_destroy_hooks_default) {
unsigned arena_ind, arena_ind_another, arena_ind_prev;
void **ptrs;
void **ptrs;
unsigned nptrs;
arena_ind = do_arena_create(NULL);
@ -249,26 +252,27 @@ TEST_BEGIN(test_arena_destroy_hooks_default) {
arena_ind_prev = arena_ind;
arena_ind = do_arena_create(NULL);
do_arena_reset_pre(arena_ind, &ptrs, &nptrs);
expect_u_eq(arena_ind, arena_ind_prev,
"Arena index should have been recycled");
expect_u_eq(
arena_ind, arena_ind_prev, "Arena index should have been recycled");
do_arena_destroy(arena_ind);
do_arena_reset_post(ptrs, nptrs, arena_ind);
do_arena_destroy(arena_ind_another);
/* Try arena.create with custom hooks. */
size_t sz = sizeof(extent_hooks_t *);
size_t sz = sizeof(extent_hooks_t *);
extent_hooks_t *a0_default_hooks;
expect_d_eq(mallctl("arena.0.extent_hooks", (void *)&a0_default_hooks,
&sz, NULL, 0), 0, "Unexpected mallctlnametomib() failure");
&sz, NULL, 0),
0, "Unexpected mallctlnametomib() failure");
/* Default impl; but wrapped as "customized". */
extent_hooks_t new_hooks = *a0_default_hooks;
extent_hooks_t new_hooks = *a0_default_hooks;
extent_hooks_t *hook = &new_hooks;
sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz,
(void *)&hook, sizeof(void *)), 0,
"Unexpected mallctl() failure");
(void *)&hook, sizeof(void *)),
0, "Unexpected mallctl() failure");
do_arena_destroy(arena_ind);
}
TEST_END
@ -280,13 +284,15 @@ TEST_END
static bool
extent_dalloc_unmap(extent_hooks_t *extent_hooks, void *addr, size_t size,
bool committed, unsigned arena_ind) {
TRACE_HOOK("%s(extent_hooks=%p, addr=%p, size=%zu, committed=%s, "
"arena_ind=%u)\n", __func__, extent_hooks, addr, size, committed ?
"true" : "false", arena_ind);
TRACE_HOOK(
"%s(extent_hooks=%p, addr=%p, size=%zu, committed=%s, "
"arena_ind=%u)\n",
__func__, extent_hooks, addr, size, committed ? "true" : "false",
arena_ind);
expect_ptr_eq(extent_hooks, &hooks,
"extent_hooks should be same as pointer used to set hooks");
expect_ptr_eq(extent_hooks->dalloc, extent_dalloc_unmap,
"Wrong hook function");
expect_ptr_eq(
extent_hooks->dalloc, extent_dalloc_unmap, "Wrong hook function");
called_dalloc = true;
if (!try_dalloc) {
return true;
@ -301,21 +307,15 @@ extent_dalloc_unmap(extent_hooks_t *extent_hooks, void *addr, size_t size,
static extent_hooks_t hooks_orig;
static extent_hooks_t hooks_unmap = {
extent_alloc_hook,
extent_dalloc_unmap, /* dalloc */
extent_destroy_hook,
extent_commit_hook,
extent_decommit_hook,
extent_purge_lazy_hook,
extent_purge_forced_hook,
extent_split_hook,
extent_merge_hook
};
static extent_hooks_t hooks_unmap = {extent_alloc_hook,
extent_dalloc_unmap, /* dalloc */
extent_destroy_hook, extent_commit_hook, extent_decommit_hook,
extent_purge_lazy_hook, extent_purge_forced_hook, extent_split_hook,
extent_merge_hook};
TEST_BEGIN(test_arena_destroy_hooks_unmap) {
unsigned arena_ind;
void **ptrs;
void **ptrs;
unsigned nptrs;
extent_hooks_prep();
@ -353,9 +353,6 @@ TEST_END
int
main(void) {
return test(
test_arena_reset,
test_arena_destroy_initial,
test_arena_destroy_hooks_default,
test_arena_destroy_hooks_unmap);
return test(test_arena_reset, test_arena_destroy_initial,
test_arena_destroy_hooks_default, test_arena_destroy_hooks_unmap);
}

View file

@ -187,7 +187,6 @@ TEST_BEGIN(test_atomic_u64) {
}
TEST_END
TEST_STRUCT(uint32_t, u32);
TEST_BEGIN(test_atomic_u32) {
INTEGER_TEST_BODY(uint32_t, u32);
@ -212,7 +211,6 @@ TEST_BEGIN(test_atomic_zd) {
}
TEST_END
TEST_STRUCT(unsigned, u);
TEST_BEGIN(test_atomic_u) {
INTEGER_TEST_BODY(unsigned, u);
@ -221,11 +219,6 @@ TEST_END
int
main(void) {
return test(
test_atomic_u64,
test_atomic_u32,
test_atomic_p,
test_atomic_zu,
test_atomic_zd,
test_atomic_u);
return test(test_atomic_u64, test_atomic_u32, test_atomic_p,
test_atomic_zu, test_atomic_zd, test_atomic_u);
}

View file

@ -4,14 +4,13 @@
static void
test_switch_background_thread_ctl(bool new_val) {
bool e0, e1;
bool e0, e1;
size_t sz = sizeof(bool);
e1 = new_val;
expect_d_eq(mallctl("background_thread", (void *)&e0, &sz,
&e1, sz), 0, "Unexpected mallctl() failure");
expect_b_eq(e0, !e1,
"background_thread should be %d before.\n", !e1);
expect_d_eq(mallctl("background_thread", (void *)&e0, &sz, &e1, sz), 0,
"Unexpected mallctl() failure");
expect_b_eq(e0, !e1, "background_thread should be %d before.\n", !e1);
if (e1) {
expect_zu_gt(n_background_threads, 0,
"Number of background threads should be non zero.\n");
@ -23,14 +22,13 @@ test_switch_background_thread_ctl(bool new_val) {
static void
test_repeat_background_thread_ctl(bool before) {
bool e0, e1;
bool e0, e1;
size_t sz = sizeof(bool);
e1 = before;
expect_d_eq(mallctl("background_thread", (void *)&e0, &sz,
&e1, sz), 0, "Unexpected mallctl() failure");
expect_b_eq(e0, before,
"background_thread should be %d.\n", before);
expect_d_eq(mallctl("background_thread", (void *)&e0, &sz, &e1, sz), 0,
"Unexpected mallctl() failure");
expect_b_eq(e0, before, "background_thread should be %d.\n", before);
if (e1) {
expect_zu_gt(n_background_threads, 0,
"Number of background threads should be non zero.\n");
@ -43,15 +41,15 @@ test_repeat_background_thread_ctl(bool before) {
TEST_BEGIN(test_background_thread_ctl) {
test_skip_if(!have_background_thread);
bool e0, e1;
bool e0, e1;
size_t sz = sizeof(bool);
expect_d_eq(mallctl("opt.background_thread", (void *)&e0, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("background_thread", (void *)&e1, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
expect_b_eq(e0, e1,
"Default and opt.background_thread does not match.\n");
expect_d_eq(mallctl("opt.background_thread", (void *)&e0, &sz, NULL, 0),
0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("background_thread", (void *)&e1, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
expect_b_eq(
e0, e1, "Default and opt.background_thread does not match.\n");
if (e0) {
test_switch_background_thread_ctl(false);
}
@ -75,7 +73,7 @@ TEST_BEGIN(test_background_thread_running) {
test_skip_if(!config_stats);
#if defined(JEMALLOC_BACKGROUND_THREAD)
tsd_t *tsd = tsd_fetch();
tsd_t *tsd = tsd_fetch();
background_thread_info_t *info = &background_thread_info[0];
test_repeat_background_thread_ctl(false);
@ -113,6 +111,5 @@ int
main(void) {
/* Background_thread creation tests reentrancy naturally. */
return test_no_reentrancy(
test_background_thread_ctl,
test_background_thread_running);
test_background_thread_ctl, test_background_thread_running);
}

View file

@ -1,6 +1,7 @@
#include "test/jemalloc_test.h"
const char *malloc_conf = "background_thread:false,narenas:1,max_background_threads:8";
const char *malloc_conf =
"background_thread:false,narenas:1,max_background_threads:8";
static unsigned
max_test_narenas(void) {
@ -21,14 +22,14 @@ TEST_BEGIN(test_deferred) {
test_skip_if(!have_background_thread);
unsigned id;
size_t sz_u = sizeof(unsigned);
size_t sz_u = sizeof(unsigned);
for (unsigned i = 0; i < max_test_narenas(); i++) {
expect_d_eq(mallctl("arenas.create", &id, &sz_u, NULL, 0), 0,
"Failed to create arena");
}
bool enable = true;
bool enable = true;
size_t sz_b = sizeof(bool);
expect_d_eq(mallctl("background_thread", NULL, NULL, &enable, sz_b), 0,
"Failed to enable background threads");
@ -44,29 +45,32 @@ TEST_BEGIN(test_max_background_threads) {
size_t max_n_thds;
size_t opt_max_n_thds;
size_t sz_m = sizeof(max_n_thds);
expect_d_eq(mallctl("opt.max_background_threads",
&opt_max_n_thds, &sz_m, NULL, 0), 0,
"Failed to get opt.max_background_threads");
expect_d_eq(mallctl("max_background_threads", &max_n_thds, &sz_m, NULL,
0), 0, "Failed to get max background threads");
expect_d_eq(mallctl("opt.max_background_threads", &opt_max_n_thds,
&sz_m, NULL, 0),
0, "Failed to get opt.max_background_threads");
expect_d_eq(
mallctl("max_background_threads", &max_n_thds, &sz_m, NULL, 0), 0,
"Failed to get max background threads");
expect_zu_eq(opt_max_n_thds, max_n_thds,
"max_background_threads and "
"opt.max_background_threads should match");
expect_d_eq(mallctl("max_background_threads", NULL, NULL, &max_n_thds,
sz_m), 0, "Failed to set max background threads");
expect_d_eq(
mallctl("max_background_threads", NULL, NULL, &max_n_thds, sz_m), 0,
"Failed to set max background threads");
size_t size_zero = 0;
expect_d_ne(mallctl("max_background_threads", NULL, NULL, &size_zero,
sz_m), 0, "Should not allow zero background threads");
expect_d_ne(
mallctl("max_background_threads", NULL, NULL, &size_zero, sz_m), 0,
"Should not allow zero background threads");
unsigned id;
size_t sz_u = sizeof(unsigned);
size_t sz_u = sizeof(unsigned);
for (unsigned i = 0; i < max_test_narenas(); i++) {
expect_d_eq(mallctl("arenas.create", &id, &sz_u, NULL, 0), 0,
"Failed to create arena");
}
bool enable = true;
bool enable = true;
size_t sz_b = sizeof(bool);
expect_d_eq(mallctl("background_thread", NULL, NULL, &enable, sz_b), 0,
"Failed to enable background threads");
@ -75,16 +79,18 @@ TEST_BEGIN(test_max_background_threads) {
size_t new_max_thds = max_n_thds - 1;
if (new_max_thds > 0) {
expect_d_eq(mallctl("max_background_threads", NULL, NULL,
&new_max_thds, sz_m), 0,
"Failed to set max background threads");
&new_max_thds, sz_m),
0, "Failed to set max background threads");
expect_zu_eq(n_background_threads, new_max_thds,
"Number of background threads should decrease by 1.\n");
}
new_max_thds = 1;
expect_d_eq(mallctl("max_background_threads", NULL, NULL, &new_max_thds,
sz_m), 0, "Failed to set max background threads");
expect_d_ne(mallctl("max_background_threads", NULL, NULL, &size_zero,
sz_m), 0, "Should not allow zero background threads");
expect_d_eq(
mallctl("max_background_threads", NULL, NULL, &new_max_thds, sz_m),
0, "Failed to set max background threads");
expect_d_ne(
mallctl("max_background_threads", NULL, NULL, &size_zero, sz_m), 0,
"Should not allow zero background threads");
expect_zu_eq(n_background_threads, new_max_thds,
"Number of background threads should be 1.\n");
}
@ -92,7 +98,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_deferred,
test_max_background_threads);
return test_no_reentrancy(test_deferred, test_max_background_threads);
}

View file

@ -3,37 +3,31 @@
#include "test/extent_hooks.h"
static extent_hooks_t hooks_null = {
extent_alloc_hook,
NULL, /* dalloc */
NULL, /* destroy */
NULL, /* commit */
NULL, /* decommit */
NULL, /* purge_lazy */
NULL, /* purge_forced */
NULL, /* split */
NULL /* merge */
extent_alloc_hook, NULL, /* dalloc */
NULL, /* destroy */
NULL, /* commit */
NULL, /* decommit */
NULL, /* purge_lazy */
NULL, /* purge_forced */
NULL, /* split */
NULL /* merge */
};
static extent_hooks_t hooks_not_null = {
extent_alloc_hook,
extent_dalloc_hook,
extent_destroy_hook,
NULL, /* commit */
extent_decommit_hook,
extent_purge_lazy_hook,
extent_purge_forced_hook,
NULL, /* split */
NULL /* merge */
extent_alloc_hook, extent_dalloc_hook, extent_destroy_hook,
NULL, /* commit */
extent_decommit_hook, extent_purge_lazy_hook, extent_purge_forced_hook,
NULL, /* split */
NULL /* merge */
};
TEST_BEGIN(test_base_hooks_default) {
base_t *base;
size_t allocated0, allocated1, edata_allocated,
rtree_allocated, resident, mapped, n_thp;
size_t allocated0, allocated1, edata_allocated, rtree_allocated,
resident, mapped, n_thp;
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
base = base_new(tsdn, 0,
(extent_hooks_t *)&ehooks_default_extent_hooks,
base = base_new(tsdn, 0, (extent_hooks_t *)&ehooks_default_extent_hooks,
/* metadata_use_hooks */ true);
if (config_stats) {
@ -42,13 +36,13 @@ TEST_BEGIN(test_base_hooks_default) {
expect_zu_ge(allocated0, sizeof(base_t),
"Base header should count as allocated");
if (opt_metadata_thp == metadata_thp_always) {
expect_zu_gt(n_thp, 0,
"Base should have 1 THP at least.");
expect_zu_gt(
n_thp, 0, "Base should have 1 THP at least.");
}
}
expect_ptr_not_null(base_alloc(tsdn, base, 42, 1),
"Unexpected base_alloc() failure");
expect_ptr_not_null(
base_alloc(tsdn, base, 42, 1), "Unexpected base_alloc() failure");
if (config_stats) {
base_stats_get(tsdn, base, &allocated1, &edata_allocated,
@ -63,9 +57,9 @@ TEST_END
TEST_BEGIN(test_base_hooks_null) {
extent_hooks_t hooks_orig;
base_t *base;
size_t allocated0, allocated1, edata_allocated,
rtree_allocated, resident, mapped, n_thp;
base_t *base;
size_t allocated0, allocated1, edata_allocated, rtree_allocated,
resident, mapped, n_thp;
extent_hooks_prep();
try_dalloc = false;
@ -86,13 +80,13 @@ TEST_BEGIN(test_base_hooks_null) {
expect_zu_ge(allocated0, sizeof(base_t),
"Base header should count as allocated");
if (opt_metadata_thp == metadata_thp_always) {
expect_zu_gt(n_thp, 0,
"Base should have 1 THP at least.");
expect_zu_gt(
n_thp, 0, "Base should have 1 THP at least.");
}
}
expect_ptr_not_null(base_alloc(tsdn, base, 42, 1),
"Unexpected base_alloc() failure");
expect_ptr_not_null(
base_alloc(tsdn, base, 42, 1), "Unexpected base_alloc() failure");
if (config_stats) {
base_stats_get(tsdn, base, &allocated1, &edata_allocated,
@ -109,8 +103,8 @@ TEST_END
TEST_BEGIN(test_base_hooks_not_null) {
extent_hooks_t hooks_orig;
base_t *base;
void *p, *q, *r, *r_exp;
base_t *base;
void *p, *q, *r, *r_exp;
extent_hooks_prep();
try_dalloc = false;
@ -133,33 +127,34 @@ TEST_BEGIN(test_base_hooks_not_null) {
*/
{
const size_t alignments[] = {
1,
QUANTUM,
QUANTUM << 1,
CACHELINE,
CACHELINE << 1,
1,
QUANTUM,
QUANTUM << 1,
CACHELINE,
CACHELINE << 1,
};
unsigned i;
for (i = 0; i < sizeof(alignments) / sizeof(size_t); i++) {
size_t alignment = alignments[i];
size_t align_ceil = ALIGNMENT_CEILING(alignment,
QUANTUM);
size_t align_ceil = ALIGNMENT_CEILING(
alignment, QUANTUM);
p = base_alloc(tsdn, base, 1, alignment);
expect_ptr_not_null(p,
"Unexpected base_alloc() failure");
expect_ptr_not_null(
p, "Unexpected base_alloc() failure");
expect_ptr_eq(p,
(void *)(ALIGNMENT_CEILING((uintptr_t)p,
alignment)), "Expected quantum alignment");
(void *)(ALIGNMENT_CEILING(
(uintptr_t)p, alignment)),
"Expected quantum alignment");
q = base_alloc(tsdn, base, alignment, alignment);
expect_ptr_not_null(q,
"Unexpected base_alloc() failure");
expect_ptr_not_null(
q, "Unexpected base_alloc() failure");
expect_ptr_eq((void *)((uintptr_t)p + align_ceil), q,
"Minimal allocation should take up %zu bytes",
align_ceil);
r = base_alloc(tsdn, base, 1, alignment);
expect_ptr_not_null(r,
"Unexpected base_alloc() failure");
expect_ptr_not_null(
r, "Unexpected base_alloc() failure");
expect_ptr_eq((void *)((uintptr_t)q + align_ceil), r,
"Minimal allocation should take up %zu bytes",
align_ceil);
@ -193,21 +188,18 @@ TEST_BEGIN(test_base_hooks_not_null) {
* Check for proper alignment support when normal blocks are too small.
*/
{
const size_t alignments[] = {
HUGEPAGE,
HUGEPAGE << 1
};
unsigned i;
const size_t alignments[] = {HUGEPAGE, HUGEPAGE << 1};
unsigned i;
for (i = 0; i < sizeof(alignments) / sizeof(size_t); i++) {
size_t alignment = alignments[i];
p = base_alloc(tsdn, base, QUANTUM, alignment);
expect_ptr_not_null(p,
"Unexpected base_alloc() failure");
expect_ptr_not_null(
p, "Unexpected base_alloc() failure");
expect_ptr_eq(p,
(void *)(ALIGNMENT_CEILING((uintptr_t)p,
alignment)), "Expected %zu-byte alignment",
alignment);
(void *)(ALIGNMENT_CEILING(
(uintptr_t)p, alignment)),
"Expected %zu-byte alignment", alignment);
}
}
@ -237,12 +229,11 @@ TEST_BEGIN(test_base_ehooks_get_for_metadata_default_hook) {
base = base_new(tsdn, 0, &hooks, /* metadata_use_hooks */ false);
ehooks_t *ehooks = base_ehooks_get_for_metadata(base);
expect_true(ehooks_are_default(ehooks),
"Expected default extent hook functions pointer");
"Expected default extent hook functions pointer");
base_delete(tsdn, base);
}
TEST_END
TEST_BEGIN(test_base_ehooks_get_for_metadata_custom_hook) {
extent_hooks_prep();
memcpy(&hooks, &hooks_not_null, sizeof(extent_hooks_t));
@ -251,17 +242,15 @@ TEST_BEGIN(test_base_ehooks_get_for_metadata_custom_hook) {
base = base_new(tsdn, 0, &hooks, /* metadata_use_hooks */ true);
ehooks_t *ehooks = base_ehooks_get_for_metadata(base);
expect_ptr_eq(&hooks, ehooks_get_extent_hooks_ptr(ehooks),
"Expected user-specified extend hook functions pointer");
"Expected user-specified extend hook functions pointer");
base_delete(tsdn, base);
}
TEST_END
int
main(void) {
return test(
test_base_hooks_default,
test_base_hooks_null,
return test(test_base_hooks_default, test_base_hooks_null,
test_base_hooks_not_null,
test_base_ehooks_get_for_metadata_default_hook,
test_base_ehooks_get_for_metadata_custom_hook);
test_base_ehooks_get_for_metadata_default_hook,
test_base_ehooks_get_for_metadata_custom_hook);
}

View file

@ -6,8 +6,8 @@ static void *global_ptrs[BATCH_MAX];
#define PAGE_ALIGNED(ptr) (((uintptr_t)ptr & PAGE_MASK) == 0)
static void
verify_batch_basic(tsd_t *tsd, void **ptrs, size_t batch, size_t usize,
bool zero) {
verify_batch_basic(
tsd_t *tsd, void **ptrs, size_t batch, size_t usize, bool zero) {
for (size_t i = 0; i < batch; ++i) {
void *p = ptrs[i];
expect_zu_eq(isalloc(tsd_tsdn(tsd), p), usize, "");
@ -46,7 +46,8 @@ verify_batch_locality(tsd_t *tsd, void **ptrs, size_t batch, size_t usize,
assert(i > 0);
void *q = ptrs[i - 1];
expect_true((uintptr_t)p > (uintptr_t)q
&& (size_t)((uintptr_t)p - (uintptr_t)q) == usize, "");
&& (size_t)((uintptr_t)p - (uintptr_t)q) == usize,
"");
}
}
@ -62,16 +63,17 @@ struct batch_alloc_packet_s {
void **ptrs;
size_t num;
size_t size;
int flags;
int flags;
};
static size_t
batch_alloc_wrapper(void **ptrs, size_t num, size_t size, int flags) {
batch_alloc_packet_t batch_alloc_packet = {ptrs, num, size, flags};
size_t filled;
size_t len = sizeof(size_t);
size_t filled;
size_t len = sizeof(size_t);
assert_d_eq(mallctl("experimental.batch_alloc", &filled, &len,
&batch_alloc_packet, sizeof(batch_alloc_packet)), 0, "");
&batch_alloc_packet, sizeof(batch_alloc_packet)),
0, "");
return filled;
}
@ -79,16 +81,16 @@ static void
test_wrapper(size_t size, size_t alignment, bool zero, unsigned arena_flag) {
tsd_t *tsd = tsd_fetch();
assert(tsd != NULL);
const size_t usize =
(alignment != 0 ? sz_sa2u(size, alignment) : sz_s2u(size));
const szind_t ind = sz_size2index(usize);
const size_t usize = (alignment != 0 ? sz_sa2u(size, alignment)
: sz_s2u(size));
const szind_t ind = sz_size2index(usize);
const bin_info_t *bin_info = &bin_infos[ind];
const unsigned nregs = bin_info->nregs;
const unsigned nregs = bin_info->nregs;
assert(nregs > 0);
arena_t *arena;
if (arena_flag != 0) {
arena = arena_get(tsd_tsdn(tsd), MALLOCX_ARENA_GET(arena_flag),
false);
arena = arena_get(
tsd_tsdn(tsd), MALLOCX_ARENA_GET(arena_flag), false);
} else {
arena = arena_choose(tsd, NULL);
}
@ -122,13 +124,13 @@ test_wrapper(size_t size, size_t alignment, bool zero, unsigned arena_flag) {
}
size_t batch = base + (size_t)j;
assert(batch < BATCH_MAX);
size_t filled = batch_alloc_wrapper(global_ptrs, batch,
size, flags);
size_t filled = batch_alloc_wrapper(
global_ptrs, batch, size, flags);
assert_zu_eq(filled, batch, "");
verify_batch_basic(tsd, global_ptrs, batch, usize,
zero);
verify_batch_locality(tsd, global_ptrs, batch, usize,
arena, nregs);
verify_batch_basic(
tsd, global_ptrs, batch, usize, zero);
verify_batch_locality(
tsd, global_ptrs, batch, usize, arena, nregs);
release_batch(global_ptrs, batch, usize);
}
}
@ -153,9 +155,10 @@ TEST_END
TEST_BEGIN(test_batch_alloc_manual_arena) {
unsigned arena_ind;
size_t len_unsigned = sizeof(unsigned);
assert_d_eq(mallctl("arenas.create", &arena_ind, &len_unsigned, NULL,
0), 0, "");
size_t len_unsigned = sizeof(unsigned);
assert_d_eq(
mallctl("arenas.create", &arena_ind, &len_unsigned, NULL, 0), 0,
"");
test_wrapper(11, 0, false, MALLOCX_ARENA(arena_ind));
}
TEST_END
@ -180,10 +183,7 @@ TEST_END
int
main(void) {
return test(
test_batch_alloc,
test_batch_alloc_zero,
test_batch_alloc_aligned,
test_batch_alloc_manual_arena,
return test(test_batch_alloc, test_batch_alloc_zero,
test_batch_alloc_aligned, test_batch_alloc_manual_arena,
test_batch_alloc_large);
}

View file

@ -5,7 +5,7 @@
TEST_BEGIN(test_simple) {
enum { NELEMS_MAX = 10, DATA_BASE_VAL = 100, NRUNS = 5 };
batcher_t batcher;
size_t data[NELEMS_MAX];
size_t data[NELEMS_MAX];
for (size_t nelems = 0; nelems < NELEMS_MAX; nelems++) {
batcher_init(&batcher, nelems);
for (int run = 0; run < NRUNS; run++) {
@ -13,8 +13,8 @@ TEST_BEGIN(test_simple) {
data[i] = (size_t)-1;
}
for (size_t i = 0; i < nelems; i++) {
size_t idx = batcher_push_begin(TSDN_NULL,
&batcher, 1);
size_t idx = batcher_push_begin(
TSDN_NULL, &batcher, 1);
assert_zu_eq(i, idx, "Wrong index");
assert_zu_eq((size_t)-1, data[idx],
"Expected uninitialized slot");
@ -22,8 +22,8 @@ TEST_BEGIN(test_simple) {
batcher_push_end(TSDN_NULL, &batcher);
}
if (nelems > 0) {
size_t idx = batcher_push_begin(TSDN_NULL,
&batcher, 1);
size_t idx = batcher_push_begin(
TSDN_NULL, &batcher, 1);
assert_zu_eq(BATCHER_NO_IDX, idx,
"Shouldn't be able to push into a full "
"batcher");
@ -51,7 +51,7 @@ TEST_BEGIN(test_simple) {
TEST_END
TEST_BEGIN(test_multi_push) {
size_t idx, nelems;
size_t idx, nelems;
batcher_t batcher;
batcher_init(&batcher, 11);
/* Push two at a time, 5 times, for 10 total. */
@ -82,13 +82,13 @@ enum {
typedef struct stress_test_data_s stress_test_data_t;
struct stress_test_data_s {
batcher_t batcher;
mtx_t pop_mtx;
batcher_t batcher;
mtx_t pop_mtx;
atomic_u32_t thread_id;
uint32_t elems_data[STRESS_TEST_ELEMS];
size_t push_count[STRESS_TEST_ELEMS];
size_t pop_count[STRESS_TEST_ELEMS];
uint32_t elems_data[STRESS_TEST_ELEMS];
size_t push_count[STRESS_TEST_ELEMS];
size_t pop_count[STRESS_TEST_ELEMS];
atomic_zu_t atomic_push_count[STRESS_TEST_ELEMS];
atomic_zu_t atomic_pop_count[STRESS_TEST_ELEMS];
};
@ -108,7 +108,8 @@ get_nth_set(bool elems_owned[STRESS_TEST_ELEMS], size_t n) {
return i;
}
}
assert_not_reached("Asked for the %zu'th set element when < %zu are "
assert_not_reached(
"Asked for the %zu'th set element when < %zu are "
"set",
n, n);
/* Just to silence a compiler warning. */
@ -118,20 +119,19 @@ get_nth_set(bool elems_owned[STRESS_TEST_ELEMS], size_t n) {
static void *
stress_test_thd(void *arg) {
stress_test_data_t *data = arg;
size_t prng = atomic_fetch_add_u32(&data->thread_id, 1,
ATOMIC_RELAXED);
size_t prng = atomic_fetch_add_u32(&data->thread_id, 1, ATOMIC_RELAXED);
size_t nelems_owned = 0;
bool elems_owned[STRESS_TEST_ELEMS] = {0};
bool elems_owned[STRESS_TEST_ELEMS] = {0};
size_t local_push_count[STRESS_TEST_ELEMS] = {0};
size_t local_pop_count[STRESS_TEST_ELEMS] = {0};
for (int i = 0; i < STRESS_TEST_OPS; i++) {
size_t rnd = prng_range_zu(&prng,
STRESS_TEST_PUSH_TO_POP_RATIO);
size_t rnd = prng_range_zu(
&prng, STRESS_TEST_PUSH_TO_POP_RATIO);
if (rnd == 0 || nelems_owned == 0) {
size_t nelems = batcher_pop_begin(TSDN_NULL,
&data->batcher);
size_t nelems = batcher_pop_begin(
TSDN_NULL, &data->batcher);
if (nelems == BATCHER_NO_IDX) {
continue;
}
@ -147,19 +147,18 @@ stress_test_thd(void *arg) {
}
batcher_pop_end(TSDN_NULL, &data->batcher);
} else {
size_t elem_to_push_idx = prng_range_zu(&prng,
nelems_owned);
size_t elem = get_nth_set(elems_owned,
elem_to_push_idx);
assert_true(
elems_owned[elem],
size_t elem_to_push_idx = prng_range_zu(
&prng, nelems_owned);
size_t elem = get_nth_set(
elems_owned, elem_to_push_idx);
assert_true(elems_owned[elem],
"Should own element we're about to pop");
elems_owned[elem] = false;
local_push_count[elem]++;
data->push_count[elem]++;
nelems_owned--;
size_t idx = batcher_push_begin(TSDN_NULL,
&data->batcher, 1);
size_t idx = batcher_push_begin(
TSDN_NULL, &data->batcher, 1);
assert_zu_ne(idx, BATCHER_NO_IDX,
"Batcher can't be full -- we have one of its "
"elems!");
@ -171,10 +170,10 @@ stress_test_thd(void *arg) {
/* Push all local elems back, flush local counts to the shared ones. */
size_t push_idx = 0;
if (nelems_owned != 0) {
push_idx = batcher_push_begin(TSDN_NULL, &data->batcher,
nelems_owned);
assert_zu_ne(BATCHER_NO_IDX, push_idx,
"Should be space to push");
push_idx = batcher_push_begin(
TSDN_NULL, &data->batcher, nelems_owned);
assert_zu_ne(
BATCHER_NO_IDX, push_idx, "Should be space to push");
}
for (size_t i = 0; i < STRESS_TEST_ELEMS; i++) {
if (elems_owned[i]) {
@ -183,12 +182,10 @@ stress_test_thd(void *arg) {
local_push_count[i]++;
data->push_count[i]++;
}
atomic_fetch_add_zu(
&data->atomic_push_count[i], local_push_count[i],
ATOMIC_RELAXED);
atomic_fetch_add_zu(
&data->atomic_pop_count[i], local_pop_count[i],
ATOMIC_RELAXED);
atomic_fetch_add_zu(&data->atomic_push_count[i],
local_push_count[i], ATOMIC_RELAXED);
atomic_fetch_add_zu(&data->atomic_pop_count[i],
local_pop_count[i], ATOMIC_RELAXED);
}
if (nelems_owned != 0) {
batcher_push_end(TSDN_NULL, &data->batcher);
@ -223,8 +220,8 @@ TEST_BEGIN(test_stress) {
thd_join(threads[i], NULL);
}
for (int i = 0; i < STRESS_TEST_ELEMS; i++) {
assert_zu_ne(0, data.push_count[i],
"Should have done something!");
assert_zu_ne(
0, data.push_count[i], "Should have done something!");
assert_zu_eq(data.push_count[i], data.pop_count[i],
"every element should be pushed and popped an equal number "
"of times");

View file

@ -9,10 +9,10 @@ enum {
typedef struct stress_thread_data_s stress_thread_data_t;
struct stress_thread_data_s {
unsigned thd_id;
unsigned thd_id;
atomic_zu_t *ready_thds;
atomic_zu_t *done_thds;
void **to_dalloc;
void **to_dalloc;
};
static atomic_zu_t push_failure_count;
@ -68,19 +68,19 @@ increment_pop_attempt(size_t elems_to_pop) {
static void
increment_slab_dalloc_count(unsigned slab_dalloc_count, bool list_empty) {
if (slab_dalloc_count > 0) {
atomic_fetch_add_zu(&dalloc_nonzero_slab_count, 1,
ATOMIC_RELAXED);
atomic_fetch_add_zu(
&dalloc_nonzero_slab_count, 1, ATOMIC_RELAXED);
} else {
atomic_fetch_add_zu(&dalloc_zero_slab_count, 1,
ATOMIC_RELAXED);
atomic_fetch_add_zu(&dalloc_zero_slab_count, 1, ATOMIC_RELAXED);
}
if (!list_empty) {
atomic_fetch_add_zu(&dalloc_nonempty_list_count, 1,
ATOMIC_RELAXED);
atomic_fetch_add_zu(
&dalloc_nonempty_list_count, 1, ATOMIC_RELAXED);
}
}
static void flush_tcache() {
static void
flush_tcache() {
assert_d_eq(0, mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
"Unexpected mallctl failure");
}
@ -88,7 +88,7 @@ static void flush_tcache() {
static void *
stress_thread(void *arg) {
stress_thread_data_t *data = arg;
uint64_t prng_state = data->thd_id;
uint64_t prng_state = data->thd_id;
atomic_fetch_add_zu(data->ready_thds, 1, ATOMIC_RELAXED);
while (atomic_load_zu(data->ready_thds, ATOMIC_RELAXED)
!= STRESS_THREADS) {
@ -99,7 +99,6 @@ stress_thread(void *arg) {
if (prng_range_u64(&prng_state, 3) == 0) {
flush_tcache();
}
}
flush_tcache();
atomic_fetch_add_zu(data->done_thds, 1, ATOMIC_RELAXED);
@ -125,9 +124,9 @@ stress_run(void (*main_thread_fn)(), int nruns) {
atomic_store_zu(&dalloc_nonempty_list_count, 0, ATOMIC_RELAXED);
for (int run = 0; run < nruns; run++) {
thd_t thds[STRESS_THREADS];
thd_t thds[STRESS_THREADS];
stress_thread_data_t thd_datas[STRESS_THREADS];
atomic_zu_t ready_thds;
atomic_zu_t ready_thds;
atomic_store_zu(&ready_thds, 0, ATOMIC_RELAXED);
atomic_zu_t done_thds;
atomic_store_zu(&done_thds, 0, ATOMIC_RELAXED);
@ -164,7 +163,7 @@ stress_run(void (*main_thread_fn)(), int nruns) {
static void
do_allocs_frees() {
enum {NALLOCS = 32};
enum { NALLOCS = 32 };
flush_tcache();
void *ptrs[NALLOCS];
for (int i = 0; i < NALLOCS; i++) {
@ -182,7 +181,7 @@ test_arena_reset_main_fn() {
}
TEST_BEGIN(test_arena_reset) {
int err;
int err;
unsigned arena;
unsigned old_arena;
@ -256,17 +255,16 @@ TEST_BEGIN(test_races) {
"Should have seen some pop successes");
assert_zu_lt(0, atomic_load_zu(&dalloc_zero_slab_count, ATOMIC_RELAXED),
"Expected some frees that didn't empty a slab");
assert_zu_lt(0, atomic_load_zu(&dalloc_nonzero_slab_count,
ATOMIC_RELAXED), "expected some frees that emptied a slab");
assert_zu_lt(0, atomic_load_zu(&dalloc_nonempty_list_count,
ATOMIC_RELAXED), "expected some frees that used the empty list");
assert_zu_lt(0,
atomic_load_zu(&dalloc_nonzero_slab_count, ATOMIC_RELAXED),
"expected some frees that emptied a slab");
assert_zu_lt(0,
atomic_load_zu(&dalloc_nonempty_list_count, ATOMIC_RELAXED),
"expected some frees that used the empty list");
}
TEST_END
int
main(void) {
return test_no_reentrancy(
test_arena_reset,
test_races,
test_fork);
return test_no_reentrancy(test_arena_reset, test_races, test_fork);
}

View file

@ -7,9 +7,9 @@
static void *
thd_producer(void *varg) {
void **mem = varg;
void **mem = varg;
unsigned arena, i;
size_t sz;
size_t sz;
sz = sizeof(arena);
/* Remote arena. */
@ -28,8 +28,8 @@ thd_producer(void *varg) {
}
TEST_BEGIN(test_producer_consumer) {
thd_t thds[NTHREADS];
void *mem[NTHREADS][REMOTE_NALLOC];
thd_t thds[NTHREADS];
void *mem[NTHREADS][REMOTE_NALLOC];
unsigned i;
/* Create producer threads to allocate. */
@ -42,8 +42,8 @@ TEST_BEGIN(test_producer_consumer) {
/* Remote deallocation by the current thread. */
for (i = 0; i < NTHREADS; i++) {
for (unsigned j = 0; j < REMOTE_NALLOC; j++) {
expect_ptr_not_null(mem[i][j],
"Unexpected remote allocation failure");
expect_ptr_not_null(
mem[i][j], "Unexpected remote allocation failure");
dallocx(mem[i][j], 0);
}
}
@ -52,7 +52,7 @@ TEST_END
static void *
thd_start(void *varg) {
void *ptr, *ptr2;
void *ptr, *ptr2;
edata_t *edata;
unsigned shard1, shard2;
@ -82,10 +82,10 @@ thd_start(void *varg) {
}
TEST_BEGIN(test_bin_shard_mt) {
test_skip_if(have_percpu_arena &&
PERCPU_ARENA_ENABLED(opt_percpu_arena));
test_skip_if(
have_percpu_arena && PERCPU_ARENA_ENABLED(opt_percpu_arena));
thd_t thds[NTHREADS];
thd_t thds[NTHREADS];
unsigned i;
for (i = 0; i < NTHREADS; i++) {
thd_create(&thds[i], thd_start, NULL);
@ -104,8 +104,8 @@ TEST_END
TEST_BEGIN(test_bin_shard) {
unsigned nbins, i;
size_t mib[4], mib2[4];
size_t miblen, miblen2, len;
size_t mib[4], mib2[4];
size_t miblen, miblen2, len;
len = sizeof(nbins);
expect_d_eq(mallctl("arenas.nbins", (void *)&nbins, &len, NULL, 0), 0,
@ -120,17 +120,19 @@ TEST_BEGIN(test_bin_shard) {
for (i = 0; i < nbins; i++) {
uint32_t nshards;
size_t size, sz1, sz2;
size_t size, sz1, sz2;
mib[2] = i;
sz1 = sizeof(nshards);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&nshards, &sz1,
NULL, 0), 0, "Unexpected mallctlbymib() failure");
expect_d_eq(
mallctlbymib(mib, miblen, (void *)&nshards, &sz1, NULL, 0),
0, "Unexpected mallctlbymib() failure");
mib2[2] = i;
sz2 = sizeof(size);
expect_d_eq(mallctlbymib(mib2, miblen2, (void *)&size, &sz2,
NULL, 0), 0, "Unexpected mallctlbymib() failure");
expect_d_eq(
mallctlbymib(mib2, miblen2, (void *)&size, &sz2, NULL, 0),
0, "Unexpected mallctlbymib() failure");
if (size >= 1 && size <= 128) {
expect_u_eq(nshards, 16, "Unexpected nshards");
@ -148,7 +150,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_bin_shard,
test_bin_shard_mt,
test_producer_consumer);
test_bin_shard, test_bin_shard_mt, test_producer_consumer);
}

View file

@ -2,36 +2,37 @@
#include "jemalloc/internal/bit_util.h"
#define TEST_POW2_CEIL(t, suf, pri) do { \
unsigned i, pow2; \
t x; \
\
expect_##suf##_eq(pow2_ceil_##suf(0), 0, "Unexpected result"); \
\
for (i = 0; i < sizeof(t) * 8; i++) { \
expect_##suf##_eq(pow2_ceil_##suf(((t)1) << i), ((t)1) \
<< i, "Unexpected result"); \
} \
\
for (i = 2; i < sizeof(t) * 8; i++) { \
expect_##suf##_eq(pow2_ceil_##suf((((t)1) << i) - 1), \
((t)1) << i, "Unexpected result"); \
} \
\
for (i = 0; i < sizeof(t) * 8 - 1; i++) { \
expect_##suf##_eq(pow2_ceil_##suf((((t)1) << i) + 1), \
((t)1) << (i+1), "Unexpected result"); \
} \
\
for (pow2 = 1; pow2 < 25; pow2++) { \
for (x = (((t)1) << (pow2-1)) + 1; x <= ((t)1) << pow2; \
x++) { \
expect_##suf##_eq(pow2_ceil_##suf(x), \
((t)1) << pow2, \
"Unexpected result, x=%"pri, x); \
} \
} \
} while (0)
#define TEST_POW2_CEIL(t, suf, pri) \
do { \
unsigned i, pow2; \
t x; \
\
expect_##suf##_eq(pow2_ceil_##suf(0), 0, "Unexpected result"); \
\
for (i = 0; i < sizeof(t) * 8; i++) { \
expect_##suf##_eq(pow2_ceil_##suf(((t)1) << i), \
((t)1) << i, "Unexpected result"); \
} \
\
for (i = 2; i < sizeof(t) * 8; i++) { \
expect_##suf##_eq(pow2_ceil_##suf((((t)1) << i) - 1), \
((t)1) << i, "Unexpected result"); \
} \
\
for (i = 0; i < sizeof(t) * 8 - 1; i++) { \
expect_##suf##_eq(pow2_ceil_##suf((((t)1) << i) + 1), \
((t)1) << (i + 1), "Unexpected result"); \
} \
\
for (pow2 = 1; pow2 < 25; pow2++) { \
for (x = (((t)1) << (pow2 - 1)) + 1; \
x <= ((t)1) << pow2; x++) { \
expect_##suf##_eq(pow2_ceil_##suf(x), \
((t)1) << pow2, \
"Unexpected result, x=%" pri, x); \
} \
} \
} while (0)
TEST_BEGIN(test_pow2_ceil_u64) {
TEST_POW2_CEIL(uint64_t, u64, FMTu64);
@ -54,10 +55,10 @@ expect_lg_ceil_range(size_t input, unsigned answer) {
expect_u_eq(0, answer, "Got %u as lg_ceil of 1", answer);
return;
}
expect_zu_le(input, (ZU(1) << answer),
"Got %u as lg_ceil of %zu", answer, input);
expect_zu_gt(input, (ZU(1) << (answer - 1)),
"Got %u as lg_ceil of %zu", answer, input);
expect_zu_le(input, (ZU(1) << answer), "Got %u as lg_ceil of %zu",
answer, input);
expect_zu_gt(input, (ZU(1) << (answer - 1)), "Got %u as lg_ceil of %zu",
answer, input);
}
static void
@ -66,8 +67,8 @@ expect_lg_floor_range(size_t input, unsigned answer) {
expect_u_eq(0, answer, "Got %u as lg_floor of 1", answer);
return;
}
expect_zu_ge(input, (ZU(1) << answer),
"Got %u as lg_floor of %zu", answer, input);
expect_zu_ge(input, (ZU(1) << answer), "Got %u as lg_floor of %zu",
answer, input);
expect_zu_lt(input, (ZU(1) << (answer + 1)),
"Got %u as lg_floor of %zu", answer, input);
}
@ -101,22 +102,24 @@ TEST_BEGIN(test_lg_ceil_floor) {
}
TEST_END
#define TEST_FFS(t, suf, test_suf, pri) do { \
for (unsigned i = 0; i < sizeof(t) * 8; i++) { \
for (unsigned j = 0; j <= i; j++) { \
for (unsigned k = 0; k <= j; k++) { \
t x = (t)1 << i; \
x |= (t)1 << j; \
x |= (t)1 << k; \
expect_##test_suf##_eq(ffs_##suf(x), k, \
"Unexpected result, x=%"pri, x); \
} \
} \
} \
} while(0)
#define TEST_FFS(t, suf, test_suf, pri) \
do { \
for (unsigned i = 0; i < sizeof(t) * 8; i++) { \
for (unsigned j = 0; j <= i; j++) { \
for (unsigned k = 0; k <= j; k++) { \
t x = (t)1 << i; \
x |= (t)1 << j; \
x |= (t)1 << k; \
expect_##test_suf##_eq(ffs_##suf(x), \
k, "Unexpected result, x=%" pri, \
x); \
} \
} \
} \
} while (0)
TEST_BEGIN(test_ffs_u) {
TEST_FFS(unsigned, u, u,"u");
TEST_FFS(unsigned, u, u, "u");
}
TEST_END
@ -145,22 +148,24 @@ TEST_BEGIN(test_ffs_zu) {
}
TEST_END
#define TEST_FLS(t, suf, test_suf, pri) do { \
for (unsigned i = 0; i < sizeof(t) * 8; i++) { \
for (unsigned j = 0; j <= i; j++) { \
for (unsigned k = 0; k <= j; k++) { \
t x = (t)1 << i; \
x |= (t)1 << j; \
x |= (t)1 << k; \
expect_##test_suf##_eq(fls_##suf(x), i, \
"Unexpected result, x=%"pri, x); \
} \
} \
} \
} while(0)
#define TEST_FLS(t, suf, test_suf, pri) \
do { \
for (unsigned i = 0; i < sizeof(t) * 8; i++) { \
for (unsigned j = 0; j <= i; j++) { \
for (unsigned k = 0; k <= j; k++) { \
t x = (t)1 << i; \
x |= (t)1 << j; \
x |= (t)1 << k; \
expect_##test_suf##_eq(fls_##suf(x), \
i, "Unexpected result, x=%" pri, \
x); \
} \
} \
} \
} while (0)
TEST_BEGIN(test_fls_u) {
TEST_FLS(unsigned, u, u,"u");
TEST_FLS(unsigned, u, u, "u");
}
TEST_END
@ -190,7 +195,7 @@ TEST_BEGIN(test_fls_zu) {
TEST_END
TEST_BEGIN(test_fls_u_slow) {
TEST_FLS(unsigned, u_slow, u,"u");
TEST_FLS(unsigned, u_slow, u, "u");
}
TEST_END
@ -280,30 +285,11 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_pow2_ceil_u64,
test_pow2_ceil_u32,
test_pow2_ceil_zu,
test_lg_ceil_floor,
test_ffs_u,
test_ffs_lu,
test_ffs_llu,
test_ffs_u32,
test_ffs_u64,
test_ffs_zu,
test_fls_u,
test_fls_lu,
test_fls_llu,
test_fls_u32,
test_fls_u64,
test_fls_zu,
test_fls_u_slow,
test_fls_lu_slow,
test_fls_llu_slow,
test_popcount_u,
test_popcount_u_slow,
test_popcount_lu,
test_popcount_lu_slow,
test_popcount_llu,
test_popcount_llu_slow);
return test_no_reentrancy(test_pow2_ceil_u64, test_pow2_ceil_u32,
test_pow2_ceil_zu, test_lg_ceil_floor, test_ffs_u, test_ffs_lu,
test_ffs_llu, test_ffs_u32, test_ffs_u64, test_ffs_zu, test_fls_u,
test_fls_lu, test_fls_llu, test_fls_u32, test_fls_u64, test_fls_zu,
test_fls_u_slow, test_fls_lu_slow, test_fls_llu_slow,
test_popcount_u, test_popcount_u_slow, test_popcount_lu,
test_popcount_lu_slow, test_popcount_llu, test_popcount_llu_slow);
}

View file

@ -9,14 +9,17 @@ test_bitmap_initializer_body(const bitmap_info_t *binfo, size_t nbits) {
expect_zu_eq(bitmap_size(binfo), bitmap_size(&binfo_dyn),
"Unexpected difference between static and dynamic initialization, "
"nbits=%zu", nbits);
"nbits=%zu",
nbits);
expect_zu_eq(binfo->nbits, binfo_dyn.nbits,
"Unexpected difference between static and dynamic initialization, "
"nbits=%zu", nbits);
"nbits=%zu",
nbits);
#ifdef BITMAP_USE_TREE
expect_u_eq(binfo->nlevels, binfo_dyn.nlevels,
"Unexpected difference between static and dynamic initialization, "
"nbits=%zu", nbits);
"nbits=%zu",
nbits);
{
unsigned i;
@ -24,7 +27,8 @@ test_bitmap_initializer_body(const bitmap_info_t *binfo, size_t nbits) {
expect_zu_eq(binfo->levels[i].group_offset,
binfo_dyn.levels[i].group_offset,
"Unexpected difference between static and dynamic "
"initialization, nbits=%zu, level=%u", nbits, i);
"initialization, nbits=%zu, level=%u",
nbits, i);
}
}
#else
@ -34,12 +38,12 @@ test_bitmap_initializer_body(const bitmap_info_t *binfo, size_t nbits) {
}
TEST_BEGIN(test_bitmap_initializer) {
#define NB(nbits) { \
if (nbits <= BITMAP_MAXBITS) { \
bitmap_info_t binfo = \
BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_initializer_body(&binfo, nbits); \
} \
#define NB(nbits) \
{ \
if (nbits <= BITMAP_MAXBITS) { \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_initializer_body(&binfo, nbits); \
} \
}
NBITS_TAB
#undef NB
@ -47,11 +51,11 @@ TEST_BEGIN(test_bitmap_initializer) {
TEST_END
static size_t
test_bitmap_size_body(const bitmap_info_t *binfo, size_t nbits,
size_t prev_size) {
test_bitmap_size_body(
const bitmap_info_t *binfo, size_t nbits, size_t prev_size) {
size_t size = bitmap_size(binfo);
expect_zu_ge(size, (nbits >> 3),
"Bitmap size is smaller than expected");
expect_zu_ge(
size, (nbits >> 3), "Bitmap size is smaller than expected");
expect_zu_ge(size, prev_size, "Bitmap size is smaller than expected");
return size;
}
@ -65,10 +69,10 @@ TEST_BEGIN(test_bitmap_size) {
bitmap_info_init(&binfo, nbits);
prev_size = test_bitmap_size_body(&binfo, nbits, prev_size);
}
#define NB(nbits) { \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
prev_size = test_bitmap_size_body(&binfo, nbits, \
prev_size); \
#define NB(nbits) \
{ \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
prev_size = test_bitmap_size_body(&binfo, nbits, prev_size); \
}
prev_size = 0;
NBITS_TAB
@ -78,14 +82,14 @@ TEST_END
static void
test_bitmap_init_body(const bitmap_info_t *binfo, size_t nbits) {
size_t i;
size_t i;
bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
expect_ptr_not_null(bitmap, "Unexpected malloc() failure");
bitmap_init(bitmap, binfo, false);
for (i = 0; i < nbits; i++) {
expect_false(bitmap_get(bitmap, binfo, i),
"Bit should be unset");
expect_false(
bitmap_get(bitmap, binfo, i), "Bit should be unset");
}
bitmap_init(bitmap, binfo, true);
@ -104,9 +108,10 @@ TEST_BEGIN(test_bitmap_init) {
bitmap_info_init(&binfo, nbits);
test_bitmap_init_body(&binfo, nbits);
}
#define NB(nbits) { \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_init_body(&binfo, nbits); \
#define NB(nbits) \
{ \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_init_body(&binfo, nbits); \
}
NBITS_TAB
#undef NB
@ -115,7 +120,7 @@ TEST_END
static void
test_bitmap_set_body(const bitmap_info_t *binfo, size_t nbits) {
size_t i;
size_t i;
bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
expect_ptr_not_null(bitmap, "Unexpected malloc() failure");
bitmap_init(bitmap, binfo, false);
@ -135,9 +140,10 @@ TEST_BEGIN(test_bitmap_set) {
bitmap_info_init(&binfo, nbits);
test_bitmap_set_body(&binfo, nbits);
}
#define NB(nbits) { \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_set_body(&binfo, nbits); \
#define NB(nbits) \
{ \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_set_body(&binfo, nbits); \
}
NBITS_TAB
#undef NB
@ -146,7 +152,7 @@ TEST_END
static void
test_bitmap_unset_body(const bitmap_info_t *binfo, size_t nbits) {
size_t i;
size_t i;
bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
expect_ptr_not_null(bitmap, "Unexpected malloc() failure");
bitmap_init(bitmap, binfo, false);
@ -173,9 +179,10 @@ TEST_BEGIN(test_bitmap_unset) {
bitmap_info_init(&binfo, nbits);
test_bitmap_unset_body(&binfo, nbits);
}
#define NB(nbits) { \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_unset_body(&binfo, nbits); \
#define NB(nbits) \
{ \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_unset_body(&binfo, nbits); \
}
NBITS_TAB
#undef NB
@ -193,7 +200,7 @@ test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
expect_zu_eq(bitmap_ffu(bitmap, binfo, 0), i,
"First unset bit should be just after previous first unset "
"bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i-1 : i), i,
expect_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i - 1 : i), i,
"First unset bit should be just after previous first unset "
"bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
@ -213,7 +220,7 @@ test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
bitmap_unset(bitmap, binfo, i);
expect_zu_eq(bitmap_ffu(bitmap, binfo, 0), i,
"First unset bit should the bit previously unset");
expect_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i-1 : i), i,
expect_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i - 1 : i), i,
"First unset bit should the bit previously unset");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
"First unset bit should the bit previously unset");
@ -232,7 +239,7 @@ test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
expect_zu_eq(bitmap_ffu(bitmap, binfo, 0), i,
"First unset bit should be just after the bit previously "
"set");
expect_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i-1 : i), i,
expect_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i - 1 : i), i,
"First unset bit should be just after the bit previously "
"set");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
@ -245,7 +252,8 @@ test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
}
expect_zu_eq(bitmap_ffu(bitmap, binfo, 0), nbits - 1,
"First unset bit should be the last bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, (nbits > 1) ? nbits-2 : nbits-1),
expect_zu_eq(
bitmap_ffu(bitmap, binfo, (nbits > 1) ? nbits - 2 : nbits - 1),
nbits - 1, "First unset bit should be the last bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, nbits - 1), nbits - 1,
"First unset bit should be the last bit");
@ -258,26 +266,26 @@ test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
* bitmap_ffu() finds the correct bit for all five min_bit cases.
*/
if (nbits >= 3) {
for (size_t i = 0; i < nbits-2; i++) {
for (size_t i = 0; i < nbits - 2; i++) {
bitmap_unset(bitmap, binfo, i);
bitmap_unset(bitmap, binfo, i+2);
bitmap_unset(bitmap, binfo, i + 2);
if (i > 0) {
expect_zu_eq(bitmap_ffu(bitmap, binfo, i-1), i,
"Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i - 1),
i, "Unexpected first unset bit");
}
expect_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
"Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i+1), i+2,
expect_zu_eq(bitmap_ffu(bitmap, binfo, i + 1), i + 2,
"Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i+2), i+2,
expect_zu_eq(bitmap_ffu(bitmap, binfo, i + 2), i + 2,
"Unexpected first unset bit");
if (i + 3 < nbits) {
expect_zu_eq(bitmap_ffu(bitmap, binfo, i+3),
expect_zu_eq(bitmap_ffu(bitmap, binfo, i + 3),
nbits, "Unexpected first unset bit");
}
expect_zu_eq(bitmap_sfu(bitmap, binfo), i,
"Unexpected first unset bit");
expect_zu_eq(bitmap_sfu(bitmap, binfo), i+2,
expect_zu_eq(bitmap_sfu(bitmap, binfo), i + 2,
"Unexpected first unset bit");
}
}
@ -288,24 +296,24 @@ test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
* cases.
*/
if (nbits >= 3) {
bitmap_unset(bitmap, binfo, nbits-1);
for (size_t i = 0; i < nbits-1; i++) {
bitmap_unset(bitmap, binfo, nbits - 1);
for (size_t i = 0; i < nbits - 1; i++) {
bitmap_unset(bitmap, binfo, i);
if (i > 0) {
expect_zu_eq(bitmap_ffu(bitmap, binfo, i-1), i,
"Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i - 1),
i, "Unexpected first unset bit");
}
expect_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
"Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i+1), nbits-1,
"Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, nbits-1),
nbits-1, "Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, i + 1),
nbits - 1, "Unexpected first unset bit");
expect_zu_eq(bitmap_ffu(bitmap, binfo, nbits - 1),
nbits - 1, "Unexpected first unset bit");
expect_zu_eq(bitmap_sfu(bitmap, binfo), i,
"Unexpected first unset bit");
}
expect_zu_eq(bitmap_sfu(bitmap, binfo), nbits-1,
expect_zu_eq(bitmap_sfu(bitmap, binfo), nbits - 1,
"Unexpected first unset bit");
}
@ -322,9 +330,10 @@ TEST_BEGIN(test_bitmap_xfu) {
bitmap_info_init(&binfo, nbits);
test_bitmap_xfu_body(&binfo, nbits);
}
#define NB(nbits) { \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_xfu_body(&binfo, nbits); \
#define NB(nbits) \
{ \
bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
test_bitmap_xfu_body(&binfo, nbits); \
}
NBITS_TAB
#undef NB
@ -333,11 +342,6 @@ TEST_END
int
main(void) {
return test(
test_bitmap_initializer,
test_bitmap_size,
test_bitmap_init,
test_bitmap_set,
test_bitmap_unset,
test_bitmap_xfu);
return test(test_bitmap_initializer, test_bitmap_size, test_bitmap_init,
test_bitmap_set, test_bitmap_unset, test_bitmap_xfu);
}

View file

@ -5,24 +5,24 @@
#define TEST_BUF_SIZE 16
#define UNIT_MAX (TEST_BUF_SIZE * 3)
static size_t test_write_len;
static char test_buf[TEST_BUF_SIZE];
static size_t test_write_len;
static char test_buf[TEST_BUF_SIZE];
static uint64_t arg;
static uint64_t arg_store;
static void
test_write_cb(void *cbopaque, const char *s) {
size_t prev_test_write_len = test_write_len;
test_write_len += strlen(s); /* only increase the length */
test_write_len += strlen(s); /* only increase the length */
arg_store = *(uint64_t *)cbopaque; /* only pass along the argument */
assert_zu_le(prev_test_write_len, test_write_len,
"Test write overflowed");
assert_zu_le(
prev_test_write_len, test_write_len, "Test write overflowed");
}
static void
test_buf_writer_body(tsdn_t *tsdn, buf_writer_t *buf_writer) {
char s[UNIT_MAX + 1];
size_t n_unit, remain, i;
char s[UNIT_MAX + 1];
size_t n_unit, remain, i;
ssize_t unit;
assert(buf_writer->buf != NULL);
@ -41,7 +41,8 @@ test_buf_writer_body(tsdn_t *tsdn, buf_writer_t *buf_writer) {
remain += unit;
if (remain > buf_writer->buf_size) {
/* Flushes should have happened. */
assert_u64_eq(arg_store, arg, "Call "
assert_u64_eq(arg_store, arg,
"Call "
"back argument didn't get through");
remain %= buf_writer->buf_size;
if (remain == 0) {
@ -51,12 +52,14 @@ test_buf_writer_body(tsdn_t *tsdn, buf_writer_t *buf_writer) {
}
assert_zu_eq(test_write_len + remain, i * unit,
"Incorrect length after writing %zu strings"
" of length %zu", i, unit);
" of length %zu",
i, unit);
}
buf_writer_flush(buf_writer);
expect_zu_eq(test_write_len, n_unit * unit,
"Incorrect length after flushing at the end of"
" writing %zu strings of length %zu", n_unit, unit);
" writing %zu strings of length %zu",
n_unit, unit);
}
}
buf_writer_terminate(tsdn, buf_writer);
@ -64,9 +67,9 @@ test_buf_writer_body(tsdn_t *tsdn, buf_writer_t *buf_writer) {
TEST_BEGIN(test_buf_write_static) {
buf_writer_t buf_writer;
tsdn_t *tsdn = tsdn_fetch();
tsdn_t *tsdn = tsdn_fetch();
assert_false(buf_writer_init(tsdn, &buf_writer, test_write_cb, &arg,
test_buf, TEST_BUF_SIZE),
test_buf, TEST_BUF_SIZE),
"buf_writer_init() should not encounter error on static buffer");
test_buf_writer_body(tsdn, &buf_writer);
}
@ -74,22 +77,24 @@ TEST_END
TEST_BEGIN(test_buf_write_dynamic) {
buf_writer_t buf_writer;
tsdn_t *tsdn = tsdn_fetch();
tsdn_t *tsdn = tsdn_fetch();
assert_false(buf_writer_init(tsdn, &buf_writer, test_write_cb, &arg,
NULL, TEST_BUF_SIZE), "buf_writer_init() should not OOM");
NULL, TEST_BUF_SIZE),
"buf_writer_init() should not OOM");
test_buf_writer_body(tsdn, &buf_writer);
}
TEST_END
TEST_BEGIN(test_buf_write_oom) {
buf_writer_t buf_writer;
tsdn_t *tsdn = tsdn_fetch();
tsdn_t *tsdn = tsdn_fetch();
assert_true(buf_writer_init(tsdn, &buf_writer, test_write_cb, &arg,
NULL, SC_LARGE_MAXCLASS + 1), "buf_writer_init() should OOM");
NULL, SC_LARGE_MAXCLASS + 1),
"buf_writer_init() should OOM");
assert(buf_writer.buf == NULL);
char s[UNIT_MAX + 1];
size_t n_unit, i;
char s[UNIT_MAX + 1];
size_t n_unit, i;
ssize_t unit;
memset(s, 'a', UNIT_MAX);
@ -107,20 +112,22 @@ TEST_BEGIN(test_buf_write_oom) {
"Call back argument didn't get through");
assert_zu_eq(test_write_len, i * unit,
"Incorrect length after writing %zu strings"
" of length %zu", i, unit);
" of length %zu",
i, unit);
}
buf_writer_flush(&buf_writer);
expect_zu_eq(test_write_len, n_unit * unit,
"Incorrect length after flushing at the end of"
" writing %zu strings of length %zu", n_unit, unit);
" writing %zu strings of length %zu",
n_unit, unit);
}
}
buf_writer_terminate(tsdn, &buf_writer);
}
TEST_END
static int test_read_count;
static size_t test_read_len;
static int test_read_count;
static size_t test_read_len;
static uint64_t arg_sum;
ssize_t
@ -142,8 +149,8 @@ test_read_cb(void *cbopaque, void *buf, size_t limit) {
memset(buf, 'a', read_len);
size_t prev_test_read_len = test_read_len;
test_read_len += read_len;
assert_zu_le(prev_test_read_len, test_read_len,
"Test read overflowed");
assert_zu_le(
prev_test_read_len, test_read_len, "Test read overflowed");
return read_len;
}
}
@ -168,9 +175,9 @@ test_buf_writer_pipe_body(tsdn_t *tsdn, buf_writer_t *buf_writer) {
TEST_BEGIN(test_buf_write_pipe) {
buf_writer_t buf_writer;
tsdn_t *tsdn = tsdn_fetch();
tsdn_t *tsdn = tsdn_fetch();
assert_false(buf_writer_init(tsdn, &buf_writer, test_write_cb, &arg,
test_buf, TEST_BUF_SIZE),
test_buf, TEST_BUF_SIZE),
"buf_writer_init() should not encounter error on static buffer");
test_buf_writer_pipe_body(tsdn, &buf_writer);
}
@ -178,19 +185,16 @@ TEST_END
TEST_BEGIN(test_buf_write_pipe_oom) {
buf_writer_t buf_writer;
tsdn_t *tsdn = tsdn_fetch();
tsdn_t *tsdn = tsdn_fetch();
assert_true(buf_writer_init(tsdn, &buf_writer, test_write_cb, &arg,
NULL, SC_LARGE_MAXCLASS + 1), "buf_writer_init() should OOM");
NULL, SC_LARGE_MAXCLASS + 1),
"buf_writer_init() should OOM");
test_buf_writer_pipe_body(tsdn, &buf_writer);
}
TEST_END
int
main(void) {
return test(
test_buf_write_static,
test_buf_write_dynamic,
test_buf_write_oom,
test_buf_write_pipe,
test_buf_write_pipe_oom);
return test(test_buf_write_static, test_buf_write_dynamic,
test_buf_write_oom, test_buf_write_pipe, test_buf_write_pipe_oom);
}

View file

@ -3,7 +3,7 @@
static void
do_fill_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t ncached_max,
cache_bin_sz_t nfill_attempt, cache_bin_sz_t nfill_succeed) {
bool success;
bool success;
void *ptr;
assert_true(cache_bin_ncached_get_local(bin) == 0, "");
CACHE_BIN_PTR_ARRAY_DECLARE(arr, nfill_attempt);
@ -12,17 +12,16 @@ do_fill_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t ncached_max,
arr.ptr[i] = &ptrs[i];
}
cache_bin_finish_fill(bin, &arr, nfill_succeed);
expect_true(cache_bin_ncached_get_local(bin) == nfill_succeed,
"");
expect_true(cache_bin_ncached_get_local(bin) == nfill_succeed, "");
cache_bin_low_water_set(bin);
for (cache_bin_sz_t i = 0; i < nfill_succeed; i++) {
ptr = cache_bin_alloc(bin, &success);
expect_true(success, "");
expect_ptr_eq(ptr, (void *)&ptrs[i],
"Should pop in order filled");
expect_true(cache_bin_low_water_get(bin)
== nfill_succeed - i - 1, "");
expect_ptr_eq(
ptr, (void *)&ptrs[i], "Should pop in order filled");
expect_true(
cache_bin_low_water_get(bin) == nfill_succeed - i - 1, "");
}
expect_true(cache_bin_ncached_get_local(bin) == 0, "");
expect_true(cache_bin_low_water_get(bin) == 0, "");
@ -46,16 +45,15 @@ do_flush_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
}
cache_bin_finish_flush(bin, &arr, nflush);
expect_true(cache_bin_ncached_get_local(bin) == nfill - nflush,
"");
expect_true(cache_bin_ncached_get_local(bin) == nfill - nflush, "");
while (cache_bin_ncached_get_local(bin) > 0) {
cache_bin_alloc(bin, &success);
}
}
static void
do_batch_alloc_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
size_t batch) {
do_batch_alloc_test(
cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill, size_t batch) {
assert_true(cache_bin_ncached_get_local(bin) == 0, "");
CACHE_BIN_PTR_ARRAY_DECLARE(arr, nfill);
cache_bin_init_ptr_array_for_fill(bin, &arr, nfill);
@ -72,8 +70,8 @@ do_batch_alloc_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
for (cache_bin_sz_t i = 0; i < (cache_bin_sz_t)n; i++) {
expect_ptr_eq(out[i], &ptrs[i], "");
}
expect_true(cache_bin_low_water_get(bin) == nfill -
(cache_bin_sz_t)n, "");
expect_true(
cache_bin_low_water_get(bin) == nfill - (cache_bin_sz_t)n, "");
while (cache_bin_ncached_get_local(bin) > 0) {
bool success;
cache_bin_alloc(bin, &success);
@ -98,8 +96,8 @@ test_bin_init(cache_bin_t *bin, cache_bin_info_t *info) {
TEST_BEGIN(test_cache_bin) {
const int ncached_max = 100;
bool success;
void *ptr;
bool success;
void *ptr;
cache_bin_info_t info;
cache_bin_info_init(&info, ncached_max);
@ -125,7 +123,7 @@ TEST_BEGIN(test_cache_bin) {
*/
void **ptrs = mallocx(sizeof(void *) * (ncached_max + 1), 0);
assert_ptr_not_null(ptrs, "Unexpected mallocx failure");
for (cache_bin_sz_t i = 0; i < ncached_max; i++) {
for (cache_bin_sz_t i = 0; i < ncached_max; i++) {
expect_true(cache_bin_ncached_get_local(&bin) == i, "");
success = cache_bin_dalloc_easy(&bin, &ptrs[i]);
expect_true(success,
@ -133,18 +131,17 @@ TEST_BEGIN(test_cache_bin) {
expect_true(cache_bin_low_water_get(&bin) == 0,
"Pushes and pops shouldn't change low water of zero.");
}
expect_true(cache_bin_ncached_get_local(&bin) == ncached_max,
"");
expect_true(cache_bin_ncached_get_local(&bin) == ncached_max, "");
success = cache_bin_dalloc_easy(&bin, &ptrs[ncached_max]);
expect_false(success, "Shouldn't be able to dalloc into a full bin.");
cache_bin_low_water_set(&bin);
for (cache_bin_sz_t i = 0; i < ncached_max; i++) {
expect_true(cache_bin_low_water_get(&bin)
== ncached_max - i, "");
expect_true(cache_bin_ncached_get_local(&bin)
== ncached_max - i, "");
expect_true(
cache_bin_low_water_get(&bin) == ncached_max - i, "");
expect_true(
cache_bin_ncached_get_local(&bin) == ncached_max - i, "");
/*
* This should fail -- the easy variant can't change the low
* water mark.
@ -152,20 +149,21 @@ TEST_BEGIN(test_cache_bin) {
ptr = cache_bin_alloc_easy(&bin, &success);
expect_ptr_null(ptr, "");
expect_false(success, "");
expect_true(cache_bin_low_water_get(&bin)
== ncached_max - i, "");
expect_true(cache_bin_ncached_get_local(&bin)
== ncached_max - i, "");
expect_true(
cache_bin_low_water_get(&bin) == ncached_max - i, "");
expect_true(
cache_bin_ncached_get_local(&bin) == ncached_max - i, "");
/* This should succeed, though. */
ptr = cache_bin_alloc(&bin, &success);
expect_true(success, "");
expect_ptr_eq(ptr, &ptrs[ncached_max - i - 1],
"Alloc should pop in stack order");
expect_true(cache_bin_low_water_get(&bin)
== ncached_max - i - 1, "");
expect_true(cache_bin_ncached_get_local(&bin)
== ncached_max - i - 1, "");
expect_true(
cache_bin_low_water_get(&bin) == ncached_max - i - 1, "");
expect_true(
cache_bin_ncached_get_local(&bin) == ncached_max - i - 1,
"");
}
/* Now we're empty -- all alloc attempts should fail. */
expect_true(cache_bin_ncached_get_local(&bin) == 0, "");
@ -184,8 +182,7 @@ TEST_BEGIN(test_cache_bin) {
for (cache_bin_sz_t i = ncached_max / 2; i < ncached_max; i++) {
cache_bin_dalloc_easy(&bin, &ptrs[i]);
}
expect_true(cache_bin_ncached_get_local(&bin) == ncached_max,
"");
expect_true(cache_bin_ncached_get_local(&bin) == ncached_max, "");
for (cache_bin_sz_t i = ncached_max - 1; i >= ncached_max / 2; i--) {
/*
* Size is bigger than low water -- the reduced version should
@ -208,20 +205,16 @@ TEST_BEGIN(test_cache_bin) {
/* Test fill. */
/* Try to fill all, succeed fully. */
do_fill_test(&bin, ptrs, ncached_max, ncached_max,
ncached_max);
do_fill_test(&bin, ptrs, ncached_max, ncached_max, ncached_max);
/* Try to fill all, succeed partially. */
do_fill_test(&bin, ptrs, ncached_max, ncached_max,
ncached_max / 2);
do_fill_test(&bin, ptrs, ncached_max, ncached_max, ncached_max / 2);
/* Try to fill all, fail completely. */
do_fill_test(&bin, ptrs, ncached_max, ncached_max, 0);
/* Try to fill some, succeed fully. */
do_fill_test(&bin, ptrs, ncached_max, ncached_max / 2,
ncached_max / 2);
do_fill_test(&bin, ptrs, ncached_max, ncached_max / 2, ncached_max / 2);
/* Try to fill some, succeed partially. */
do_fill_test(&bin, ptrs, ncached_max, ncached_max / 2,
ncached_max / 4);
do_fill_test(&bin, ptrs, ncached_max, ncached_max / 2, ncached_max / 4);
/* Try to fill some, fail completely. */
do_fill_test(&bin, ptrs, ncached_max, ncached_max / 2, 0);
@ -262,11 +255,10 @@ TEST_END
static void
do_flush_stashed_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
cache_bin_sz_t nstash) {
expect_true(cache_bin_ncached_get_local(bin) == 0,
"Bin not empty");
expect_true(cache_bin_nstashed_get_local(bin) == 0,
"Bin not empty");
expect_true(nfill + nstash <= bin->bin_info.ncached_max, "Exceeded max");
expect_true(cache_bin_ncached_get_local(bin) == 0, "Bin not empty");
expect_true(cache_bin_nstashed_get_local(bin) == 0, "Bin not empty");
expect_true(
nfill + nstash <= bin->bin_info.ncached_max, "Exceeded max");
bool ret;
/* Fill */
@ -274,16 +266,16 @@ do_flush_stashed_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
ret = cache_bin_dalloc_easy(bin, &ptrs[i]);
expect_true(ret, "Unexpected fill failure");
}
expect_true(cache_bin_ncached_get_local(bin) == nfill,
"Wrong cached count");
expect_true(
cache_bin_ncached_get_local(bin) == nfill, "Wrong cached count");
/* Stash */
for (cache_bin_sz_t i = 0; i < nstash; i++) {
ret = cache_bin_stash(bin, &ptrs[i + nfill]);
expect_true(ret, "Unexpected stash failure");
}
expect_true(cache_bin_nstashed_get_local(bin) == nstash,
"Wrong stashed count");
expect_true(
cache_bin_nstashed_get_local(bin) == nstash, "Wrong stashed count");
if (nfill + nstash == bin->bin_info.ncached_max) {
ret = cache_bin_dalloc_easy(bin, &ptrs[0]);
@ -300,20 +292,20 @@ do_flush_stashed_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
expect_true((uintptr_t)ptr < (uintptr_t)&ptrs[nfill],
"Should not alloc stashed ptrs");
}
expect_true(cache_bin_ncached_get_local(bin) == 0,
"Wrong cached count");
expect_true(cache_bin_nstashed_get_local(bin) == nstash,
"Wrong stashed count");
expect_true(
cache_bin_ncached_get_local(bin) == 0, "Wrong cached count");
expect_true(
cache_bin_nstashed_get_local(bin) == nstash, "Wrong stashed count");
cache_bin_alloc(bin, &ret);
expect_false(ret, "Should not alloc stashed");
/* Clear stashed ones */
cache_bin_finish_flush_stashed(bin);
expect_true(cache_bin_ncached_get_local(bin) == 0,
"Wrong cached count");
expect_true(cache_bin_nstashed_get_local(bin) == 0,
"Wrong stashed count");
expect_true(
cache_bin_ncached_get_local(bin) == 0, "Wrong cached count");
expect_true(
cache_bin_nstashed_get_local(bin) == 0, "Wrong stashed count");
cache_bin_alloc(bin, &ret);
expect_false(ret, "Should not alloc from empty bin");
@ -322,7 +314,7 @@ do_flush_stashed_test(cache_bin_t *bin, void **ptrs, cache_bin_sz_t nfill,
TEST_BEGIN(test_cache_bin_stash) {
const int ncached_max = 100;
cache_bin_t bin;
cache_bin_t bin;
cache_bin_info_t info;
cache_bin_info_init(&info, ncached_max);
test_bin_init(&bin, &info);
@ -335,15 +327,17 @@ TEST_BEGIN(test_cache_bin_stash) {
assert_ptr_not_null(ptrs, "Unexpected mallocx failure");
bool ret;
for (cache_bin_sz_t i = 0; i < ncached_max; i++) {
expect_true(cache_bin_ncached_get_local(&bin) ==
(i / 2 + i % 2), "Wrong ncached value");
expect_true(cache_bin_nstashed_get_local(&bin) ==
i / 2, "Wrong nstashed value");
expect_true(
cache_bin_ncached_get_local(&bin) == (i / 2 + i % 2),
"Wrong ncached value");
expect_true(cache_bin_nstashed_get_local(&bin) == i / 2,
"Wrong nstashed value");
if (i % 2 == 0) {
cache_bin_dalloc_easy(&bin, &ptrs[i]);
} else {
ret = cache_bin_stash(&bin, &ptrs[i]);
expect_true(ret, "Should be able to stash into a "
expect_true(ret,
"Should be able to stash into a "
"non-full cache bin");
}
}
@ -360,7 +354,8 @@ TEST_BEGIN(test_cache_bin_stash) {
expect_true(diff % 2 == 0, "Should be able to alloc");
} else {
expect_false(ret, "Should not alloc stashed");
expect_true(cache_bin_nstashed_get_local(&bin) == ncached_max / 2,
expect_true(cache_bin_nstashed_get_local(&bin)
== ncached_max / 2,
"Wrong nstashed value");
}
}
@ -368,19 +363,14 @@ TEST_BEGIN(test_cache_bin_stash) {
test_bin_init(&bin, &info);
do_flush_stashed_test(&bin, ptrs, ncached_max, 0);
do_flush_stashed_test(&bin, ptrs, 0, ncached_max);
do_flush_stashed_test(&bin, ptrs, ncached_max / 2,
ncached_max / 2);
do_flush_stashed_test(&bin, ptrs, ncached_max / 4,
ncached_max / 2);
do_flush_stashed_test(&bin, ptrs, ncached_max / 2,
ncached_max / 4);
do_flush_stashed_test(&bin, ptrs, ncached_max / 4,
ncached_max / 4);
do_flush_stashed_test(&bin, ptrs, ncached_max / 2, ncached_max / 2);
do_flush_stashed_test(&bin, ptrs, ncached_max / 4, ncached_max / 2);
do_flush_stashed_test(&bin, ptrs, ncached_max / 2, ncached_max / 4);
do_flush_stashed_test(&bin, ptrs, ncached_max / 4, ncached_max / 4);
}
TEST_END
int
main(void) {
return test(test_cache_bin,
test_cache_bin_stash);
return test(test_cache_bin, test_cache_bin_stash);
}

View file

@ -2,55 +2,51 @@
TEST_BEGIN(test_new_delete) {
tsd_t *tsd;
ckh_t ckh;
ckh_t ckh;
tsd = tsd_fetch();
expect_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
ckh_string_keycomp), "Unexpected ckh_new() error");
expect_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp),
"Unexpected ckh_new() error");
ckh_delete(tsd, &ckh);
expect_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash,
ckh_pointer_keycomp), "Unexpected ckh_new() error");
expect_false(
ckh_new(tsd, &ckh, 3, ckh_pointer_hash, ckh_pointer_keycomp),
"Unexpected ckh_new() error");
ckh_delete(tsd, &ckh);
}
TEST_END
TEST_BEGIN(test_count_insert_search_remove) {
tsd_t *tsd;
ckh_t ckh;
const char *strs[] = {
"a string",
"A string",
"a string.",
"A string."
};
tsd_t *tsd;
ckh_t ckh;
const char *strs[] = {"a string", "A string", "a string.", "A string."};
const char *missing = "A string not in the hash table.";
size_t i;
size_t i;
tsd = tsd_fetch();
expect_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
ckh_string_keycomp), "Unexpected ckh_new() error");
expect_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp),
"Unexpected ckh_new() error");
expect_zu_eq(ckh_count(&ckh), 0,
"ckh_count() should return %zu, but it returned %zu", ZU(0),
ckh_count(&ckh));
/* Insert. */
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
for (i = 0; i < sizeof(strs) / sizeof(const char *); i++) {
ckh_insert(tsd, &ckh, strs[i], strs[i]);
expect_zu_eq(ckh_count(&ckh), i+1,
"ckh_count() should return %zu, but it returned %zu", i+1,
expect_zu_eq(ckh_count(&ckh), i + 1,
"ckh_count() should return %zu, but it returned %zu", i + 1,
ckh_count(&ckh));
}
/* Search. */
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
for (i = 0; i < sizeof(strs) / sizeof(const char *); i++) {
union {
void *p;
void *p;
const char *s;
} k, v;
void **kp, **vp;
void **kp, **vp;
const char *ks, *vs;
kp = (i & 1) ? &k.p : NULL;
@ -62,21 +58,21 @@ TEST_BEGIN(test_count_insert_search_remove) {
ks = (i & 1) ? strs[i] : (const char *)NULL;
vs = (i & 2) ? strs[i] : (const char *)NULL;
expect_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu",
i);
expect_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu",
i);
expect_ptr_eq(
(void *)ks, (void *)k.s, "Key mismatch, i=%zu", i);
expect_ptr_eq(
(void *)vs, (void *)v.s, "Value mismatch, i=%zu", i);
}
expect_true(ckh_search(&ckh, missing, NULL, NULL),
"Unexpected ckh_search() success");
/* Remove. */
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
for (i = 0; i < sizeof(strs) / sizeof(const char *); i++) {
union {
void *p;
void *p;
const char *s;
} k, v;
void **kp, **vp;
void **kp, **vp;
const char *ks, *vs;
kp = (i & 1) ? &k.p : NULL;
@ -88,14 +84,14 @@ TEST_BEGIN(test_count_insert_search_remove) {
ks = (i & 1) ? strs[i] : (const char *)NULL;
vs = (i & 2) ? strs[i] : (const char *)NULL;
expect_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu",
i);
expect_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu",
i);
expect_ptr_eq(
(void *)ks, (void *)k.s, "Key mismatch, i=%zu", i);
expect_ptr_eq(
(void *)vs, (void *)v.s, "Value mismatch, i=%zu", i);
expect_zu_eq(ckh_count(&ckh),
sizeof(strs)/sizeof(const char *) - i - 1,
sizeof(strs) / sizeof(const char *) - i - 1,
"ckh_count() should return %zu, but it returned %zu",
sizeof(strs)/sizeof(const char *) - i - 1,
sizeof(strs) / sizeof(const char *) - i - 1,
ckh_count(&ckh));
}
@ -106,18 +102,19 @@ TEST_END
TEST_BEGIN(test_insert_iter_remove) {
#define NITEMS ZU(1000)
tsd_t *tsd;
ckh_t ckh;
ckh_t ckh;
void **p[NITEMS];
void *q, *r;
void *q, *r;
size_t i;
tsd = tsd_fetch();
expect_false(ckh_new(tsd, &ckh, 2, ckh_pointer_hash,
ckh_pointer_keycomp), "Unexpected ckh_new() error");
expect_false(
ckh_new(tsd, &ckh, 2, ckh_pointer_hash, ckh_pointer_keycomp),
"Unexpected ckh_new() error");
for (i = 0; i < NITEMS; i++) {
p[i] = mallocx(i+1, 0);
p[i] = mallocx(i + 1, 0);
expect_ptr_not_null(p[i], "Unexpected mallocx() failure");
}
@ -151,7 +148,7 @@ TEST_BEGIN(test_insert_iter_remove) {
}
{
bool seen[NITEMS];
bool seen[NITEMS];
size_t tabind;
memset(seen, 0, sizeof(seen));
@ -195,8 +192,8 @@ TEST_BEGIN(test_insert_iter_remove) {
}
expect_zu_eq(ckh_count(&ckh), 0,
"ckh_count() should return %zu, but it returned %zu",
ZU(0), ckh_count(&ckh));
"ckh_count() should return %zu, but it returned %zu", ZU(0),
ckh_count(&ckh));
ckh_delete(tsd, &ckh);
#undef NITEMS
}
@ -204,8 +201,6 @@ TEST_END
int
main(void) {
return test(
test_new_delete,
test_count_insert_search_remove,
return test(test_new_delete, test_count_insert_search_remove,
test_insert_iter_remove);
}

View file

@ -11,7 +11,7 @@ TEST_BEGIN(test_counter_accum) {
counter_accum_init(&c, interval);
tsd_t *tsd = tsd_fetch();
bool trigger;
bool trigger;
for (unsigned i = 0; i < n; i++) {
trigger = counter_accum(tsd_tsdn(tsd), &c, increment);
accum += increment;
@ -39,8 +39,8 @@ static void *
thd_start(void *varg) {
counter_accum_t *c = (counter_accum_t *)varg;
tsd_t *tsd = tsd_fetch();
bool trigger;
tsd_t *tsd = tsd_fetch();
bool trigger;
uintptr_t n_triggered = 0;
for (unsigned i = 0; i < N_ITER_THD; i++) {
trigger = counter_accum(tsd_tsdn(tsd), c, ITER_INCREMENT);
@ -50,12 +50,11 @@ thd_start(void *varg) {
return (void *)n_triggered;
}
TEST_BEGIN(test_counter_mt) {
counter_accum_t shared_c;
counter_accum_init(&shared_c, interval);
thd_t thds[N_THDS];
thd_t thds[N_THDS];
unsigned i;
for (i = 0; i < N_THDS; i++) {
thd_create(&thds[i], thd_start, (void *)&shared_c);
@ -74,7 +73,5 @@ TEST_END
int
main(void) {
return test(
test_counter_accum,
test_counter_mt);
return test(test_counter_accum, test_counter_mt);
}

View file

@ -22,12 +22,11 @@ TEST_BEGIN(test_decay_init) {
TEST_END
TEST_BEGIN(test_decay_ms_valid) {
expect_false(decay_ms_valid(-7),
"Misclassified negative decay as valid");
expect_false(
decay_ms_valid(-7), "Misclassified negative decay as valid");
expect_true(decay_ms_valid(-1),
"Misclassified -1 (never decay) as invalid decay");
expect_true(decay_ms_valid(8943),
"Misclassified valid decay");
expect_true(decay_ms_valid(8943), "Misclassified valid decay");
if (SSIZE_MAX > NSTIME_SEC_MAX) {
expect_false(
decay_ms_valid((ssize_t)(NSTIME_SEC_MAX * KQU(1000) + 39)),
@ -111,12 +110,12 @@ TEST_BEGIN(test_decay_empty) {
assert_false(err, "");
uint64_t time_between_calls = decay_epoch_duration_ns(&decay) / 5;
int nepochs = 0;
int nepochs = 0;
for (uint64_t i = 0; i < decay_ns / time_between_calls * 10; i++) {
size_t dirty_pages = 0;
nstime_init(&curtime, i * time_between_calls);
bool epoch_advanced = decay_maybe_advance_epoch(&decay,
&curtime, dirty_pages);
bool epoch_advanced = decay_maybe_advance_epoch(
&decay, &curtime, dirty_pages);
if (epoch_advanced) {
nepochs++;
expect_zu_eq(decay_npages_limit_get(&decay), 0,
@ -158,30 +157,32 @@ TEST_BEGIN(test_decay) {
nstime_init(&epochtime, decay_epoch_duration_ns(&decay));
const size_t dirty_pages_per_epoch = 1000;
size_t dirty_pages = 0;
uint64_t epoch_ns = decay_epoch_duration_ns(&decay);
bool epoch_advanced = false;
size_t dirty_pages = 0;
uint64_t epoch_ns = decay_epoch_duration_ns(&decay);
bool epoch_advanced = false;
/* Populate backlog with some dirty pages */
for (uint64_t i = 0; i < nepoch_init; i++) {
nstime_add(&curtime, &epochtime);
dirty_pages += dirty_pages_per_epoch;
epoch_advanced |= decay_maybe_advance_epoch(&decay, &curtime,
dirty_pages);
epoch_advanced |= decay_maybe_advance_epoch(
&decay, &curtime, dirty_pages);
}
expect_true(epoch_advanced, "Epoch never advanced");
size_t npages_limit = decay_npages_limit_get(&decay);
expect_zu_gt(npages_limit, 0, "npages_limit is incorrectly equal "
expect_zu_gt(npages_limit, 0,
"npages_limit is incorrectly equal "
"to zero after dirty pages have been added");
/* Keep dirty pages unchanged and verify that npages_limit decreases */
for (uint64_t i = nepoch_init; i * epoch_ns < decay_ns; ++i) {
nstime_add(&curtime, &epochtime);
epoch_advanced = decay_maybe_advance_epoch(&decay, &curtime,
dirty_pages);
epoch_advanced = decay_maybe_advance_epoch(
&decay, &curtime, dirty_pages);
if (epoch_advanced) {
size_t npages_limit_new = decay_npages_limit_get(&decay);
size_t npages_limit_new = decay_npages_limit_get(
&decay);
expect_zu_lt(npages_limit_new, npages_limit,
"napges_limit failed to decay");
@ -189,20 +190,22 @@ TEST_BEGIN(test_decay) {
}
}
expect_zu_gt(npages_limit, 0, "npages_limit decayed to zero earlier "
expect_zu_gt(npages_limit, 0,
"npages_limit decayed to zero earlier "
"than decay_ms since last dirty page was added");
/* Completely push all dirty pages out of the backlog */
epoch_advanced = false;
for (uint64_t i = 0; i < nepoch_init; i++) {
nstime_add(&curtime, &epochtime);
epoch_advanced |= decay_maybe_advance_epoch(&decay, &curtime,
dirty_pages);
epoch_advanced |= decay_maybe_advance_epoch(
&decay, &curtime, dirty_pages);
}
expect_true(epoch_advanced, "Epoch never advanced");
npages_limit = decay_npages_limit_get(&decay);
expect_zu_eq(npages_limit, 0, "npages_limit didn't decay to 0 after "
expect_zu_eq(npages_limit, 0,
"npages_limit didn't decay to 0 after "
"decay_ms since last bump in dirty pages");
}
TEST_END
@ -230,29 +233,29 @@ TEST_BEGIN(test_decay_ns_until_purge) {
"Failed to return unbounded wait time for zero threshold");
const size_t dirty_pages_per_epoch = 1000;
size_t dirty_pages = 0;
bool epoch_advanced = false;
size_t dirty_pages = 0;
bool epoch_advanced = false;
for (uint64_t i = 0; i < nepoch_init; i++) {
nstime_add(&curtime, &epochtime);
dirty_pages += dirty_pages_per_epoch;
epoch_advanced |= decay_maybe_advance_epoch(&decay, &curtime,
dirty_pages);
epoch_advanced |= decay_maybe_advance_epoch(
&decay, &curtime, dirty_pages);
}
expect_true(epoch_advanced, "Epoch never advanced");
uint64_t ns_until_purge_all = decay_ns_until_purge(&decay,
dirty_pages, dirty_pages);
uint64_t ns_until_purge_all = decay_ns_until_purge(
&decay, dirty_pages, dirty_pages);
expect_u64_ge(ns_until_purge_all, decay_ns,
"Incorrectly calculated time to purge all pages");
uint64_t ns_until_purge_none = decay_ns_until_purge(&decay,
dirty_pages, 0);
uint64_t ns_until_purge_none = decay_ns_until_purge(
&decay, dirty_pages, 0);
expect_u64_eq(ns_until_purge_none, decay_epoch_duration_ns(&decay) * 2,
"Incorrectly calculated time to purge 0 pages");
uint64_t npages_threshold = dirty_pages / 2;
uint64_t ns_until_purge_half = decay_ns_until_purge(&decay,
dirty_pages, npages_threshold);
uint64_t ns_until_purge_half = decay_ns_until_purge(
&decay, dirty_pages, npages_threshold);
nstime_t waittime;
nstime_init(&waittime, ns_until_purge_half);
@ -263,7 +266,7 @@ TEST_BEGIN(test_decay_ns_until_purge) {
expect_zu_lt(npages_limit, dirty_pages,
"npages_limit failed to decrease after waiting");
size_t expected = dirty_pages - npages_limit;
int deviation = abs((int)expected - (int)(npages_threshold));
int deviation = abs((int)expected - (int)(npages_threshold));
expect_d_lt(deviation, (int)(npages_threshold / 2),
"After waiting, number of pages is out of the expected interval "
"[0.5 * npages_threshold .. 1.5 * npages_threshold]");
@ -272,12 +275,7 @@ TEST_END
int
main(void) {
return test(
test_decay_init,
test_decay_ms_valid,
test_decay_npages_purge_in,
test_decay_maybe_advance_epoch,
test_decay_empty,
test_decay,
test_decay_ns_until_purge);
return test(test_decay_init, test_decay_ms_valid,
test_decay_npages_purge_in, test_decay_maybe_advance_epoch,
test_decay_empty, test_decay, test_decay_ns_until_purge);
}

View file

@ -11,12 +11,12 @@ TEST_BEGIN(test_div_exhaustive) {
max = 1000 * 1000;
}
for (size_t dividend = 0; dividend < 1000 * divisor;
dividend += divisor) {
size_t quotient = div_compute(
&div_info, dividend);
dividend += divisor) {
size_t quotient = div_compute(&div_info, dividend);
expect_zu_eq(dividend, quotient * divisor,
"With divisor = %zu, dividend = %zu, "
"got quotient %zu", divisor, dividend, quotient);
"got quotient %zu",
divisor, dividend, quotient);
}
}
}
@ -24,6 +24,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_div_exhaustive);
return test_no_reentrancy(test_div_exhaustive);
}

View file

@ -4,7 +4,8 @@
#include "jemalloc/internal/safety_check.h"
bool fake_abort_called;
void fake_abort(const char *message) {
void
fake_abort(const char *message) {
(void)message;
fake_abort_called = true;
}
@ -23,10 +24,9 @@ test_double_free_post(void) {
static bool
tcache_enabled(void) {
bool enabled;
bool enabled;
size_t sz = sizeof(enabled);
assert_d_eq(
mallctl("thread.tcache.enabled", &enabled, &sz, NULL, 0), 0,
assert_d_eq(mallctl("thread.tcache.enabled", &enabled, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
return enabled;
}
@ -41,7 +41,7 @@ TEST_BEGIN(test_large_double_free_tcache) {
test_double_free_pre();
char *ptr = malloc(SC_LARGE_MINCLASS);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
free(ptr);
if (!guarded) {
free(ptr);
@ -64,7 +64,7 @@ TEST_BEGIN(test_large_double_free_no_tcache) {
test_double_free_pre();
char *ptr = mallocx(SC_LARGE_MINCLASS, MALLOCX_TCACHE_NONE);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
dallocx(ptr, MALLOCX_TCACHE_NONE);
if (!guarded) {
dallocx(ptr, MALLOCX_TCACHE_NONE);
@ -87,7 +87,7 @@ TEST_BEGIN(test_small_double_free_tcache) {
test_double_free_pre();
char *ptr = malloc(1);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
free(ptr);
if (!guarded) {
free(ptr);
@ -115,7 +115,7 @@ TEST_BEGIN(test_small_double_free_arena) {
*/
char *ptr1 = malloc(1);
char *ptr = malloc(1);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
bool guarded = extent_is_guarded(tsdn_fetch(), ptr);
free(ptr);
if (!guarded) {
mallctl("thread.tcache.flush", NULL, NULL, NULL, 0);
@ -135,9 +135,7 @@ TEST_END
int
main(void) {
return test(
test_large_double_free_no_tcache,
test_large_double_free_tcache,
test_small_double_free_tcache,
return test(test_large_double_free_no_tcache,
test_large_double_free_tcache, test_small_double_free_tcache,
test_small_double_free_arena);
}

View file

@ -49,16 +49,16 @@ TEST_END
static size_t
ecf_count(edata_cache_fast_t *ecf) {
size_t count = 0;
size_t count = 0;
edata_t *cur;
ql_foreach(cur, &ecf->list.head, ql_link_inactive) {
ql_foreach (cur, &ecf->list.head, ql_link_inactive) {
count++;
}
return count;
}
TEST_BEGIN(test_edata_cache_fast_simple) {
edata_cache_t ec;
edata_cache_t ec;
edata_cache_fast_t ecf;
test_edata_cache_init(&ec);
@ -96,7 +96,7 @@ TEST_BEGIN(test_edata_cache_fast_simple) {
TEST_END
TEST_BEGIN(test_edata_cache_fill) {
edata_cache_t ec;
edata_cache_t ec;
edata_cache_fast_t ecf;
test_edata_cache_init(&ec);
@ -179,7 +179,7 @@ TEST_BEGIN(test_edata_cache_fill) {
TEST_END
TEST_BEGIN(test_edata_cache_disable) {
edata_cache_t ec;
edata_cache_t ec;
edata_cache_fast_t ecf;
test_edata_cache_init(&ec);
@ -198,7 +198,8 @@ TEST_BEGIN(test_edata_cache_disable) {
expect_zu_eq(0, ecf_count(&ecf), "");
expect_zu_eq(EDATA_CACHE_FAST_FILL,
atomic_load_zu(&ec.count, ATOMIC_RELAXED), "Disabling should flush");
atomic_load_zu(&ec.count, ATOMIC_RELAXED),
"Disabling should flush");
edata_t *edata = edata_cache_fast_get(TSDN_NULL, &ecf);
expect_zu_eq(0, ecf_count(&ecf), "");
@ -218,9 +219,6 @@ TEST_END
int
main(void) {
return test(
test_edata_cache,
test_edata_cache_fast_simple,
test_edata_cache_fill,
test_edata_cache_disable);
return test(test_edata_cache, test_edata_cache_fast_simple,
test_edata_cache_fill, test_edata_cache_disable);
}

View file

@ -12,9 +12,9 @@ static bool print_escaped = false;
typedef struct buf_descriptor_s buf_descriptor_t;
struct buf_descriptor_s {
char *buf;
char *buf;
size_t len;
bool mid_quote;
bool mid_quote;
};
/*
@ -56,8 +56,8 @@ forwarding_cb(void *buf_descriptor_v, const char *str) {
}
}
size_t written = malloc_snprintf(buf_descriptor->buf,
buf_descriptor->len, "%s", str);
size_t written = malloc_snprintf(
buf_descriptor->buf, buf_descriptor->len, "%s", str);
expect_zu_eq(written, strlen(str), "Buffer overflow!");
buf_descriptor->buf += written;
buf_descriptor->len -= written;
@ -66,19 +66,18 @@ forwarding_cb(void *buf_descriptor_v, const char *str) {
static void
expect_emit_output(void (*emit_fn)(emitter_t *),
const char *expected_json_output,
const char *expected_json_compact_output,
const char *expected_json_output, const char *expected_json_compact_output,
const char *expected_table_output) {
emitter_t emitter;
char buf[MALLOC_PRINTF_BUFSIZE];
emitter_t emitter;
char buf[MALLOC_PRINTF_BUFSIZE];
buf_descriptor_t buf_descriptor;
buf_descriptor.buf = buf;
buf_descriptor.len = MALLOC_PRINTF_BUFSIZE;
buf_descriptor.mid_quote = false;
emitter_init(&emitter, emitter_output_json, &forwarding_cb,
&buf_descriptor);
emitter_init(
&emitter, emitter_output_json, &forwarding_cb, &buf_descriptor);
(*emit_fn)(&emitter);
expect_str_eq(expected_json_output, buf, "json output failure");
@ -89,24 +88,24 @@ expect_emit_output(void (*emit_fn)(emitter_t *),
emitter_init(&emitter, emitter_output_json_compact, &forwarding_cb,
&buf_descriptor);
(*emit_fn)(&emitter);
expect_str_eq(expected_json_compact_output, buf,
"compact json output failure");
expect_str_eq(
expected_json_compact_output, buf, "compact json output failure");
buf_descriptor.buf = buf;
buf_descriptor.len = MALLOC_PRINTF_BUFSIZE;
buf_descriptor.mid_quote = false;
emitter_init(&emitter, emitter_output_table, &forwarding_cb,
&buf_descriptor);
emitter_init(
&emitter, emitter_output_table, &forwarding_cb, &buf_descriptor);
(*emit_fn)(&emitter);
expect_str_eq(expected_table_output, buf, "table output failure");
}
static void
emit_dict(emitter_t *emitter) {
bool b_false = false;
bool b_true = true;
int i_123 = 123;
bool b_false = false;
bool b_true = true;
int i_123 = 123;
const char *str = "a string";
emitter_begin(emitter);
@ -122,48 +121,49 @@ emit_dict(emitter_t *emitter) {
}
static const char *dict_json =
"{\n"
"\t\"foo\": {\n"
"\t\t\"abc\": false,\n"
"\t\t\"def\": true,\n"
"\t\t\"ghi\": 123,\n"
"\t\t\"jkl\": \"a string\"\n"
"\t}\n"
"}\n";
"{\n"
"\t\"foo\": {\n"
"\t\t\"abc\": false,\n"
"\t\t\"def\": true,\n"
"\t\t\"ghi\": 123,\n"
"\t\t\"jkl\": \"a string\"\n"
"\t}\n"
"}\n";
static const char *dict_json_compact =
"{"
"\"foo\":{"
"\"abc\":false,"
"\"def\":true,"
"\"ghi\":123,"
"\"jkl\":\"a string\""
"}"
"}";
"{"
"\"foo\":{"
"\"abc\":false,"
"\"def\":true,"
"\"ghi\":123,"
"\"jkl\":\"a string\""
"}"
"}";
static const char *dict_table =
"This is the foo table:\n"
" ABC: false\n"
" DEF: true\n"
" GHI: 123 (note_key1: \"a string\")\n"
" JKL: \"a string\" (note_key2: false)\n";
"This is the foo table:\n"
" ABC: false\n"
" DEF: true\n"
" GHI: 123 (note_key1: \"a string\")\n"
" JKL: \"a string\" (note_key2: false)\n";
static void
emit_table_printf(emitter_t *emitter) {
emitter_begin(emitter);
emitter_table_printf(emitter, "Table note 1\n");
emitter_table_printf(emitter, "Table note 2 %s\n",
"with format string");
emitter_table_printf(
emitter, "Table note 2 %s\n", "with format string");
emitter_end(emitter);
}
static const char *table_printf_json =
"{\n"
"}\n";
"{\n"
"}\n";
static const char *table_printf_json_compact = "{}";
static const char *table_printf_table =
"Table note 1\n"
"Table note 2 with format string\n";
"Table note 1\n"
"Table note 2 with format string\n";
static void emit_nested_dict(emitter_t *emitter) {
static void
emit_nested_dict(emitter_t *emitter) {
int val = 123;
emitter_begin(emitter);
emitter_dict_begin(emitter, "json1", "Dict 1");
@ -174,53 +174,53 @@ static void emit_nested_dict(emitter_t *emitter) {
emitter_dict_end(emitter); /* Close 3 */
emitter_dict_end(emitter); /* Close 1 */
emitter_dict_begin(emitter, "json4", "Dict 4");
emitter_kv(emitter, "primitive", "Another primitive",
emitter_type_int, &val);
emitter_kv(
emitter, "primitive", "Another primitive", emitter_type_int, &val);
emitter_dict_end(emitter); /* Close 4 */
emitter_end(emitter);
}
static const char *nested_dict_json =
"{\n"
"\t\"json1\": {\n"
"\t\t\"json2\": {\n"
"\t\t\t\"primitive\": 123\n"
"\t\t},\n"
"\t\t\"json3\": {\n"
"\t\t}\n"
"\t},\n"
"\t\"json4\": {\n"
"\t\t\"primitive\": 123\n"
"\t}\n"
"}\n";
"{\n"
"\t\"json1\": {\n"
"\t\t\"json2\": {\n"
"\t\t\t\"primitive\": 123\n"
"\t\t},\n"
"\t\t\"json3\": {\n"
"\t\t}\n"
"\t},\n"
"\t\"json4\": {\n"
"\t\t\"primitive\": 123\n"
"\t}\n"
"}\n";
static const char *nested_dict_json_compact =
"{"
"\"json1\":{"
"\"json2\":{"
"\"primitive\":123"
"},"
"\"json3\":{"
"}"
"},"
"\"json4\":{"
"\"primitive\":123"
"}"
"}";
"{"
"\"json1\":{"
"\"json2\":{"
"\"primitive\":123"
"},"
"\"json3\":{"
"}"
"},"
"\"json4\":{"
"\"primitive\":123"
"}"
"}";
static const char *nested_dict_table =
"Dict 1\n"
" Dict 2\n"
" A primitive: 123\n"
" Dict 3\n"
"Dict 4\n"
" Another primitive: 123\n";
"Dict 1\n"
" Dict 2\n"
" A primitive: 123\n"
" Dict 3\n"
"Dict 4\n"
" Another primitive: 123\n";
static void
emit_types(emitter_t *emitter) {
bool b = false;
int i = -123;
unsigned u = 123;
ssize_t zd = -456;
size_t zu = 456;
bool b = false;
int i = -123;
unsigned u = 123;
ssize_t zd = -456;
size_t zu = 456;
const char *str = "string";
const char *long_str =
"abcdefghijklmnopqrstuvwxyz "
@ -254,55 +254,55 @@ emit_types(emitter_t *emitter) {
}
static const char *types_json =
"{\n"
"\t\"k1\": false,\n"
"\t\"k2\": -123,\n"
"\t\"k3\": 123,\n"
"\t\"k4\": -456,\n"
"\t\"k5\": 456,\n"
"\t\"k6\": \"string\",\n"
"\t\"k7\": \"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz\",\n"
"\t\"k8\": 789,\n"
"\t\"k9\": 10000000000\n"
"}\n";
"{\n"
"\t\"k1\": false,\n"
"\t\"k2\": -123,\n"
"\t\"k3\": 123,\n"
"\t\"k4\": -456,\n"
"\t\"k5\": 456,\n"
"\t\"k6\": \"string\",\n"
"\t\"k7\": \"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz\",\n"
"\t\"k8\": 789,\n"
"\t\"k9\": 10000000000\n"
"}\n";
static const char *types_json_compact =
"{"
"\"k1\":false,"
"\"k2\":-123,"
"\"k3\":123,"
"\"k4\":-456,"
"\"k5\":456,"
"\"k6\":\"string\","
"\"k7\":\"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz\","
"\"k8\":789,"
"\"k9\":10000000000"
"}";
"{"
"\"k1\":false,"
"\"k2\":-123,"
"\"k3\":123,"
"\"k4\":-456,"
"\"k5\":456,"
"\"k6\":\"string\","
"\"k7\":\"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz\","
"\"k8\":789,"
"\"k9\":10000000000"
"}";
static const char *types_table =
"K1: false\n"
"K2: -123\n"
"K3: 123\n"
"K4: -456\n"
"K5: 456\n"
"K6: \"string\"\n"
"K7: \"abcdefghijklmnopqrstuvwxyz "
"K1: false\n"
"K2: -123\n"
"K3: 123\n"
"K4: -456\n"
"K5: 456\n"
"K6: \"string\"\n"
"K7: \"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
@ -312,8 +312,8 @@ static const char *types_table =
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz "
"abcdefghijklmnopqrstuvwxyz\"\n"
"K8: 789\n"
"K9: 10000000000\n";
"K8: 789\n"
"K9: 10000000000\n";
static void
emit_modal(emitter_t *emitter) {
@ -336,37 +336,37 @@ emit_modal(emitter_t *emitter) {
}
const char *modal_json =
"{\n"
"\t\"j0\": {\n"
"\t\t\"j1\": {\n"
"\t\t\t\"i1\": 123,\n"
"\t\t\t\"i2\": 123,\n"
"\t\t\t\"i4\": 123\n"
"\t\t},\n"
"\t\t\"i5\": 123,\n"
"\t\t\"i6\": 123\n"
"\t}\n"
"}\n";
"{\n"
"\t\"j0\": {\n"
"\t\t\"j1\": {\n"
"\t\t\t\"i1\": 123,\n"
"\t\t\t\"i2\": 123,\n"
"\t\t\t\"i4\": 123\n"
"\t\t},\n"
"\t\t\"i5\": 123,\n"
"\t\t\"i6\": 123\n"
"\t}\n"
"}\n";
const char *modal_json_compact =
"{"
"\"j0\":{"
"\"j1\":{"
"\"i1\":123,"
"\"i2\":123,"
"\"i4\":123"
"},"
"\"i5\":123,"
"\"i6\":123"
"}"
"}";
"{"
"\"j0\":{"
"\"j1\":{"
"\"i1\":123,"
"\"i2\":123,"
"\"i4\":123"
"},"
"\"i5\":123,"
"\"i6\":123"
"}"
"}";
const char *modal_table =
"T0\n"
" I1: 123\n"
" I3: 123\n"
" T1\n"
" I4: 123\n"
" I5: 123\n"
" I6: 123\n";
"T0\n"
" I1: 123\n"
" I3: 123\n"
" T1\n"
" I4: 123\n"
" I5: 123\n"
" I6: 123\n";
static void
emit_json_array(emitter_t *emitter) {
@ -387,121 +387,124 @@ emit_json_array(emitter_t *emitter) {
emitter_json_kv(emitter, "bar", emitter_type_int, &ival);
emitter_json_kv(emitter, "baz", emitter_type_int, &ival);
emitter_json_object_end(emitter); /* Close arr[3]. */
emitter_json_array_end(emitter); /* Close arr. */
emitter_json_array_end(emitter); /* Close arr. */
emitter_json_object_end(emitter); /* Close dict. */
emitter_end(emitter);
}
static const char *json_array_json =
"{\n"
"\t\"dict\": {\n"
"\t\t\"arr\": [\n"
"\t\t\t{\n"
"\t\t\t\t\"foo\": 123\n"
"\t\t\t},\n"
"\t\t\t123,\n"
"\t\t\t123,\n"
"\t\t\t{\n"
"\t\t\t\t\"bar\": 123,\n"
"\t\t\t\t\"baz\": 123\n"
"\t\t\t}\n"
"\t\t]\n"
"\t}\n"
"}\n";
"{\n"
"\t\"dict\": {\n"
"\t\t\"arr\": [\n"
"\t\t\t{\n"
"\t\t\t\t\"foo\": 123\n"
"\t\t\t},\n"
"\t\t\t123,\n"
"\t\t\t123,\n"
"\t\t\t{\n"
"\t\t\t\t\"bar\": 123,\n"
"\t\t\t\t\"baz\": 123\n"
"\t\t\t}\n"
"\t\t]\n"
"\t}\n"
"}\n";
static const char *json_array_json_compact =
"{"
"\"dict\":{"
"\"arr\":["
"{"
"\"foo\":123"
"},"
"123,"
"123,"
"{"
"\"bar\":123,"
"\"baz\":123"
"}"
"]"
"}"
"}";
"{"
"\"dict\":{"
"\"arr\":["
"{"
"\"foo\":123"
"},"
"123,"
"123,"
"{"
"\"bar\":123,"
"\"baz\":123"
"}"
"]"
"}"
"}";
static const char *json_array_table = "";
static void
emit_json_nested_array(emitter_t *emitter) {
int ival = 123;
int ival = 123;
char *sval = "foo";
emitter_begin(emitter);
emitter_json_array_begin(emitter);
emitter_json_array_begin(emitter);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_value(emitter, emitter_type_string, &sval);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_value(emitter, emitter_type_string, &sval);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_value(emitter, emitter_type_string, &sval);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_value(emitter, emitter_type_string, &sval);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_value(emitter, emitter_type_string, &sval);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_value(emitter, emitter_type_string, &sval);
emitter_json_value(emitter, emitter_type_int, &ival);
emitter_json_array_end(emitter);
emitter_json_array_begin(emitter);
emitter_json_array_end(emitter);
emitter_json_array_end(emitter);
emitter_end(emitter);
}
static const char *json_nested_array_json =
"{\n"
"\t[\n"
"\t\t[\n"
"\t\t\t123,\n"
"\t\t\t\"foo\",\n"
"\t\t\t123,\n"
"\t\t\t\"foo\"\n"
"\t\t],\n"
"\t\t[\n"
"\t\t\t123\n"
"\t\t],\n"
"\t\t[\n"
"\t\t\t\"foo\",\n"
"\t\t\t123\n"
"\t\t],\n"
"\t\t[\n"
"\t\t]\n"
"\t]\n"
"}\n";
"{\n"
"\t[\n"
"\t\t[\n"
"\t\t\t123,\n"
"\t\t\t\"foo\",\n"
"\t\t\t123,\n"
"\t\t\t\"foo\"\n"
"\t\t],\n"
"\t\t[\n"
"\t\t\t123\n"
"\t\t],\n"
"\t\t[\n"
"\t\t\t\"foo\",\n"
"\t\t\t123\n"
"\t\t],\n"
"\t\t[\n"
"\t\t]\n"
"\t]\n"
"}\n";
static const char *json_nested_array_json_compact =
"{"
"["
"["
"123,"
"\"foo\","
"123,"
"\"foo\""
"],"
"["
"123"
"],"
"["
"\"foo\","
"123"
"],"
"["
"]"
"]"
"}";
"{"
"["
"["
"123,"
"\"foo\","
"123,"
"\"foo\""
"],"
"["
"123"
"],"
"["
"\"foo\","
"123"
"],"
"["
"]"
"]"
"}";
static const char *json_nested_array_table = "";
static void
emit_table_row(emitter_t *emitter) {
emitter_begin(emitter);
emitter_row_t row;
emitter_col_t abc = {emitter_justify_left, 10, emitter_type_title, {0}, {0, 0}};
emitter_col_t abc = {
emitter_justify_left, 10, emitter_type_title, {0}, {0, 0}};
abc.str_val = "ABC title";
emitter_col_t def = {emitter_justify_right, 15, emitter_type_title, {0}, {0, 0}};
emitter_col_t def = {
emitter_justify_right, 15, emitter_type_title, {0}, {0, 0}};
def.str_val = "DEF title";
emitter_col_t ghi = {emitter_justify_right, 5, emitter_type_title, {0}, {0, 0}};
emitter_col_t ghi = {
emitter_justify_right, 5, emitter_type_title, {0}, {0, 0}};
ghi.str_val = "GHI";
emitter_row_init(&row);
@ -536,21 +539,21 @@ emit_table_row(emitter_t *emitter) {
}
static const char *table_row_json =
"{\n"
"}\n";
"{\n"
"}\n";
static const char *table_row_json_compact = "{}";
static const char *table_row_table =
"ABC title DEF title GHI\n"
"123 true 456\n"
"789 false 1011\n"
"\"a string\" false ghi\n";
"ABC title DEF title GHI\n"
"123 true 456\n"
"789 false 1011\n"
"\"a string\" false ghi\n";
#define GENERATE_TEST(feature) \
TEST_BEGIN(test_##feature) { \
expect_emit_output(emit_##feature, feature##_json, \
feature##_json_compact, feature##_table); \
} \
TEST_END
#define GENERATE_TEST(feature) \
TEST_BEGIN(test_##feature) { \
expect_emit_output(emit_##feature, feature##_json, \
feature##_json_compact, feature##_table); \
} \
TEST_END
GENERATE_TEST(dict)
GENERATE_TEST(table_printf)
@ -563,13 +566,7 @@ GENERATE_TEST(table_row)
int
main(void) {
return test_no_reentrancy(
test_dict,
test_table_printf,
test_nested_dict,
test_types,
test_modal,
test_json_array,
test_json_nested_array,
test_table_row);
return test_no_reentrancy(test_dict, test_table_printf,
test_nested_dict, test_types, test_modal, test_json_array,
test_json_nested_array, test_table_row);
}

View file

@ -2,9 +2,9 @@
TEST_BEGIN(test_small_extent_size) {
unsigned nbins, i;
size_t sz, extent_size;
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
size_t sz, extent_size;
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
/*
* Iterate over all small size classes, get their extent sizes, and
@ -21,25 +21,26 @@ TEST_BEGIN(test_small_extent_size) {
mib[2] = i;
sz = sizeof(size_t);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&extent_size, &sz,
NULL, 0), 0, "Unexpected mallctlbymib failure");
expect_zu_eq(extent_size,
sz_psz_quantize_floor(extent_size),
NULL, 0),
0, "Unexpected mallctlbymib failure");
expect_zu_eq(extent_size, sz_psz_quantize_floor(extent_size),
"Small extent quantization should be a no-op "
"(extent_size=%zu)", extent_size);
expect_zu_eq(extent_size,
sz_psz_quantize_ceil(extent_size),
"(extent_size=%zu)",
extent_size);
expect_zu_eq(extent_size, sz_psz_quantize_ceil(extent_size),
"Small extent quantization should be a no-op "
"(extent_size=%zu)", extent_size);
"(extent_size=%zu)",
extent_size);
}
}
TEST_END
TEST_BEGIN(test_large_extent_size) {
bool cache_oblivious;
bool cache_oblivious;
unsigned nlextents, i;
size_t sz, extent_size_prev, ceil_prev;
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
size_t sz, extent_size_prev, ceil_prev;
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
/*
* Iterate over all large size classes, get their extent sizes, and
@ -48,11 +49,13 @@ TEST_BEGIN(test_large_extent_size) {
sz = sizeof(bool);
expect_d_eq(mallctl("opt.cache_oblivious", (void *)&cache_oblivious,
&sz, NULL, 0), 0, "Unexpected mallctl failure");
&sz, NULL, 0),
0, "Unexpected mallctl failure");
sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL,
0), 0, "Unexpected mallctl failure");
expect_d_eq(
mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
expect_d_eq(mallctlnametomib("arenas.lextent.0.size", mib, &miblen), 0,
"Unexpected mallctlnametomib failure");
@ -62,20 +65,21 @@ TEST_BEGIN(test_large_extent_size) {
mib[2] = i;
sz = sizeof(size_t);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&lextent_size,
&sz, NULL, 0), 0, "Unexpected mallctlbymib failure");
extent_size = cache_oblivious ? lextent_size + PAGE :
lextent_size;
&sz, NULL, 0),
0, "Unexpected mallctlbymib failure");
extent_size = cache_oblivious ? lextent_size + PAGE
: lextent_size;
floor = sz_psz_quantize_floor(extent_size);
ceil = sz_psz_quantize_ceil(extent_size);
expect_zu_eq(extent_size, floor,
"Extent quantization should be a no-op for precise size "
"(lextent_size=%zu, extent_size=%zu)", lextent_size,
extent_size);
"(lextent_size=%zu, extent_size=%zu)",
lextent_size, extent_size);
expect_zu_eq(extent_size, ceil,
"Extent quantization should be a no-op for precise size "
"(lextent_size=%zu, extent_size=%zu)", lextent_size,
extent_size);
"(lextent_size=%zu, extent_size=%zu)",
lextent_size, extent_size);
if (i > 0) {
expect_zu_eq(extent_size_prev,
@ -85,23 +89,22 @@ TEST_BEGIN(test_large_extent_size) {
expect_zu_eq(ceil_prev, extent_size,
"Ceiling should be a precise size "
"(extent_size_prev=%zu, ceil_prev=%zu, "
"extent_size=%zu)", extent_size_prev,
ceil_prev, extent_size);
"extent_size=%zu)",
extent_size_prev, ceil_prev, extent_size);
}
}
if (i + 1 < nlextents) {
extent_size_prev = floor;
ceil_prev = sz_psz_quantize_ceil(extent_size +
PAGE);
ceil_prev = sz_psz_quantize_ceil(extent_size + PAGE);
}
}
}
TEST_END
TEST_BEGIN(test_monotonic) {
#define SZ_MAX ZU(4 * 1024 * 1024)
#define SZ_MAX ZU(4 * 1024 * 1024)
unsigned i;
size_t floor_prev, ceil_prev;
size_t floor_prev, ceil_prev;
floor_prev = 0;
ceil_prev = 0;
@ -117,12 +120,15 @@ TEST_BEGIN(test_monotonic) {
floor, extent_size, ceil);
expect_zu_ge(ceil, extent_size,
"Ceiling should be >= (floor=%zu, extent_size=%zu, "
"ceil=%zu)", floor, extent_size, ceil);
"ceil=%zu)",
floor, extent_size, ceil);
expect_zu_le(floor_prev, floor, "Floor should be monotonic "
expect_zu_le(floor_prev, floor,
"Floor should be monotonic "
"(floor_prev=%zu, floor=%zu, extent_size=%zu, ceil=%zu)",
floor_prev, floor, extent_size, ceil);
expect_zu_le(ceil_prev, ceil, "Ceiling should be monotonic "
expect_zu_le(ceil_prev, ceil,
"Ceiling should be monotonic "
"(floor=%zu, extent_size=%zu, ceil_prev=%zu, ceil=%zu)",
floor, extent_size, ceil_prev, ceil);
@ -135,7 +141,5 @@ TEST_END
int
main(void) {
return test(
test_small_extent_size,
test_large_extent_size,
test_monotonic);
test_small_extent_size, test_large_extent_size, test_monotonic);
}

View file

@ -5,21 +5,19 @@
static void
do_test_init(size_t nbits) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb = malloc(sz);
/* Junk fb's contents. */
memset(fb, 99, sz);
fb_init(fb, nbits);
for (size_t i = 0; i < nbits; i++) {
expect_false(fb_get(fb, nbits, i),
"bitmap should start empty");
expect_false(fb_get(fb, nbits, i), "bitmap should start empty");
}
free(fb);
}
TEST_BEGIN(test_fb_init) {
#define NB(nbits) \
do_test_init(nbits);
#define NB(nbits) do_test_init(nbits);
NBITS_TAB
#undef NB
}
@ -27,7 +25,7 @@ TEST_END
static void
do_test_get_set_unset(size_t nbits) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb = malloc(sz);
fb_init(fb, nbits);
/* Set the bits divisible by 3. */
@ -56,8 +54,7 @@ do_test_get_set_unset(size_t nbits) {
}
TEST_BEGIN(test_get_set_unset) {
#define NB(nbits) \
do_test_get_set_unset(nbits);
#define NB(nbits) do_test_get_set_unset(nbits);
NBITS_TAB
#undef NB
}
@ -65,7 +62,7 @@ TEST_END
static ssize_t
find_3_5_compute(ssize_t i, size_t nbits, bool bit, bool forward) {
for(; i < (ssize_t)nbits && i >= 0; i += (forward ? 1 : -1)) {
for (; i < (ssize_t)nbits && i >= 0; i += (forward ? 1 : -1)) {
bool expected_bit = i % 3 == 0 || i % 5 == 0;
if (expected_bit == bit) {
return i;
@ -76,7 +73,7 @@ find_3_5_compute(ssize_t i, size_t nbits, bool bit, bool forward) {
static void
do_test_search_simple(size_t nbits) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb = malloc(sz);
fb_init(fb, nbits);
@ -96,7 +93,7 @@ do_test_search_simple(size_t nbits) {
expect_zu_eq(ffs_compute, ffs_search, "ffs mismatch at %zu", i);
ssize_t fls_compute = find_3_5_compute(i, nbits, true, false);
size_t fls_search = fb_fls(fb, nbits, i);
size_t fls_search = fb_fls(fb, nbits, i);
expect_zu_eq(fls_compute, fls_search, "fls mismatch at %zu", i);
size_t ffu_compute = find_3_5_compute(i, nbits, false, true);
@ -112,8 +109,7 @@ do_test_search_simple(size_t nbits) {
}
TEST_BEGIN(test_search_simple) {
#define NB(nbits) \
do_test_search_simple(nbits);
#define NB(nbits) do_test_search_simple(nbits);
NBITS_TAB
#undef NB
}
@ -145,15 +141,17 @@ expect_exhaustive_results(fb_group_t *mostly_full, fb_group_t *mostly_empty,
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(special_bit, fb_fls(mostly_empty, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zu_eq(position + 1, fb_ffu(mostly_empty, nbits, position),
expect_zu_eq(position + 1,
fb_ffu(mostly_empty, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(position - 1,
fb_flu(mostly_empty, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(position - 1, fb_flu(mostly_empty, nbits,
position), "mismatch at %zu, %zu", position, special_bit);
expect_zu_eq(position + 1, fb_ffs(mostly_full, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(position - 1, fb_fls(mostly_full, nbits,
position), "mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(position - 1, fb_fls(mostly_full, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zu_eq(position, fb_ffu(mostly_full, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(position, fb_flu(mostly_full, nbits, position),
@ -162,8 +160,8 @@ expect_exhaustive_results(fb_group_t *mostly_full, fb_group_t *mostly_empty,
/* position > special_bit. */
expect_zu_eq(nbits, fb_ffs(mostly_empty, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(special_bit, fb_fls(mostly_empty, nbits,
position), "mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(special_bit, fb_fls(mostly_empty, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zu_eq(position, fb_ffu(mostly_empty, nbits, position),
"mismatch at %zu, %zu", position, special_bit);
expect_zd_eq(position, fb_flu(mostly_empty, nbits, position),
@ -186,7 +184,7 @@ do_test_search_exhaustive(size_t nbits) {
if (nbits > 1000) {
return;
}
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *empty = malloc(sz);
fb_init(empty, nbits);
fb_group_t *full = malloc(sz);
@ -209,8 +207,7 @@ do_test_search_exhaustive(size_t nbits) {
}
TEST_BEGIN(test_search_exhaustive) {
#define NB(nbits) \
do_test_search_exhaustive(nbits);
#define NB(nbits) do_test_search_exhaustive(nbits);
NBITS_TAB
#undef NB
}
@ -222,8 +219,8 @@ TEST_BEGIN(test_range_simple) {
* big enough that usages of things like weirdnum (below) near the
* beginning fit comfortably into the beginning of the bitmap.
*/
size_t nbits = 64 * 10;
size_t ngroups = FB_NGROUPS(nbits);
size_t nbits = 64 * 10;
size_t ngroups = FB_NGROUPS(nbits);
fb_group_t *fb = malloc(sizeof(fb_group_t) * ngroups);
fb_init(fb, nbits);
for (size_t i = 0; i < nbits; i++) {
@ -255,7 +252,7 @@ TEST_END
static void
do_test_empty_full_exhaustive(size_t nbits) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *empty = malloc(sz);
fb_init(empty, nbits);
fb_group_t *full = malloc(sz);
@ -273,15 +270,15 @@ do_test_empty_full_exhaustive(size_t nbits) {
expect_false(fb_empty(empty, nbits), "error at bit %zu", i);
if (nbits != 1) {
expect_false(fb_full(empty, nbits),
"error at bit %zu", i);
expect_false(fb_empty(full, nbits),
"error at bit %zu", i);
expect_false(
fb_full(empty, nbits), "error at bit %zu", i);
expect_false(
fb_empty(full, nbits), "error at bit %zu", i);
} else {
expect_true(fb_full(empty, nbits),
"error at bit %zu", i);
expect_true(fb_empty(full, nbits),
"error at bit %zu", i);
expect_true(
fb_full(empty, nbits), "error at bit %zu", i);
expect_true(
fb_empty(full, nbits), "error at bit %zu", i);
}
expect_false(fb_full(full, nbits), "error at bit %zu", i);
@ -294,8 +291,7 @@ do_test_empty_full_exhaustive(size_t nbits) {
}
TEST_BEGIN(test_empty_full) {
#define NB(nbits) \
do_test_empty_full_exhaustive(nbits);
#define NB(nbits) do_test_empty_full_exhaustive(nbits);
NBITS_TAB
#undef NB
}
@ -306,8 +302,8 @@ TEST_END
* built closely on top of it.
*/
TEST_BEGIN(test_iter_range_simple) {
size_t set_limit = 30;
size_t nbits = 100;
size_t set_limit = 30;
size_t nbits = 100;
fb_group_t fb[FB_NGROUPS(100)];
fb_init(fb, nbits);
@ -318,7 +314,7 @@ TEST_BEGIN(test_iter_range_simple) {
*/
size_t begin = (size_t)-1;
size_t len = (size_t)-1;
bool result;
bool result;
/* A set of checks with only the first set_limit bits *set*. */
fb_set_range(fb, nbits, 0, set_limit);
@ -410,7 +406,6 @@ TEST_BEGIN(test_iter_range_simple) {
expect_zu_eq(0, begin, "Incorrect begin at %zu", i);
expect_zu_eq(set_limit, len, "Incorrect len at %zu", i);
}
}
TEST_END
@ -426,11 +421,11 @@ fb_iter_simple(fb_group_t *fb, size_t nbits, size_t start, size_t *r_begin,
ssize_t stride = (forward ? (ssize_t)1 : (ssize_t)-1);
ssize_t range_begin = (ssize_t)start;
for (; range_begin != (ssize_t)nbits && range_begin != -1;
range_begin += stride) {
range_begin += stride) {
if (fb_get(fb, nbits, range_begin) == val) {
ssize_t range_end = range_begin;
for (; range_end != (ssize_t)nbits && range_end != -1;
range_end += stride) {
range_end += stride) {
if (fb_get(fb, nbits, range_end) != val) {
break;
}
@ -470,26 +465,26 @@ fb_range_longest_simple(fb_group_t *fb, size_t nbits, bool val) {
}
static void
expect_iter_results_at(fb_group_t *fb, size_t nbits, size_t pos,
bool val, bool forward) {
bool iter_res;
expect_iter_results_at(
fb_group_t *fb, size_t nbits, size_t pos, bool val, bool forward) {
bool iter_res;
size_t iter_begin JEMALLOC_CC_SILENCE_INIT(0);
size_t iter_len JEMALLOC_CC_SILENCE_INIT(0);
size_t iter_len JEMALLOC_CC_SILENCE_INIT(0);
if (val) {
if (forward) {
iter_res = fb_srange_iter(fb, nbits, pos,
&iter_begin, &iter_len);
iter_res = fb_srange_iter(
fb, nbits, pos, &iter_begin, &iter_len);
} else {
iter_res = fb_srange_riter(fb, nbits, pos,
&iter_begin, &iter_len);
iter_res = fb_srange_riter(
fb, nbits, pos, &iter_begin, &iter_len);
}
} else {
if (forward) {
iter_res = fb_urange_iter(fb, nbits, pos,
&iter_begin, &iter_len);
iter_res = fb_urange_iter(
fb, nbits, pos, &iter_begin, &iter_len);
} else {
iter_res = fb_urange_riter(fb, nbits, pos,
&iter_begin, &iter_len);
iter_res = fb_urange_riter(
fb, nbits, pos, &iter_begin, &iter_len);
}
}
@ -500,15 +495,15 @@ expect_iter_results_at(fb_group_t *fb, size_t nbits, size_t pos,
*/
size_t simple_iter_begin = 0;
size_t simple_iter_len = 0;
simple_iter_res = fb_iter_simple(fb, nbits, pos, &simple_iter_begin,
&simple_iter_len, val, forward);
simple_iter_res = fb_iter_simple(
fb, nbits, pos, &simple_iter_begin, &simple_iter_len, val, forward);
expect_b_eq(iter_res, simple_iter_res, "Result mismatch at %zu", pos);
if (iter_res && simple_iter_res) {
assert_zu_eq(iter_begin, simple_iter_begin,
"Begin mismatch at %zu", pos);
expect_zu_eq(iter_len, simple_iter_len,
"Length mismatch at %zu", pos);
expect_zu_eq(
iter_len, simple_iter_len, "Length mismatch at %zu", pos);
}
}
@ -543,7 +538,7 @@ do_test_iter_range_exhaustive(size_t nbits) {
if (nbits > 1000) {
return;
}
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb = malloc(sz);
fb_init(fb, nbits);
@ -558,7 +553,7 @@ do_test_iter_range_exhaustive(size_t nbits) {
expect_iter_results(fb, nbits);
fb_unset_range(fb, nbits, 0, nbits);
fb_set_range(fb, nbits, 0, nbits / 2 == 0 ? 1: nbits / 2);
fb_set_range(fb, nbits, 0, nbits / 2 == 0 ? 1 : nbits / 2);
expect_iter_results(fb, nbits);
free(fb);
@ -569,8 +564,7 @@ do_test_iter_range_exhaustive(size_t nbits) {
* computation.
*/
TEST_BEGIN(test_iter_range_exhaustive) {
#define NB(nbits) \
do_test_iter_range_exhaustive(nbits);
#define NB(nbits) do_test_iter_range_exhaustive(nbits);
NBITS_TAB
#undef NB
}
@ -581,8 +575,8 @@ TEST_END
* returns the number of set bits in [scount_start, scount_end).
*/
static size_t
scount_contiguous(size_t set_start, size_t set_end, size_t scount_start,
size_t scount_end) {
scount_contiguous(
size_t set_start, size_t set_end, size_t scount_start, size_t scount_end) {
/* No overlap. */
if (set_end <= scount_start || scount_end <= set_start) {
return 0;
@ -611,8 +605,8 @@ scount_contiguous(size_t set_start, size_t set_end, size_t scount_start,
}
static size_t
ucount_contiguous(size_t set_start, size_t set_end, size_t ucount_start,
size_t ucount_end) {
ucount_contiguous(
size_t set_start, size_t set_end, size_t ucount_start, size_t ucount_end) {
/* No overlap. */
if (set_end <= ucount_start || ucount_end <= set_start) {
return ucount_end - ucount_start;
@ -641,34 +635,33 @@ ucount_contiguous(size_t set_start, size_t set_end, size_t ucount_start,
}
static void
expect_count_match_contiguous(fb_group_t *fb, size_t nbits, size_t set_start,
size_t set_end) {
expect_count_match_contiguous(
fb_group_t *fb, size_t nbits, size_t set_start, size_t set_end) {
for (size_t i = 0; i < nbits; i++) {
for (size_t j = i + 1; j <= nbits; j++) {
size_t cnt = j - i;
size_t scount_expected = scount_contiguous(set_start,
set_end, i, j);
size_t scount_expected = scount_contiguous(
set_start, set_end, i, j);
size_t scount_computed = fb_scount(fb, nbits, i, cnt);
expect_zu_eq(scount_expected, scount_computed,
"fb_scount error with nbits=%zu, start=%zu, "
"cnt=%zu, with bits set in [%zu, %zu)",
nbits, i, cnt, set_start, set_end);
size_t ucount_expected = ucount_contiguous(set_start,
set_end, i, j);
size_t ucount_expected = ucount_contiguous(
set_start, set_end, i, j);
size_t ucount_computed = fb_ucount(fb, nbits, i, cnt);
assert_zu_eq(ucount_expected, ucount_computed,
"fb_ucount error with nbits=%zu, start=%zu, "
"cnt=%zu, with bits set in [%zu, %zu)",
nbits, i, cnt, set_start, set_end);
}
}
}
static void
do_test_count_contiguous(size_t nbits) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb = malloc(sz);
fb_init(fb, nbits);
@ -688,7 +681,7 @@ do_test_count_contiguous(size_t nbits) {
}
TEST_BEGIN(test_count_contiguous_simple) {
enum {nbits = 300};
enum { nbits = 300 };
fb_group_t fb[FB_NGROUPS(nbits)];
fb_init(fb, nbits);
/* Just an arbitrary number. */
@ -718,10 +711,10 @@ TEST_BEGIN(test_count_contiguous_simple) {
TEST_END
TEST_BEGIN(test_count_contiguous) {
#define NB(nbits) \
/* This test is *particularly* slow in debug builds. */ \
if ((!config_debug && nbits < 300) || nbits < 150) { \
do_test_count_contiguous(nbits); \
#define NB(nbits) \
/* This test is *particularly* slow in debug builds. */ \
if ((!config_debug && nbits < 300) || nbits < 150) { \
do_test_count_contiguous(nbits); \
}
NBITS_TAB
#undef NB
@ -729,15 +722,15 @@ TEST_BEGIN(test_count_contiguous) {
TEST_END
static void
expect_count_match_alternating(fb_group_t *fb_even, fb_group_t *fb_odd,
size_t nbits) {
expect_count_match_alternating(
fb_group_t *fb_even, fb_group_t *fb_odd, size_t nbits) {
for (size_t i = 0; i < nbits; i++) {
for (size_t j = i + 1; j <= nbits; j++) {
size_t cnt = j - i;
size_t odd_scount = cnt / 2
+ (size_t)(cnt % 2 == 1 && i % 2 == 1);
size_t odd_scount_computed = fb_scount(fb_odd, nbits,
i, j - i);
size_t odd_scount_computed = fb_scount(
fb_odd, nbits, i, j - i);
assert_zu_eq(odd_scount, odd_scount_computed,
"fb_scount error with nbits=%zu, start=%zu, "
"cnt=%zu, with alternating bits set.",
@ -745,8 +738,8 @@ expect_count_match_alternating(fb_group_t *fb_even, fb_group_t *fb_odd,
size_t odd_ucount = cnt / 2
+ (size_t)(cnt % 2 == 1 && i % 2 == 0);
size_t odd_ucount_computed = fb_ucount(fb_odd, nbits,
i, j - i);
size_t odd_ucount_computed = fb_ucount(
fb_odd, nbits, i, j - i);
assert_zu_eq(odd_ucount, odd_ucount_computed,
"fb_ucount error with nbits=%zu, start=%zu, "
"cnt=%zu, with alternating bits set.",
@ -754,8 +747,8 @@ expect_count_match_alternating(fb_group_t *fb_even, fb_group_t *fb_odd,
size_t even_scount = cnt / 2
+ (size_t)(cnt % 2 == 1 && i % 2 == 0);
size_t even_scount_computed = fb_scount(fb_even, nbits,
i, j - i);
size_t even_scount_computed = fb_scount(
fb_even, nbits, i, j - i);
assert_zu_eq(even_scount, even_scount_computed,
"fb_scount error with nbits=%zu, start=%zu, "
"cnt=%zu, with alternating bits set.",
@ -763,8 +756,8 @@ expect_count_match_alternating(fb_group_t *fb_even, fb_group_t *fb_odd,
size_t even_ucount = cnt / 2
+ (size_t)(cnt % 2 == 1 && i % 2 == 1);
size_t even_ucount_computed = fb_ucount(fb_even, nbits,
i, j - i);
size_t even_ucount_computed = fb_ucount(
fb_even, nbits, i, j - i);
assert_zu_eq(even_ucount, even_ucount_computed,
"fb_ucount error with nbits=%zu, start=%zu, "
"cnt=%zu, with alternating bits set.",
@ -778,7 +771,7 @@ do_test_count_alternating(size_t nbits) {
if (nbits > 1000) {
return;
}
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb_even = malloc(sz);
fb_group_t *fb_odd = malloc(sz);
@ -800,8 +793,7 @@ do_test_count_alternating(size_t nbits) {
}
TEST_BEGIN(test_count_alternating) {
#define NB(nbits) \
do_test_count_alternating(nbits);
#define NB(nbits) do_test_count_alternating(nbits);
NBITS_TAB
#undef NB
}
@ -809,8 +801,9 @@ TEST_END
static void
do_test_bit_op(size_t nbits, bool (*op)(bool a, bool b),
void (*fb_op)(fb_group_t *dst, fb_group_t *src1, fb_group_t *src2, size_t nbits)) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
void (*fb_op)(
fb_group_t *dst, fb_group_t *src1, fb_group_t *src2, size_t nbits)) {
size_t sz = FB_NGROUPS(nbits) * sizeof(fb_group_t);
fb_group_t *fb1 = malloc(sz);
fb_group_t *fb2 = malloc(sz);
fb_group_t *fb_result = malloc(sz);
@ -853,8 +846,10 @@ do_test_bit_op(size_t nbits, bool (*op)(bool a, bool b),
bool bit2 = ((prng2 & (1ULL << (i % 64))) != 0);
/* Original bitmaps shouldn't change. */
expect_b_eq(bit1, fb_get(fb1, nbits, i), "difference at bit %zu", i);
expect_b_eq(bit2, fb_get(fb2, nbits, i), "difference at bit %zu", i);
expect_b_eq(
bit1, fb_get(fb1, nbits, i), "difference at bit %zu", i);
expect_b_eq(
bit2, fb_get(fb2, nbits, i), "difference at bit %zu", i);
/* New one should be bitwise and. */
expect_b_eq(op(bit1, bit2), fb_get(fb_result, nbits, i),
@ -883,8 +878,7 @@ do_test_bit_and(size_t nbits) {
}
TEST_BEGIN(test_bit_and) {
#define NB(nbits) \
do_test_bit_and(nbits);
#define NB(nbits) do_test_bit_and(nbits);
NBITS_TAB
#undef NB
}
@ -901,8 +895,7 @@ do_test_bit_or(size_t nbits) {
}
TEST_BEGIN(test_bit_or) {
#define NB(nbits) \
do_test_bit_or(nbits);
#define NB(nbits) do_test_bit_or(nbits);
NBITS_TAB
#undef NB
}
@ -915,8 +908,8 @@ binary_not(bool a, bool b) {
}
static void
fb_bit_not_shim(fb_group_t *dst, fb_group_t *src1, fb_group_t *src2,
size_t nbits) {
fb_bit_not_shim(
fb_group_t *dst, fb_group_t *src1, fb_group_t *src2, size_t nbits) {
(void)src2;
fb_bit_not(dst, src1, nbits);
}
@ -927,8 +920,7 @@ do_test_bit_not(size_t nbits) {
}
TEST_BEGIN(test_bit_not) {
#define NB(nbits) \
do_test_bit_not(nbits);
#define NB(nbits) do_test_bit_not(nbits);
NBITS_TAB
#undef NB
}
@ -936,19 +928,9 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_fb_init,
test_get_set_unset,
test_search_simple,
test_search_exhaustive,
test_range_simple,
test_empty_full,
test_iter_range_simple,
test_iter_range_exhaustive,
test_count_contiguous_simple,
test_count_contiguous,
test_count_alternating,
test_bit_and,
test_bit_or,
test_bit_not);
return test_no_reentrancy(test_fb_init, test_get_set_unset,
test_search_simple, test_search_exhaustive, test_range_simple,
test_empty_full, test_iter_range_simple, test_iter_range_exhaustive,
test_count_contiguous_simple, test_count_contiguous,
test_count_alternating, test_bit_and, test_bit_or, test_bit_not);
}

View file

@ -8,7 +8,7 @@ TEST_BEGIN(test_fork) {
/* Set up a manually managed arena for test. */
unsigned arena_ind;
size_t sz = sizeof(unsigned);
size_t sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz, NULL, 0),
0, "Unexpected mallctl() failure");
@ -16,8 +16,8 @@ TEST_BEGIN(test_fork) {
unsigned old_arena_ind;
sz = sizeof(old_arena_ind);
expect_d_eq(mallctl("thread.arena", (void *)&old_arena_ind, &sz,
(void *)&arena_ind, sizeof(arena_ind)), 0,
"Unexpected mallctl() failure");
(void *)&arena_ind, sizeof(arena_ind)),
0, "Unexpected mallctl() failure");
p = malloc(1);
expect_ptr_not_null(p, "Unexpected malloc() failure");
@ -108,7 +108,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_fork,
test_fork_multithreaded);
return test_no_reentrancy(test_fork, test_fork_multithreaded);
}

View file

@ -28,7 +28,7 @@ fxp_close(fxp_t a, fxp_t b) {
static fxp_t
xparse_fxp(const char *str) {
fxp_t result;
bool err = fxp_parse(&result, str, NULL);
bool err = fxp_parse(&result, str, NULL);
assert_false(err, "Invalid fxp string: %s", str);
return result;
}
@ -36,14 +36,14 @@ xparse_fxp(const char *str) {
static void
expect_parse_accurate(const char *str, const char *parse_str) {
double true_val = strtod(str, NULL);
fxp_t fxp_val;
char *end;
bool err = fxp_parse(&fxp_val, parse_str, &end);
fxp_t fxp_val;
char *end;
bool err = fxp_parse(&fxp_val, parse_str, &end);
expect_false(err, "Unexpected parse failure");
expect_ptr_eq(parse_str + strlen(str), end,
"Didn't parse whole string");
expect_true(double_close(fxp2double(fxp_val), true_val),
"Misparsed %s", str);
expect_ptr_eq(
parse_str + strlen(str), end, "Didn't parse whole string");
expect_true(
double_close(fxp2double(fxp_val), true_val), "Misparsed %s", str);
}
static void
@ -100,12 +100,12 @@ static void
expect_parse_failure(const char *str) {
fxp_t result = FXP_INIT_INT(333);
char *end = (void *)0x123;
bool err = fxp_parse(&result, str, &end);
bool err = fxp_parse(&result, str, &end);
expect_true(err, "Expected a parse error on: %s", str);
expect_ptr_eq((void *)0x123, end,
"Parse error shouldn't change results");
expect_u32_eq(result, FXP_INIT_INT(333),
"Parse error shouldn't change results");
expect_ptr_eq(
(void *)0x123, end, "Parse error shouldn't change results");
expect_u32_eq(
result, FXP_INIT_INT(333), "Parse error shouldn't change results");
}
TEST_BEGIN(test_parse_invalid) {
@ -129,7 +129,6 @@ expect_init_percent(unsigned percent, const char *str) {
"Expect representations of FXP_INIT_PERCENT(%u) and "
"fxp_parse(\"%s\") to be equal; got %x and %x",
percent, str, result_init, result_parse);
}
/*
@ -145,12 +144,12 @@ TEST_BEGIN(test_init_percent) {
TEST_END
static void
expect_add(const char *astr, const char *bstr, const char* resultstr) {
expect_add(const char *astr, const char *bstr, const char *resultstr) {
fxp_t a = xparse_fxp(astr);
fxp_t b = xparse_fxp(bstr);
fxp_t result = xparse_fxp(resultstr);
expect_true(fxp_close(fxp_add(a, b), result),
"Expected %s + %s == %s", astr, bstr, resultstr);
expect_true(fxp_close(fxp_add(a, b), result), "Expected %s + %s == %s",
astr, bstr, resultstr);
}
TEST_BEGIN(test_add_simple) {
@ -164,12 +163,12 @@ TEST_BEGIN(test_add_simple) {
TEST_END
static void
expect_sub(const char *astr, const char *bstr, const char* resultstr) {
expect_sub(const char *astr, const char *bstr, const char *resultstr) {
fxp_t a = xparse_fxp(astr);
fxp_t b = xparse_fxp(bstr);
fxp_t result = xparse_fxp(resultstr);
expect_true(fxp_close(fxp_sub(a, b), result),
"Expected %s - %s == %s", astr, bstr, resultstr);
expect_true(fxp_close(fxp_sub(a, b), result), "Expected %s - %s == %s",
astr, bstr, resultstr);
}
TEST_BEGIN(test_sub_simple) {
@ -183,12 +182,12 @@ TEST_BEGIN(test_sub_simple) {
TEST_END
static void
expect_mul(const char *astr, const char *bstr, const char* resultstr) {
expect_mul(const char *astr, const char *bstr, const char *resultstr) {
fxp_t a = xparse_fxp(astr);
fxp_t b = xparse_fxp(bstr);
fxp_t result = xparse_fxp(resultstr);
expect_true(fxp_close(fxp_mul(a, b), result),
"Expected %s * %s == %s", astr, bstr, resultstr);
expect_true(fxp_close(fxp_mul(a, b), result), "Expected %s * %s == %s",
astr, bstr, resultstr);
}
TEST_BEGIN(test_mul_simple) {
@ -202,12 +201,12 @@ TEST_BEGIN(test_mul_simple) {
TEST_END
static void
expect_div(const char *astr, const char *bstr, const char* resultstr) {
expect_div(const char *astr, const char *bstr, const char *resultstr) {
fxp_t a = xparse_fxp(astr);
fxp_t b = xparse_fxp(bstr);
fxp_t result = xparse_fxp(resultstr);
expect_true(fxp_close(fxp_div(a, b), result),
"Expected %s / %s == %s", astr, bstr, resultstr);
expect_true(fxp_close(fxp_div(a, b), result), "Expected %s / %s == %s",
astr, bstr, resultstr);
}
TEST_BEGIN(test_div_simple) {
@ -223,11 +222,11 @@ TEST_END
static void
expect_round(const char *str, uint32_t rounded_down, uint32_t rounded_nearest) {
fxp_t fxp = xparse_fxp(str);
fxp_t fxp = xparse_fxp(str);
uint32_t fxp_rounded_down = fxp_round_down(fxp);
uint32_t fxp_rounded_nearest = fxp_round_nearest(fxp);
expect_u32_eq(rounded_down, fxp_rounded_down,
"Mistake rounding %s down", str);
expect_u32_eq(
rounded_down, fxp_rounded_down, "Mistake rounding %s down", str);
expect_u32_eq(rounded_nearest, fxp_rounded_nearest,
"Mistake rounding %s to nearest", str);
}
@ -248,11 +247,11 @@ TEST_END
static void
expect_mul_frac(size_t a, const char *fracstr, size_t expected) {
fxp_t frac = xparse_fxp(fracstr);
fxp_t frac = xparse_fxp(fracstr);
size_t result = fxp_mul_frac(a, frac);
expect_true(double_close(expected, result),
"Expected %zu * %s == %zu (fracmul); got %zu", a, fracstr,
expected, result);
"Expected %zu * %s == %zu (fracmul); got %zu", a, fracstr, expected,
result);
}
TEST_BEGIN(test_mul_frac_simple) {
@ -273,7 +272,7 @@ TEST_END
static void
expect_print(const char *str) {
fxp_t fxp = xparse_fxp(str);
char buf[FXP_BUF_SIZE];
char buf[FXP_BUF_SIZE];
fxp_print(fxp, buf);
expect_d_eq(0, strcmp(str, buf), "Couldn't round-trip print %s", str);
}
@ -298,33 +297,32 @@ TEST_BEGIN(test_print_simple) {
TEST_END
TEST_BEGIN(test_stress) {
const char *numbers[] = {
"0.0", "0.1", "0.2", "0.3", "0.4",
"0.5", "0.6", "0.7", "0.8", "0.9",
const char *numbers[] = {"0.0", "0.1", "0.2", "0.3", "0.4", "0.5",
"0.6", "0.7", "0.8", "0.9",
"1.0", "1.1", "1.2", "1.3", "1.4",
"1.5", "1.6", "1.7", "1.8", "1.9",
"1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8",
"1.9",
"2.0", "2.1", "2.2", "2.3", "2.4",
"2.5", "2.6", "2.7", "2.8", "2.9",
"2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8",
"2.9",
"17.0", "17.1", "17.2", "17.3", "17.4",
"17.5", "17.6", "17.7", "17.8", "17.9",
"17.0", "17.1", "17.2", "17.3", "17.4", "17.5", "17.6", "17.7",
"17.8", "17.9",
"18.0", "18.1", "18.2", "18.3", "18.4",
"18.5", "18.6", "18.7", "18.8", "18.9",
"18.0", "18.1", "18.2", "18.3", "18.4", "18.5", "18.6", "18.7",
"18.8", "18.9",
"123.0", "123.1", "123.2", "123.3", "123.4",
"123.5", "123.6", "123.7", "123.8", "123.9",
"123.0", "123.1", "123.2", "123.3", "123.4", "123.5", "123.6",
"123.7", "123.8", "123.9",
"124.0", "124.1", "124.2", "124.3", "124.4",
"124.5", "124.6", "124.7", "124.8", "124.9",
"124.0", "124.1", "124.2", "124.3", "124.4", "124.5", "124.6",
"124.7", "124.8", "124.9",
"125.0", "125.1", "125.2", "125.3", "125.4",
"125.5", "125.6", "125.7", "125.8", "125.9"};
size_t numbers_len = sizeof(numbers)/sizeof(numbers[0]);
"125.0", "125.1", "125.2", "125.3", "125.4", "125.5", "125.6",
"125.7", "125.8", "125.9"};
size_t numbers_len = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < numbers_len; i++) {
fxp_t fxp_a = xparse_fxp(numbers[i]);
fxp_t fxp_a = xparse_fxp(numbers[i]);
double double_a = strtod(numbers[i], NULL);
uint32_t fxp_rounded_down = fxp_round_down(fxp_a);
@ -338,37 +336,35 @@ TEST_BEGIN(test_stress) {
"Incorrectly rounded-to-nearest %s", numbers[i]);
for (size_t j = 0; j < numbers_len; j++) {
fxp_t fxp_b = xparse_fxp(numbers[j]);
fxp_t fxp_b = xparse_fxp(numbers[j]);
double double_b = strtod(numbers[j], NULL);
fxp_t fxp_sum = fxp_add(fxp_a, fxp_b);
fxp_t fxp_sum = fxp_add(fxp_a, fxp_b);
double double_sum = double_a + double_b;
expect_true(
double_close(fxp2double(fxp_sum), double_sum),
"Miscomputed %s + %s", numbers[i], numbers[j]);
if (double_a > double_b) {
fxp_t fxp_diff = fxp_sub(fxp_a, fxp_b);
fxp_t fxp_diff = fxp_sub(fxp_a, fxp_b);
double double_diff = double_a - double_b;
expect_true(
double_close(fxp2double(fxp_diff),
double_diff),
expect_true(double_close(fxp2double(fxp_diff),
double_diff),
"Miscomputed %s - %s", numbers[i],
numbers[j]);
}
fxp_t fxp_prod = fxp_mul(fxp_a, fxp_b);
fxp_t fxp_prod = fxp_mul(fxp_a, fxp_b);
double double_prod = double_a * double_b;
expect_true(
double_close(fxp2double(fxp_prod), double_prod),
"Miscomputed %s * %s", numbers[i], numbers[j]);
if (double_b != 0.0) {
fxp_t fxp_quot = fxp_div(fxp_a, fxp_b);
fxp_t fxp_quot = fxp_div(fxp_a, fxp_b);
double double_quot = double_a / double_b;
expect_true(
double_close(fxp2double(fxp_quot),
double_quot),
expect_true(double_close(fxp2double(fxp_quot),
double_quot),
"Miscomputed %s / %s", numbers[i],
numbers[j]);
}
@ -379,16 +375,8 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_parse_valid,
test_parse_invalid,
test_init_percent,
test_add_simple,
test_sub_simple,
test_mul_simple,
test_div_simple,
test_round_simple,
test_mul_frac_simple,
test_print_simple,
test_stress);
return test_no_reentrancy(test_parse_valid, test_parse_invalid,
test_init_percent, test_add_simple, test_sub_simple,
test_mul_simple, test_div_simple, test_round_simple,
test_mul_frac_simple, test_print_simple, test_stress);
}

View file

@ -39,24 +39,32 @@ typedef enum {
static int
hash_variant_bits(hash_variant_t variant) {
switch (variant) {
case hash_variant_x86_32: return 32;
case hash_variant_x86_128: return 128;
case hash_variant_x64_128: return 128;
default: not_reached();
case hash_variant_x86_32:
return 32;
case hash_variant_x86_128:
return 128;
case hash_variant_x64_128:
return 128;
default:
not_reached();
}
}
static const char *
hash_variant_string(hash_variant_t variant) {
switch (variant) {
case hash_variant_x86_32: return "hash_x86_32";
case hash_variant_x86_128: return "hash_x86_128";
case hash_variant_x64_128: return "hash_x64_128";
default: not_reached();
case hash_variant_x86_32:
return "hash_x86_32";
case hash_variant_x86_128:
return "hash_x86_128";
case hash_variant_x64_128:
return "hash_x64_128";
default:
not_reached();
}
}
#define KEY_SIZE 256
#define KEY_SIZE 256
static void
hash_variant_verify_key(hash_variant_t variant, uint8_t *key) {
const int hashbytes = hash_variant_bits(variant) / 8;
@ -79,20 +87,24 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key) {
switch (variant) {
case hash_variant_x86_32: {
uint32_t out;
out = hash_x86_32(key, i, 256-i);
memcpy(&hashes[i*hashbytes], &out, hashbytes);
out = hash_x86_32(key, i, 256 - i);
memcpy(&hashes[i * hashbytes], &out, hashbytes);
break;
} case hash_variant_x86_128: {
}
case hash_variant_x86_128: {
uint64_t out[2];
hash_x86_128(key, i, 256-i, out);
memcpy(&hashes[i*hashbytes], out, hashbytes);
hash_x86_128(key, i, 256 - i, out);
memcpy(&hashes[i * hashbytes], out, hashbytes);
break;
} case hash_variant_x64_128: {
}
case hash_variant_x64_128: {
uint64_t out[2];
hash_x64_128(key, i, 256-i, out);
memcpy(&hashes[i*hashbytes], out, hashbytes);
hash_x64_128(key, i, 256 - i, out);
memcpy(&hashes[i * hashbytes], out, hashbytes);
break;
} default: not_reached();
}
default:
not_reached();
}
}
@ -102,36 +114,50 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key) {
uint32_t out = hash_x86_32(hashes, hashes_size, 0);
memcpy(final, &out, sizeof(out));
break;
} case hash_variant_x86_128: {
}
case hash_variant_x86_128: {
uint64_t out[2];
hash_x86_128(hashes, hashes_size, 0, out);
memcpy(final, out, sizeof(out));
break;
} case hash_variant_x64_128: {
}
case hash_variant_x64_128: {
uint64_t out[2];
hash_x64_128(hashes, hashes_size, 0, out);
memcpy(final, out, sizeof(out));
break;
} default: not_reached();
}
default:
not_reached();
}
computed =
((uint32_t)final[0] << 0) |
((uint32_t)final[1] << 8) |
((uint32_t)final[2] << 16) |
((uint32_t)final[3] << 24);
computed = ((uint32_t) final[0] << 0) | ((uint32_t) final[1] << 8)
| ((uint32_t) final[2] << 16) | ((uint32_t) final[3] << 24);
switch (variant) {
#ifdef JEMALLOC_BIG_ENDIAN
case hash_variant_x86_32: expected = 0x6213303eU; break;
case hash_variant_x86_128: expected = 0x266820caU; break;
case hash_variant_x64_128: expected = 0xcc622b6fU; break;
case hash_variant_x86_32:
expected = 0x6213303eU;
break;
case hash_variant_x86_128:
expected = 0x266820caU;
break;
case hash_variant_x64_128:
expected = 0xcc622b6fU;
break;
#else
case hash_variant_x86_32: expected = 0xb0f57ee3U; break;
case hash_variant_x86_128: expected = 0xb3ece62aU; break;
case hash_variant_x64_128: expected = 0x6384ba69U; break;
case hash_variant_x86_32:
expected = 0xb0f57ee3U;
break;
case hash_variant_x86_128:
expected = 0xb3ece62aU;
break;
case hash_variant_x64_128:
expected = 0x6384ba69U;
break;
#endif
default: not_reached();
default:
not_reached();
}
expect_u32_eq(computed, expected,
@ -141,8 +167,8 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key) {
static void
hash_variant_verify(hash_variant_t variant) {
#define MAX_ALIGN 16
uint8_t key[KEY_SIZE + (MAX_ALIGN - 1)];
#define MAX_ALIGN 16
uint8_t key[KEY_SIZE + (MAX_ALIGN - 1)];
unsigned i;
for (i = 0; i < MAX_ALIGN; i++) {
@ -169,8 +195,5 @@ TEST_END
int
main(void) {
return test(
test_hash_x86_32,
test_hash_x86_128,
test_hash_x64_128);
return test(test_hash_x86_32, test_hash_x86_128, test_hash_x64_128);
}

View file

@ -2,12 +2,12 @@
#include "jemalloc/internal/hook.h"
static void *arg_extra;
static int arg_type;
static void *arg_result;
static void *arg_address;
static size_t arg_old_usize;
static size_t arg_new_usize;
static void *arg_extra;
static int arg_type;
static void *arg_result;
static void *arg_address;
static size_t arg_old_usize;
static size_t arg_new_usize;
static uintptr_t arg_result_raw;
static uintptr_t arg_args_raw[4];
@ -71,8 +71,8 @@ set_args_raw(uintptr_t *args_raw, int nargs) {
static void
expect_args_raw(uintptr_t *args_raw_expected, int nargs) {
int cmp = memcmp(args_raw_expected, arg_args_raw,
sizeof(uintptr_t) * nargs);
int cmp = memcmp(
args_raw_expected, arg_args_raw, sizeof(uintptr_t) * nargs);
expect_d_eq(cmp, 0, "Raw args mismatch");
}
@ -95,8 +95,8 @@ test_alloc_hook(void *extra, hook_alloc_t type, void *result,
}
static void
test_dalloc_hook(void *extra, hook_dalloc_t type, void *address,
uintptr_t args_raw[3]) {
test_dalloc_hook(
void *extra, hook_dalloc_t type, void *address, uintptr_t args_raw[3]) {
call_count++;
arg_extra = extra;
arg_type = (int)type;
@ -122,16 +122,15 @@ test_expand_hook(void *extra, hook_expand_t type, void *address,
TEST_BEGIN(test_hooks_basic) {
/* Just verify that the record their arguments correctly. */
hooks_t hooks = {
&test_alloc_hook, &test_dalloc_hook, &test_expand_hook,
(void *)111};
void *handle = hook_install(TSDN_NULL, &hooks);
hooks_t hooks = {&test_alloc_hook, &test_dalloc_hook, &test_expand_hook,
(void *)111};
void *handle = hook_install(TSDN_NULL, &hooks);
uintptr_t args_raw[4] = {10, 20, 30, 40};
/* Alloc */
reset_args();
hook_invoke_alloc(hook_alloc_posix_memalign, (void *)222, 333,
args_raw);
hook_invoke_alloc(
hook_alloc_posix_memalign, (void *)222, 333, args_raw);
expect_ptr_eq(arg_extra, (void *)111, "Passed wrong user pointer");
expect_d_eq((int)hook_alloc_posix_memalign, arg_type,
"Passed wrong alloc type");
@ -142,18 +141,18 @@ TEST_BEGIN(test_hooks_basic) {
/* Dalloc */
reset_args();
hook_invoke_dalloc(hook_dalloc_sdallocx, (void *)222, args_raw);
expect_d_eq((int)hook_dalloc_sdallocx, arg_type,
"Passed wrong dalloc type");
expect_d_eq(
(int)hook_dalloc_sdallocx, arg_type, "Passed wrong dalloc type");
expect_ptr_eq((void *)111, arg_extra, "Passed wrong user pointer");
expect_ptr_eq((void *)222, arg_address, "Passed wrong address");
expect_args_raw(args_raw, 3);
/* Expand */
reset_args();
hook_invoke_expand(hook_expand_xallocx, (void *)222, 333, 444, 555,
args_raw);
expect_d_eq((int)hook_expand_xallocx, arg_type,
"Passed wrong expand type");
hook_invoke_expand(
hook_expand_xallocx, (void *)222, 333, 444, 555, args_raw);
expect_d_eq(
(int)hook_expand_xallocx, arg_type, "Passed wrong expand type");
expect_ptr_eq((void *)111, arg_extra, "Passed wrong user pointer");
expect_ptr_eq((void *)222, arg_address, "Passed wrong address");
expect_zu_eq(333, arg_old_usize, "Passed wrong old usize");
@ -205,7 +204,7 @@ TEST_END
TEST_BEGIN(test_hooks_remove) {
hooks_t hooks = {&test_alloc_hook, NULL, NULL, NULL};
void *handle = hook_install(TSDN_NULL, &hooks);
void *handle = hook_install(TSDN_NULL, &hooks);
expect_ptr_ne(handle, NULL, "Hook installation failed");
call_count = 0;
uintptr_t args_raw[4] = {10, 20, 30, 40};
@ -216,14 +215,13 @@ TEST_BEGIN(test_hooks_remove) {
hook_remove(TSDN_NULL, handle);
hook_invoke_alloc(hook_alloc_malloc, NULL, 0, NULL);
expect_d_eq(call_count, 0, "Hook invoked after removal");
}
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);
void *handle = hook_install(TSDN_NULL, &hooks);
expect_ptr_ne(handle, NULL, "Hook installation failed");
/* Stop malloc from being optimized away. */
@ -237,8 +235,8 @@ TEST_BEGIN(test_hooks_alloc_simple) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_malloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
free(ptr);
@ -247,11 +245,11 @@ TEST_BEGIN(test_hooks_alloc_simple) {
err = posix_memalign((void **)&ptr, 1024, 1);
expect_d_eq(call_count, 1, "Hook not called");
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_posix_memalign,
"Wrong hook type");
expect_d_eq(
arg_type, (int)hook_alloc_posix_memalign, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)err, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)err, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)&ptr, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)1024, arg_args_raw[1], "Wrong argument");
expect_u64_eq((uintptr_t)1, arg_args_raw[2], "Wrong argument");
@ -262,11 +260,10 @@ TEST_BEGIN(test_hooks_alloc_simple) {
ptr = aligned_alloc(1024, 1);
expect_d_eq(call_count, 1, "Hook not called");
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_aligned_alloc,
"Wrong hook type");
expect_d_eq(arg_type, (int)hook_alloc_aligned_alloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)1024, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong argument");
free(ptr);
@ -278,8 +275,8 @@ TEST_BEGIN(test_hooks_alloc_simple) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_calloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)11, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)13, arg_args_raw[1], "Wrong argument");
free(ptr);
@ -292,8 +289,8 @@ TEST_BEGIN(test_hooks_alloc_simple) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_memalign, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)1024, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong argument");
free(ptr);
@ -307,8 +304,8 @@ TEST_BEGIN(test_hooks_alloc_simple) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_valloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
free(ptr);
#endif /* JEMALLOC_OVERRIDE_VALLOC */
@ -321,8 +318,8 @@ TEST_BEGIN(test_hooks_alloc_simple) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_pvalloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
free(ptr);
#endif /* JEMALLOC_OVERRIDE_PVALLOC */
@ -334,11 +331,11 @@ TEST_BEGIN(test_hooks_alloc_simple) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_mallocx, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)MALLOCX_LG_ALIGN(10), arg_args_raw[1],
"Wrong flags");
expect_u64_eq(
(uintptr_t)MALLOCX_LG_ALIGN(10), arg_args_raw[1], "Wrong flags");
free(ptr);
hook_remove(TSDN_NULL, handle);
@ -348,7 +345,7 @@ 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);
void *handle = hook_install(TSDN_NULL, &hooks);
expect_ptr_ne(handle, NULL, "Hook installation failed");
void *volatile ptr;
@ -372,8 +369,8 @@ TEST_BEGIN(test_hooks_dalloc_simple) {
expect_d_eq(arg_type, (int)hook_dalloc_dallocx, "Wrong hook type");
expect_ptr_eq(ptr, arg_address, "Wrong pointer freed");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");
expect_u64_eq((uintptr_t)MALLOCX_TCACHE_NONE, arg_args_raw[1],
"Wrong raw arg");
expect_u64_eq(
(uintptr_t)MALLOCX_TCACHE_NONE, arg_args_raw[1], "Wrong raw arg");
/* sdallocx() */
reset();
@ -385,8 +382,8 @@ TEST_BEGIN(test_hooks_dalloc_simple) {
expect_ptr_eq(ptr, arg_address, "Wrong pointer freed");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");
expect_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong raw arg");
expect_u64_eq((uintptr_t)MALLOCX_TCACHE_NONE, arg_args_raw[2],
"Wrong raw arg");
expect_u64_eq(
(uintptr_t)MALLOCX_TCACHE_NONE, arg_args_raw[2], "Wrong raw arg");
hook_remove(TSDN_NULL, handle);
}
@ -395,7 +392,7 @@ TEST_END
TEST_BEGIN(test_hooks_expand_simple) {
/* "Simple" in the sense that we're not in a realloc variant. */
hooks_t hooks = {NULL, NULL, &test_expand_hook, (void *)123};
void *handle = hook_install(TSDN_NULL, &hooks);
void *handle = hook_install(TSDN_NULL, &hooks);
expect_ptr_ne(handle, NULL, "Hook installation failed");
void *volatile ptr;
@ -421,9 +418,9 @@ TEST_BEGIN(test_hooks_expand_simple) {
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);
hooks_t hooks = {&test_alloc_hook, &test_dalloc_hook, &test_expand_hook,
(void *)123};
void *handle = hook_install(TSDN_NULL, &hooks);
expect_ptr_ne(handle, NULL, "Hook installation failed");
void *volatile ptr;
@ -435,8 +432,8 @@ TEST_BEGIN(test_hooks_realloc_as_malloc_or_free) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_realloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)NULL, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)1, arg_args_raw[1], "Wrong argument");
free(ptr);
@ -448,14 +445,11 @@ TEST_BEGIN(test_hooks_realloc_as_malloc_or_free) {
realloc(ptr, 0);
expect_d_eq(call_count, 1, "Hook not called");
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_dalloc_realloc,
"Wrong hook type");
expect_ptr_eq(ptr, arg_address,
"Wrong pointer freed");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0],
"Wrong raw arg");
expect_u64_eq((uintptr_t)0, arg_args_raw[1],
"Wrong raw arg");
expect_d_eq(
arg_type, (int)hook_dalloc_realloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_address, "Wrong pointer freed");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong raw arg");
expect_u64_eq((uintptr_t)0, arg_args_raw[1], "Wrong raw arg");
}
/* realloc(NULL, 0) as malloc(0) */
@ -465,8 +459,8 @@ TEST_BEGIN(test_hooks_realloc_as_malloc_or_free) {
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, (int)hook_alloc_realloc, "Wrong hook type");
expect_ptr_eq(ptr, arg_result, "Wrong result");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)NULL, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)0, arg_args_raw[1], "Wrong argument");
free(ptr);
@ -478,9 +472,9 @@ 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);
hooks_t hooks = {&test_alloc_hook, &test_dalloc_hook, &test_expand_hook,
(void *)123};
void *handle = hook_install(TSDN_NULL, &hooks);
expect_ptr_ne(handle, NULL, "Hook installation failed");
void *volatile ptr;
@ -496,8 +490,8 @@ do_realloc_test(void *(*ralloc)(void *, size_t, int), int flags,
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_d_eq(arg_type, expand_type, "Wrong hook type");
expect_ptr_eq(ptr, arg_address, "Wrong address");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)130, arg_args_raw[1], "Wrong argument");
free(ptr);
@ -522,11 +516,11 @@ do_realloc_test(void *(*ralloc)(void *, size_t, int), int flags,
}
expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
expect_ptr_eq(ptr2, arg_address, "Wrong address");
expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)ptr2, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)2 * 1024 * 1024, arg_args_raw[1],
"Wrong argument");
expect_u64_eq(
(uintptr_t)2 * 1024 * 1024, arg_args_raw[1], "Wrong argument");
free(ptr);
/* Realloc with move, small. */
@ -540,8 +534,8 @@ do_realloc_test(void *(*ralloc)(void *, size_t, int), int flags,
expect_d_eq(arg_type, dalloc_type, "Wrong hook type");
expect_ptr_eq(ptr, arg_address, "Wrong address");
expect_ptr_eq(ptr2, arg_result, "Wrong address");
expect_u64_eq((uintptr_t)ptr2, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr2, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)128, arg_args_raw[1], "Wrong argument");
free(ptr2);
@ -557,11 +551,11 @@ do_realloc_test(void *(*ralloc)(void *, size_t, int), int flags,
expect_d_eq(arg_type, dalloc_type, "Wrong hook type");
expect_ptr_eq(ptr, arg_address, "Wrong address");
expect_ptr_eq(ptr2, arg_result, "Wrong address");
expect_u64_eq((uintptr_t)ptr2, (uintptr_t)arg_result_raw,
"Wrong raw result");
expect_u64_eq(
(uintptr_t)ptr2, (uintptr_t)arg_result_raw, "Wrong raw result");
expect_u64_eq((uintptr_t)ptr, arg_args_raw[0], "Wrong argument");
expect_u64_eq((uintptr_t)2 * 1024 * 1024, arg_args_raw[1],
"Wrong argument");
expect_u64_eq(
(uintptr_t)2 * 1024 * 1024, arg_args_raw[1], "Wrong argument");
free(ptr2);
hook_remove(TSDN_NULL, handle);
@ -573,8 +567,8 @@ realloc_wrapper(void *ptr, size_t size, UNUSED int flags) {
}
TEST_BEGIN(test_hooks_realloc) {
do_realloc_test(&realloc_wrapper, 0, hook_expand_realloc,
hook_dalloc_realloc);
do_realloc_test(
&realloc_wrapper, 0, hook_expand_realloc, hook_dalloc_realloc);
}
TEST_END
@ -587,14 +581,9 @@ TEST_END
int
main(void) {
/* We assert on call counts. */
return test_no_reentrancy(
test_hooks_basic,
test_hooks_null,
test_hooks_remove,
test_hooks_alloc_simple,
test_hooks_dalloc_simple,
test_hooks_expand_simple,
test_hooks_realloc_as_malloc_or_free,
test_hooks_realloc,
return test_no_reentrancy(test_hooks_basic, test_hooks_null,
test_hooks_remove, test_hooks_alloc_simple,
test_hooks_dalloc_simple, test_hooks_expand_simple,
test_hooks_realloc_as_malloc_or_free, test_hooks_realloc,
test_hooks_rallocx);
}

View file

@ -13,55 +13,53 @@ struct test_data_s {
* Must be the first member -- we convert back and forth between the
* test_data_t and the hpa_shard_t;
*/
hpa_shard_t shard;
hpa_shard_t shard;
hpa_central_t central;
base_t *base;
base_t *base;
edata_cache_t shard_edata_cache;
emap_t emap;
};
static hpa_shard_opts_t test_hpa_shard_opts_default = {
/* slab_max_alloc */
ALLOC_MAX,
/* hugification_threshold */
HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(25),
/* deferral_allowed */
false,
/* hugify_delay_ms */
10 * 1000,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1
};
/* slab_max_alloc */
ALLOC_MAX,
/* hugification_threshold */
HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(25),
/* deferral_allowed */
false,
/* hugify_delay_ms */
10 * 1000,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1};
static hpa_shard_opts_t test_hpa_shard_opts_purge = {
/* slab_max_alloc */
HUGEPAGE,
/* hugification_threshold */
0.9 * HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(11),
/* deferral_allowed */
true,
/* hugify_delay_ms */
0,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1
};
/* slab_max_alloc */
HUGEPAGE,
/* hugification_threshold */
0.9 * HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(11),
/* deferral_allowed */
true,
/* hugify_delay_ms */
0,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1};
static hpa_shard_t *
create_test_data(const hpa_hooks_t *hooks, hpa_shard_opts_t *opts) {
bool err;
bool err;
base_t *base = base_new(TSDN_NULL, /* ind */ SHARD_IND,
&ehooks_default_extent_hooks, /* metadata_use_hooks */ true);
assert_ptr_not_null(base, "");
@ -98,8 +96,8 @@ destroy_test_data(hpa_shard_t *shard) {
TEST_BEGIN(test_alloc_max) {
test_skip_if(!hpa_supported());
hpa_shard_t *shard = create_test_data(&hpa_hooks_default,
&test_hpa_shard_opts_default);
hpa_shard_t *shard = create_test_data(
&hpa_hooks_default, &test_hpa_shard_opts_default);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edata;
@ -107,19 +105,19 @@ TEST_BEGIN(test_alloc_max) {
/* Small max */
bool deferred_work_generated = false;
edata = pai_alloc(tsdn, &shard->pai, ALLOC_MAX, PAGE, false, false,
/* frequent_reuse */ false, &deferred_work_generated);
/* frequent_reuse */ false, &deferred_work_generated);
expect_ptr_not_null(edata, "Allocation of small max failed");
edata = pai_alloc(tsdn, &shard->pai, ALLOC_MAX + PAGE, PAGE, false,
false, /* frequent_reuse */ false, &deferred_work_generated);
expect_ptr_null(edata, "Allocation of larger than small max succeeded");
edata = pai_alloc(tsdn, &shard->pai, ALLOC_MAX, PAGE, false,
false, /* frequent_reuse */ true, &deferred_work_generated);
edata = pai_alloc(tsdn, &shard->pai, ALLOC_MAX, PAGE, false, false,
/* frequent_reuse */ true, &deferred_work_generated);
expect_ptr_not_null(edata, "Allocation of frequent reused failed");
edata = pai_alloc(tsdn, &shard->pai, HUGEPAGE, PAGE, false,
false, /* frequent_reuse */ true, &deferred_work_generated);
edata = pai_alloc(tsdn, &shard->pai, HUGEPAGE, PAGE, false, false,
/* frequent_reuse */ true, &deferred_work_generated);
expect_ptr_not_null(edata, "Allocation of frequent reused failed");
edata = pai_alloc(tsdn, &shard->pai, HUGEPAGE + PAGE, PAGE, false,
@ -133,8 +131,8 @@ TEST_END
typedef struct mem_contents_s mem_contents_t;
struct mem_contents_s {
uintptr_t my_addr;
size_t size;
edata_t *my_edata;
size_t size;
edata_t *my_edata;
rb_node(mem_contents_t) link;
};
@ -144,8 +142,7 @@ mem_contents_cmp(const mem_contents_t *a, const mem_contents_t *b) {
}
typedef rb_tree(mem_contents_t) mem_tree_t;
rb_gen(static, mem_tree_, mem_tree_t, mem_contents_t, link,
mem_contents_cmp);
rb_gen(static, mem_tree_, mem_tree_t, mem_contents_t, link, mem_contents_cmp);
static void
node_assert_ordered(mem_contents_t *a, mem_contents_t *b) {
@ -191,14 +188,14 @@ node_remove(mem_tree_t *tree, edata_t *edata) {
TEST_BEGIN(test_stress) {
test_skip_if(!hpa_supported());
hpa_shard_t *shard = create_test_data(&hpa_hooks_default,
&test_hpa_shard_opts_default);
hpa_shard_t *shard = create_test_data(
&hpa_hooks_default, &test_hpa_shard_opts_default);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
const size_t nlive_edatas_max = 500;
size_t nlive_edatas = 0;
edata_t **live_edatas = calloc(nlive_edatas_max, sizeof(edata_t *));
size_t nlive_edatas = 0;
edata_t **live_edatas = calloc(nlive_edatas_max, sizeof(edata_t *));
/*
* Nothing special about this constant; we're only fixing it for
* consistency across runs.
@ -224,13 +221,14 @@ TEST_BEGIN(test_stress) {
*/
size_t npages_min = 1;
size_t npages_max = ALLOC_MAX / PAGE;
size_t npages = npages_min + prng_range_zu(&prng_state,
npages_max - npages_min);
size_t npages = npages_min
+ prng_range_zu(
&prng_state, npages_max - npages_min);
edata_t *edata = pai_alloc(tsdn, &shard->pai,
npages * PAGE, PAGE, false, false, false,
&deferred_work_generated);
assert_ptr_not_null(edata,
"Unexpected allocation failure");
assert_ptr_not_null(
edata, "Unexpected allocation failure");
live_edatas[nlive_edatas] = edata;
nlive_edatas++;
node_insert(&tree, edata, npages);
@ -239,7 +237,8 @@ TEST_BEGIN(test_stress) {
if (nlive_edatas == 0) {
continue;
}
size_t victim = prng_range_zu(&prng_state, nlive_edatas);
size_t victim = prng_range_zu(
&prng_state, nlive_edatas);
edata_t *to_free = live_edatas[victim];
live_edatas[victim] = live_edatas[nlive_edatas - 1];
nlive_edatas--;
@ -251,7 +250,7 @@ TEST_BEGIN(test_stress) {
size_t ntreenodes = 0;
for (mem_contents_t *contents = mem_tree_first(&tree); contents != NULL;
contents = mem_tree_next(&tree, contents)) {
contents = mem_tree_next(&tree, contents)) {
ntreenodes++;
node_check(&tree, contents);
}
@ -264,8 +263,8 @@ TEST_BEGIN(test_stress) {
for (size_t i = 0; i < nlive_edatas; i++) {
edata_t *to_free = live_edatas[i];
node_remove(&tree, to_free);
pai_dalloc(tsdn, &shard->pai, to_free,
&deferred_work_generated);
pai_dalloc(
tsdn, &shard->pai, to_free, &deferred_work_generated);
}
hpa_shard_destroy(tsdn, shard);
@ -277,8 +276,7 @@ TEST_END
static void
expect_contiguous(edata_t **edatas, size_t nedatas) {
for (size_t i = 0; i < nedatas; i++) {
size_t expected = (size_t)edata_base_get(edatas[0])
+ i * PAGE;
size_t expected = (size_t)edata_base_get(edatas[0]) + i * PAGE;
expect_zu_eq(expected, (size_t)edata_base_get(edatas[i]),
"Mismatch at index %zu", i);
}
@ -287,13 +285,13 @@ expect_contiguous(edata_t **edatas, size_t nedatas) {
TEST_BEGIN(test_alloc_dalloc_batch) {
test_skip_if(!hpa_supported());
hpa_shard_t *shard = create_test_data(&hpa_hooks_default,
&test_hpa_shard_opts_default);
hpa_shard_t *shard = create_test_data(
&hpa_hooks_default, &test_hpa_shard_opts_default);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
bool deferred_work_generated = false;
enum {NALLOCS = 8};
enum { NALLOCS = 8 };
edata_t *allocs[NALLOCS];
/*
@ -329,11 +327,11 @@ TEST_BEGIN(test_alloc_dalloc_batch) {
for (size_t i = 0; i < NALLOCS / 2; i++) {
edata_list_active_append(&allocs_list, allocs[i]);
}
pai_dalloc_batch(tsdn, &shard->pai, &allocs_list,
&deferred_work_generated);
pai_dalloc_batch(
tsdn, &shard->pai, &allocs_list, &deferred_work_generated);
for (size_t i = NALLOCS / 2; i < NALLOCS; i++) {
pai_dalloc(tsdn, &shard->pai, allocs[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &shard->pai, allocs[i], &deferred_work_generated);
}
/* Reallocate (individually), and ensure reuse and contiguity. */
@ -344,8 +342,8 @@ TEST_BEGIN(test_alloc_dalloc_batch) {
expect_ptr_not_null(allocs[i], "Unexpected alloc failure.");
}
void *new_base = edata_base_get(allocs[0]);
expect_ptr_eq(orig_base, new_base,
"Failed to reuse the allocated memory.");
expect_ptr_eq(
orig_base, new_base, "Failed to reuse the allocated memory.");
expect_contiguous(allocs, NALLOCS);
destroy_test_data(shard);
@ -429,7 +427,7 @@ TEST_BEGIN(test_defer_time) {
bool deferred_work_generated = false;
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edatas[HUGEPAGE_PAGES];
for (int i = 0; i < (int)HUGEPAGE_PAGES; i++) {
edatas[i] = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
@ -448,8 +446,8 @@ TEST_BEGIN(test_defer_time) {
/* Purge. Recall that dirty_mult is .25. */
for (int i = 0; i < (int)HUGEPAGE_PAGES / 2; i++) {
pai_dalloc(tsdn, &shard->pai, edatas[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &shard->pai, edatas[i], &deferred_work_generated);
}
hpa_shard_do_deferred_work(tsdn, shard);
@ -474,8 +472,7 @@ TEST_BEGIN(test_defer_time) {
* We would be ineligible for hugification, had we not already met the
* threshold before dipping below it.
*/
pai_dalloc(tsdn, &shard->pai, edatas[0],
&deferred_work_generated);
pai_dalloc(tsdn, &shard->pai, edatas[0], &deferred_work_generated);
/* Wait for the threshold again. */
nstime_init2(&defer_curtime, 22, 0);
hpa_shard_do_deferred_work(tsdn, shard);
@ -491,8 +488,8 @@ TEST_END
TEST_BEGIN(test_purge_no_infinite_loop) {
test_skip_if(!hpa_supported());
hpa_shard_t *shard = create_test_data(&hpa_hooks_default,
&test_hpa_shard_opts_purge);
hpa_shard_t *shard = create_test_data(
&hpa_hooks_default, &test_hpa_shard_opts_purge);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
/*
@ -500,14 +497,15 @@ TEST_BEGIN(test_purge_no_infinite_loop) {
* criteria for huge page and at the same time do not allow hugify page
* without triggering a purge.
*/
const size_t npages =
test_hpa_shard_opts_purge.hugification_threshold / PAGE + 1;
const size_t npages = test_hpa_shard_opts_purge.hugification_threshold
/ PAGE
+ 1;
const size_t size = npages * PAGE;
bool deferred_work_generated = false;
bool deferred_work_generated = false;
edata_t *edata = pai_alloc(tsdn, &shard->pai, size, PAGE,
/* zero */ false, /* guarded */ false, /* frequent_reuse */ false,
&deferred_work_generated);
/* zero */ false, /* guarded */ false, /* frequent_reuse */ false,
&deferred_work_generated);
expect_ptr_not_null(edata, "Unexpected alloc failure");
hpa_shard_do_deferred_work(tsdn, shard);
@ -542,8 +540,8 @@ TEST_BEGIN(test_no_min_purge_interval) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
false, false, &deferred_work_generated);
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false, false,
false, &deferred_work_generated);
expect_ptr_not_null(edata, "Unexpected null edata");
pai_dalloc(tsdn, &shard->pai, edata, &deferred_work_generated);
hpa_shard_do_deferred_work(tsdn, shard);
@ -584,8 +582,8 @@ TEST_BEGIN(test_min_purge_interval) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
false, false, &deferred_work_generated);
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false, false,
false, &deferred_work_generated);
expect_ptr_not_null(edata, "Unexpected null edata");
pai_dalloc(tsdn, &shard->pai, edata, &deferred_work_generated);
hpa_shard_do_deferred_work(tsdn, shard);
@ -634,7 +632,7 @@ TEST_BEGIN(test_purge) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
enum {NALLOCS = 8 * HUGEPAGE_PAGES};
enum { NALLOCS = 8 * HUGEPAGE_PAGES };
edata_t *edatas[NALLOCS];
for (int i = 0; i < NALLOCS; i++) {
edatas[i] = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
@ -643,8 +641,8 @@ TEST_BEGIN(test_purge) {
}
/* Deallocate 3 hugepages out of 8. */
for (int i = 0; i < 3 * (int)HUGEPAGE_PAGES; i++) {
pai_dalloc(tsdn, &shard->pai, edatas[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &shard->pai, edatas[i], &deferred_work_generated);
}
nstime_init2(&defer_curtime, 6, 0);
hpa_shard_do_deferred_work(tsdn, shard);
@ -702,7 +700,7 @@ TEST_BEGIN(test_experimental_max_purge_nhp) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
enum {NALLOCS = 8 * HUGEPAGE_PAGES};
enum { NALLOCS = 8 * HUGEPAGE_PAGES };
edata_t *edatas[NALLOCS];
for (int i = 0; i < NALLOCS; i++) {
edatas[i] = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
@ -711,8 +709,8 @@ TEST_BEGIN(test_experimental_max_purge_nhp) {
}
/* Deallocate 3 hugepages out of 8. */
for (int i = 0; i < 3 * (int)HUGEPAGE_PAGES; i++) {
pai_dalloc(tsdn, &shard->pai, edatas[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &shard->pai, edatas[i], &deferred_work_generated);
}
nstime_init2(&defer_curtime, 6, 0);
hpa_shard_do_deferred_work(tsdn, shard);
@ -749,8 +747,7 @@ TEST_BEGIN(test_experimental_max_purge_nhp) {
TEST_END
TEST_BEGIN(test_vectorized_opt_eq_zero) {
test_skip_if(!hpa_supported() ||
(opt_process_madvise_max_batch != 0));
test_skip_if(!hpa_supported() || (opt_process_madvise_max_batch != 0));
hpa_hooks_t hooks;
hooks.map = &defer_test_map;
@ -770,11 +767,11 @@ TEST_BEGIN(test_vectorized_opt_eq_zero) {
ndefer_purge_calls = 0;
hpa_shard_t *shard = create_test_data(&hooks, &opts);
bool deferred_work_generated = false;
bool deferred_work_generated = false;
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
false, false, &deferred_work_generated);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false, false,
false, &deferred_work_generated);
expect_ptr_not_null(edata, "Unexpected null edata");
pai_dalloc(tsdn, &shard->pai, edata, &deferred_work_generated);
hpa_shard_do_deferred_work(tsdn, shard);
@ -800,15 +797,9 @@ main(void) {
(void)mem_tree_iter;
(void)mem_tree_reverse_iter;
(void)mem_tree_destroy;
return test_no_reentrancy(
test_alloc_max,
test_stress,
test_alloc_dalloc_batch,
test_defer_time,
test_purge_no_infinite_loop,
test_no_min_purge_interval,
test_min_purge_interval,
test_purge,
test_experimental_max_purge_nhp,
test_vectorized_opt_eq_zero);
return test_no_reentrancy(test_alloc_max, test_stress,
test_alloc_dalloc_batch, test_defer_time,
test_purge_no_infinite_loop, test_no_min_purge_interval,
test_min_purge_interval, test_purge,
test_experimental_max_purge_nhp, test_vectorized_opt_eq_zero);
}

View file

@ -12,7 +12,7 @@ TEST_BEGIN(test_hpa_background_thread_a0_initialized) {
test_skip_if(!have_background_thread);
test_skip_if(san_guard_enabled());
bool enabled = false;
bool enabled = false;
size_t sz = sizeof(enabled);
int err = mallctl("background_thread", (void *)&enabled, &sz, NULL, 0);
expect_d_eq(err, 0, "Unexpected mallctl() failure");
@ -38,7 +38,7 @@ sleep_for_background_thread_interval(void) {
static unsigned
create_arena(void) {
unsigned arena_ind;
size_t sz;
size_t sz;
sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz, NULL, 2),
@ -48,17 +48,17 @@ create_arena(void) {
static size_t
get_empty_ndirty(unsigned arena_ind) {
int err;
size_t ndirty_huge;
size_t ndirty_nonhuge;
int err;
size_t ndirty_huge;
size_t ndirty_nonhuge;
uint64_t epoch = 1;
size_t sz = sizeof(epoch);
err = je_mallctl("epoch", (void *)&epoch, &sz, (void *)&epoch,
sizeof(epoch));
size_t sz = sizeof(epoch);
err = je_mallctl(
"epoch", (void *)&epoch, &sz, (void *)&epoch, sizeof(epoch));
expect_d_eq(0, err, "Unexpected mallctl() failure");
size_t mib[6];
size_t miblen = sizeof(mib)/sizeof(mib[0]);
size_t miblen = sizeof(mib) / sizeof(mib[0]);
err = mallctlnametomib(
"stats.arenas.0.hpa_shard.empty_slabs.ndirty_nonhuge", mib,
&miblen);
@ -70,8 +70,7 @@ get_empty_ndirty(unsigned arena_ind) {
expect_d_eq(0, err, "Unexpected mallctlbymib() failure");
err = mallctlnametomib(
"stats.arenas.0.hpa_shard.empty_slabs.ndirty_huge", mib,
&miblen);
"stats.arenas.0.hpa_shard.empty_slabs.ndirty_huge", mib, &miblen);
expect_d_eq(0, err, "Unexpected mallctlnametomib() failure");
sz = sizeof(ndirty_huge);
@ -85,20 +84,20 @@ get_empty_ndirty(unsigned arena_ind) {
static void
set_background_thread_enabled(bool enabled) {
int err;
err = je_mallctl("background_thread", NULL, NULL, &enabled,
sizeof(enabled));
err = je_mallctl(
"background_thread", NULL, NULL, &enabled, sizeof(enabled));
expect_d_eq(0, err, "Unexpected mallctl failure");
}
static void
wait_until_thread_is_enabled(unsigned arena_id) {
tsd_t* tsd = tsd_fetch();
tsd_t *tsd = tsd_fetch();
bool sleeping = false;
int iterations = 0;
int iterations = 0;
do {
background_thread_info_t *info =
background_thread_info_get(arena_id);
background_thread_info_t *info = background_thread_info_get(
arena_id);
malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
sleeping = background_thread_indefinite_sleep(info);
@ -113,10 +112,8 @@ expect_purging(unsigned arena_ind) {
expect_zu_eq(0, empty_ndirty, "Expected arena to start unused.");
void *ptrs[2];
ptrs[0] = mallocx(PAGE,
MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena_ind));
ptrs[1] = mallocx(PAGE,
MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena_ind));
ptrs[0] = mallocx(PAGE, MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena_ind));
ptrs[1] = mallocx(PAGE, MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena_ind));
empty_ndirty = get_empty_ndirty(arena_ind);
expect_zu_eq(0, empty_ndirty, "All pages should be active");
@ -151,15 +148,14 @@ expect_deferred_purging(unsigned arena_ind) {
*/
bool observed_dirty_page = false;
for (int i = 0; i < 10; i++) {
void *ptr = mallocx(PAGE,
MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena_ind));
void *ptr = mallocx(
PAGE, MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena_ind));
empty_ndirty = get_empty_ndirty(arena_ind);
expect_zu_eq(0, empty_ndirty, "All pages should be active");
dallocx(ptr, MALLOCX_TCACHE_NONE);
empty_ndirty = get_empty_ndirty(arena_ind);
expect_true(empty_ndirty == 0 || empty_ndirty == 1 ||
opt_prof, "Unexpected extra dirty page count: %zu",
empty_ndirty);
expect_true(empty_ndirty == 0 || empty_ndirty == 1 || opt_prof,
"Unexpected extra dirty page count: %zu", empty_ndirty);
if (empty_ndirty > 0) {
observed_dirty_page = true;
break;
@ -173,8 +169,8 @@ expect_deferred_purging(unsigned arena_ind) {
* time. Retry 100 times max before bailing out.
*/
unsigned retry = 0;
while ((empty_ndirty = get_empty_ndirty(arena_ind)) > 0 &&
(retry++ < 100)) {
while ((empty_ndirty = get_empty_ndirty(arena_ind)) > 0
&& (retry++ < 100)) {
sleep_for_background_thread_interval();
}

View file

@ -13,36 +13,35 @@ struct test_data_s {
* Must be the first member -- we convert back and forth between the
* test_data_t and the hpa_shard_t;
*/
hpa_shard_t shard;
hpa_shard_t shard;
hpa_central_t central;
base_t *base;
base_t *base;
edata_cache_t shard_edata_cache;
emap_t emap;
};
static hpa_shard_opts_t test_hpa_shard_opts_default = {
/* slab_max_alloc */
ALLOC_MAX,
/* hugification_threshold */
HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(25),
/* deferral_allowed */
false,
/* hugify_delay_ms */
10 * 1000,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1
};
/* slab_max_alloc */
ALLOC_MAX,
/* hugification_threshold */
HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(25),
/* deferral_allowed */
false,
/* hugify_delay_ms */
10 * 1000,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1};
static hpa_shard_t *
create_test_data(const hpa_hooks_t *hooks, hpa_shard_opts_t *opts) {
bool err;
bool err;
base_t *base = base_new(TSDN_NULL, /* ind */ SHARD_IND,
&ehooks_default_extent_hooks, /* metadata_use_hooks */ true);
assert_ptr_not_null(base, "");
@ -108,7 +107,8 @@ defer_vectorized_purge(void *vec, size_t vlen, size_t nbytes) {
}
static bool defer_vec_purge_didfail = false;
static bool defer_vectorized_purge_fail(void *vec, size_t vlen, size_t nbytes) {
static bool
defer_vectorized_purge_fail(void *vec, size_t vlen, size_t nbytes) {
(void)vec;
(void)vlen;
(void)nbytes;
@ -141,8 +141,7 @@ defer_test_ms_since(nstime_t *past_time) {
}
TEST_BEGIN(test_vectorized_failure_fallback) {
test_skip_if(!hpa_supported() ||
(opt_process_madvise_max_batch == 0));
test_skip_if(!hpa_supported() || (opt_process_madvise_max_batch == 0));
hpa_hooks_t hooks;
hooks.map = &defer_test_map;
@ -166,8 +165,8 @@ TEST_BEGIN(test_vectorized_failure_fallback) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
false, false, &deferred_work_generated);
edata_t *edata = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false, false,
false, &deferred_work_generated);
expect_ptr_not_null(edata, "Unexpected null edata");
pai_dalloc(tsdn, &shard->pai, edata, &deferred_work_generated);
hpa_shard_do_deferred_work(tsdn, shard);
@ -181,9 +180,8 @@ TEST_BEGIN(test_vectorized_failure_fallback) {
TEST_END
TEST_BEGIN(test_more_regions_purged_from_one_page) {
test_skip_if(!hpa_supported() ||
(opt_process_madvise_max_batch == 0) ||
HUGEPAGE_PAGES <= 4);
test_skip_if(!hpa_supported() || (opt_process_madvise_max_batch == 0)
|| HUGEPAGE_PAGES <= 4);
hpa_hooks_t hooks;
hooks.map = &defer_test_map;
@ -208,7 +206,7 @@ TEST_BEGIN(test_more_regions_purged_from_one_page) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
enum {NALLOCS = 8 * HUGEPAGE_PAGES};
enum { NALLOCS = 8 * HUGEPAGE_PAGES };
edata_t *edatas[NALLOCS];
for (int i = 0; i < NALLOCS; i++) {
edatas[i] = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
@ -249,12 +247,10 @@ TEST_BEGIN(test_more_regions_purged_from_one_page) {
}
TEST_END
size_t
hpa_purge_max_batch_size_for_test_set(size_t new_size);
size_t hpa_purge_max_batch_size_for_test_set(size_t new_size);
TEST_BEGIN(test_more_pages_than_batch_page_size) {
test_skip_if(!hpa_supported() ||
(opt_process_madvise_max_batch == 0) ||
HUGEPAGE_PAGES <= 4);
test_skip_if(!hpa_supported() || (opt_process_madvise_max_batch == 0)
|| HUGEPAGE_PAGES <= 4);
size_t old_page_batch = hpa_purge_max_batch_size_for_test_set(1);
@ -281,7 +277,7 @@ TEST_BEGIN(test_more_pages_than_batch_page_size) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
enum {NALLOCS = 8 * HUGEPAGE_PAGES};
enum { NALLOCS = 8 * HUGEPAGE_PAGES };
edata_t *edatas[NALLOCS];
for (int i = 0; i < NALLOCS; i++) {
edatas[i] = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
@ -289,8 +285,8 @@ TEST_BEGIN(test_more_pages_than_batch_page_size) {
expect_ptr_not_null(edatas[i], "Unexpected null edata");
}
for (int i = 0; i < 3 * (int)HUGEPAGE_PAGES; i++) {
pai_dalloc(tsdn, &shard->pai, edatas[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &shard->pai, edatas[i], &deferred_work_generated);
}
hpa_shard_do_deferred_work(tsdn, shard);
@ -321,8 +317,7 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_vectorized_failure_fallback,
return test_no_reentrancy(test_vectorized_failure_fallback,
test_more_regions_purged_from_one_page,
test_more_pages_than_batch_page_size);
}

View file

@ -13,36 +13,35 @@ struct test_data_s {
* Must be the first member -- we convert back and forth between the
* test_data_t and the hpa_shard_t;
*/
hpa_shard_t shard;
hpa_shard_t shard;
hpa_central_t central;
base_t *base;
base_t *base;
edata_cache_t shard_edata_cache;
emap_t emap;
};
static hpa_shard_opts_t test_hpa_shard_opts_default = {
/* slab_max_alloc */
ALLOC_MAX,
/* hugification_threshold */
HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(25),
/* deferral_allowed */
false,
/* hugify_delay_ms */
10 * 1000,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1
};
/* slab_max_alloc */
ALLOC_MAX,
/* hugification_threshold */
HUGEPAGE,
/* dirty_mult */
FXP_INIT_PERCENT(25),
/* deferral_allowed */
false,
/* hugify_delay_ms */
10 * 1000,
/* hugify_sync */
false,
/* min_purge_interval_ms */
5 * 1000,
/* experimental_max_purge_nhp */
-1};
static hpa_shard_t *
create_test_data(const hpa_hooks_t *hooks, hpa_shard_opts_t *opts) {
bool err;
bool err;
base_t *base = base_new(TSDN_NULL, /* ind */ SHARD_IND,
&ehooks_default_extent_hooks, /* metadata_use_hooks */ true);
assert_ptr_not_null(base, "");
@ -132,8 +131,8 @@ defer_test_ms_since(nstime_t *past_time) {
}
TEST_BEGIN(test_vectorized_purge) {
test_skip_if(!hpa_supported() ||
opt_process_madvise_max_batch == 0 || HUGEPAGE_PAGES <= 4);
test_skip_if(!hpa_supported() || opt_process_madvise_max_batch == 0
|| HUGEPAGE_PAGES <= 4);
assert(opt_process_madvise_max_batch == 64);
hpa_hooks_t hooks;
@ -159,7 +158,7 @@ TEST_BEGIN(test_vectorized_purge) {
nstime_init(&defer_curtime, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
enum {NALLOCS = 8 * HUGEPAGE_PAGES};
enum { NALLOCS = 8 * HUGEPAGE_PAGES };
edata_t *edatas[NALLOCS];
for (int i = 0; i < NALLOCS; i++) {
edatas[i] = pai_alloc(tsdn, &shard->pai, PAGE, PAGE, false,
@ -192,6 +191,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_vectorized_purge);
return test_no_reentrancy(test_vectorized_purge);
}

View file

@ -69,23 +69,25 @@ TEST_BEGIN(test_purge_simple) {
hpdata_alloc_allowed_set(&hpdata, false);
hpdata_purge_state_t purge_state;
size_t nranges;
size_t nranges;
size_t to_purge = hpdata_purge_begin(&hpdata, &purge_state, &nranges);
expect_zu_eq(HUGEPAGE_PAGES / 4, to_purge, "");
expect_zu_eq(1, nranges, "All dirty pages in a single range");
void *purge_addr;
void *purge_addr;
size_t purge_size;
bool got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
bool got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_true(got_result, "");
expect_ptr_eq(HPDATA_ADDR, purge_addr, "");
expect_zu_eq(HUGEPAGE_PAGES / 4 * PAGE, purge_size, "");
got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
expect_false(got_result, "Unexpected additional purge range: "
"extent at %p of size %zu", purge_addr, purge_size);
got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_false(got_result,
"Unexpected additional purge range: "
"extent at %p of size %zu",
purge_addr, purge_size);
hpdata_purge_end(&hpdata, &purge_state);
expect_zu_eq(hpdata_ntouched_get(&hpdata), HUGEPAGE_PAGES / 4, "");
@ -102,7 +104,8 @@ TEST_BEGIN(test_purge_intervening_dalloc) {
hpdata_init(&hpdata, HPDATA_ADDR, HPDATA_AGE);
/* Allocate the first 3/4 of the pages. */
void *alloc = hpdata_reserve_alloc(&hpdata, 3 * HUGEPAGE_PAGES / 4 * PAGE);
void *alloc = hpdata_reserve_alloc(
&hpdata, 3 * HUGEPAGE_PAGES / 4 * PAGE);
expect_ptr_eq(alloc, HPDATA_ADDR, "");
/* Free the first 1/4 and the third 1/4 of the pages. */
@ -115,16 +118,16 @@ TEST_BEGIN(test_purge_intervening_dalloc) {
hpdata_alloc_allowed_set(&hpdata, false);
hpdata_purge_state_t purge_state;
size_t nranges;
size_t nranges;
size_t to_purge = hpdata_purge_begin(&hpdata, &purge_state, &nranges);
expect_zu_eq(HUGEPAGE_PAGES / 2, to_purge, "");
expect_zu_eq(2, nranges, "First quarter and last half");
void *purge_addr;
void *purge_addr;
size_t purge_size;
/* First purge. */
bool got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
bool got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_true(got_result, "");
expect_ptr_eq(HPDATA_ADDR, purge_addr, "");
expect_zu_eq(HUGEPAGE_PAGES / 4 * PAGE, purge_size, "");
@ -135,18 +138,20 @@ TEST_BEGIN(test_purge_intervening_dalloc) {
HUGEPAGE_PAGES / 4 * PAGE);
/* Now continue purging. */
got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_true(got_result, "");
expect_ptr_eq(
(void *)((uintptr_t)alloc + 2 * HUGEPAGE_PAGES / 4 * PAGE),
purge_addr, "");
expect_zu_ge(HUGEPAGE_PAGES / 4 * PAGE, purge_size, "");
got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
expect_false(got_result, "Unexpected additional purge range: "
"extent at %p of size %zu", purge_addr, purge_size);
got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_false(got_result,
"Unexpected additional purge range: "
"extent at %p of size %zu",
purge_addr, purge_size);
hpdata_purge_end(&hpdata, &purge_state);
@ -155,19 +160,20 @@ TEST_BEGIN(test_purge_intervening_dalloc) {
TEST_END
TEST_BEGIN(test_purge_over_retained) {
void *purge_addr;
void *purge_addr;
size_t purge_size;
hpdata_t hpdata;
hpdata_init(&hpdata, HPDATA_ADDR, HPDATA_AGE);
/* Allocate the first 3/4 of the pages. */
void *alloc = hpdata_reserve_alloc(&hpdata, 3 * HUGEPAGE_PAGES / 4 * PAGE);
void *alloc = hpdata_reserve_alloc(
&hpdata, 3 * HUGEPAGE_PAGES / 4 * PAGE);
expect_ptr_eq(alloc, HPDATA_ADDR, "");
/* Free the second quarter. */
void *second_quarter =
(void *)((uintptr_t)alloc + HUGEPAGE_PAGES / 4 * PAGE);
void *second_quarter = (void *)((uintptr_t)alloc
+ HUGEPAGE_PAGES / 4 * PAGE);
hpdata_unreserve(&hpdata, second_quarter, HUGEPAGE_PAGES / 4 * PAGE);
expect_zu_eq(hpdata_ntouched_get(&hpdata), 3 * HUGEPAGE_PAGES / 4, "");
@ -175,21 +181,24 @@ TEST_BEGIN(test_purge_over_retained) {
/* Purge the second quarter. */
hpdata_alloc_allowed_set(&hpdata, false);
hpdata_purge_state_t purge_state;
size_t nranges;
size_t to_purge_dirty = hpdata_purge_begin(&hpdata, &purge_state, &nranges);
size_t nranges;
size_t to_purge_dirty = hpdata_purge_begin(
&hpdata, &purge_state, &nranges);
expect_zu_eq(HUGEPAGE_PAGES / 4, to_purge_dirty, "");
expect_zu_eq(1, nranges, "Second quarter only");
bool got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
bool got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_true(got_result, "");
expect_ptr_eq(second_quarter, purge_addr, "");
expect_zu_eq(HUGEPAGE_PAGES / 4 * PAGE, purge_size, "");
got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
expect_false(got_result, "Unexpected additional purge range: "
"extent at %p of size %zu", purge_addr, purge_size);
got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_false(got_result,
"Unexpected additional purge range: "
"extent at %p of size %zu",
purge_addr, purge_size);
hpdata_purge_end(&hpdata, &purge_state);
expect_zu_eq(hpdata_ntouched_get(&hpdata), HUGEPAGE_PAGES / 2, "");
@ -209,16 +218,18 @@ TEST_BEGIN(test_purge_over_retained) {
expect_zu_eq(HUGEPAGE_PAGES / 2, to_purge_dirty, "");
expect_zu_eq(1, nranges, "Single range expected");
got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_true(got_result, "");
expect_ptr_eq(HPDATA_ADDR, purge_addr, "");
expect_zu_eq(3 * HUGEPAGE_PAGES / 4 * PAGE, purge_size, "");
got_result = hpdata_purge_next(&hpdata, &purge_state, &purge_addr,
&purge_size);
expect_false(got_result, "Unexpected additional purge range: "
"extent at %p of size %zu", purge_addr, purge_size);
got_result = hpdata_purge_next(
&hpdata, &purge_state, &purge_addr, &purge_size);
expect_false(got_result,
"Unexpected additional purge range: "
"extent at %p of size %zu",
purge_addr, purge_size);
hpdata_purge_end(&hpdata, &purge_state);
expect_zu_eq(hpdata_ntouched_get(&hpdata), 0, "");
@ -241,11 +252,9 @@ TEST_BEGIN(test_hugify) {
}
TEST_END
int main(void) {
return test_no_reentrancy(
test_reserve_alloc,
test_purge_simple,
test_purge_intervening_dalloc,
test_purge_over_retained,
int
main(void) {
return test_no_reentrancy(test_reserve_alloc, test_purge_simple,
test_purge_intervening_dalloc, test_purge_over_retained,
test_hugify);
}

View file

@ -8,38 +8,40 @@ const char *malloc_conf = "oversize_threshold:2097152";
TEST_BEGIN(huge_bind_thread) {
unsigned arena1, arena2;
size_t sz = sizeof(unsigned);
size_t sz = sizeof(unsigned);
/* Bind to a manual arena. */
expect_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
"Failed to create arena");
expect_d_eq(mallctl("thread.arena", NULL, NULL, &arena1,
sizeof(arena1)), 0, "Fail to bind thread");
expect_d_eq(
mallctl("thread.arena", NULL, NULL, &arena1, sizeof(arena1)), 0,
"Fail to bind thread");
void *ptr = mallocx(HUGE_SZ, 0);
expect_ptr_not_null(ptr, "Fail to allocate huge size");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
sizeof(ptr)), 0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr, sizeof(ptr)),
0, "Unexpected mallctl() failure");
expect_u_eq(arena1, arena2, "Wrong arena used after binding");
dallocx(ptr, 0);
/* Switch back to arena 0. */
test_skip_if(have_percpu_arena &&
PERCPU_ARENA_ENABLED(opt_percpu_arena));
test_skip_if(
have_percpu_arena && PERCPU_ARENA_ENABLED(opt_percpu_arena));
arena2 = 0;
expect_d_eq(mallctl("thread.arena", NULL, NULL, &arena2,
sizeof(arena2)), 0, "Fail to bind thread");
expect_d_eq(
mallctl("thread.arena", NULL, NULL, &arena2, sizeof(arena2)), 0,
"Fail to bind thread");
ptr = mallocx(SMALL_SZ, MALLOCX_TCACHE_NONE);
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
sizeof(ptr)), 0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr, sizeof(ptr)),
0, "Unexpected mallctl() failure");
expect_u_eq(arena2, 0, "Wrong arena used after binding");
dallocx(ptr, MALLOCX_TCACHE_NONE);
/* Then huge allocation should use the huge arena. */
ptr = mallocx(HUGE_SZ, 0);
expect_ptr_not_null(ptr, "Fail to allocate huge size");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
sizeof(ptr)), 0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr, sizeof(ptr)),
0, "Unexpected mallctl() failure");
expect_u_ne(arena2, 0, "Wrong arena used after binding");
expect_u_ne(arena1, arena2, "Wrong arena used after binding");
dallocx(ptr, 0);
@ -48,25 +50,26 @@ TEST_END
TEST_BEGIN(huge_mallocx) {
unsigned arena1, arena2;
size_t sz = sizeof(unsigned);
size_t sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
"Failed to create arena");
void *huge = mallocx(HUGE_SZ, MALLOCX_ARENA(arena1));
expect_ptr_not_null(huge, "Fail to allocate huge size");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge,
sizeof(huge)), 0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge, sizeof(huge)),
0, "Unexpected mallctl() failure");
expect_u_eq(arena1, arena2, "Wrong arena used for mallocx");
dallocx(huge, MALLOCX_ARENA(arena1));
void *huge2 = mallocx(HUGE_SZ, 0);
expect_ptr_not_null(huge, "Fail to allocate huge size");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge2,
sizeof(huge2)), 0, "Unexpected mallctl() failure");
expect_d_eq(
mallctl("arenas.lookup", &arena2, &sz, &huge2, sizeof(huge2)), 0,
"Unexpected mallctl() failure");
expect_u_ne(arena1, arena2,
"Huge allocation should not come from the manual arena.");
expect_u_ne(arena2, 0,
"Huge allocation should not come from the arena 0.");
expect_u_ne(
arena2, 0, "Huge allocation should not come from the arena 0.");
dallocx(huge2, 0);
}
TEST_END
@ -82,30 +85,27 @@ TEST_BEGIN(huge_allocation) {
expect_u_gt(arena1, 0, "Huge allocation should not come from arena 0");
dallocx(ptr, 0);
test_skip_if(have_percpu_arena &&
PERCPU_ARENA_ENABLED(opt_percpu_arena));
test_skip_if(
have_percpu_arena && PERCPU_ARENA_ENABLED(opt_percpu_arena));
ptr = mallocx(HUGE_SZ >> 1, 0);
expect_ptr_not_null(ptr, "Fail to allocate half huge size");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
sizeof(ptr)), 0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr, sizeof(ptr)),
0, "Unexpected mallctl() failure");
expect_u_ne(arena1, arena2, "Wrong arena used for half huge");
dallocx(ptr, 0);
ptr = mallocx(SMALL_SZ, MALLOCX_TCACHE_NONE);
expect_ptr_not_null(ptr, "Fail to allocate small size");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
sizeof(ptr)), 0, "Unexpected mallctl() failure");
expect_u_ne(arena1, arena2,
"Huge and small should be from different arenas");
expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr, sizeof(ptr)),
0, "Unexpected mallctl() failure");
expect_u_ne(
arena1, arena2, "Huge and small should be from different arenas");
dallocx(ptr, 0);
}
TEST_END
int
main(void) {
return test(
huge_allocation,
huge_mallocx,
huge_bind_thread);
return test(huge_allocation, huge_mallocx, huge_bind_thread);
}

View file

@ -1,27 +1,30 @@
#include "test/jemalloc_test.h"
#define TEST_UTIL_EINVAL(node, a, b, c, d, why_inval) do { \
assert_d_eq(mallctl("experimental.utilization." node, \
a, b, c, d), EINVAL, "Should fail when " why_inval); \
assert_zu_eq(out_sz, out_sz_ref, \
"Output size touched when given invalid arguments"); \
assert_d_eq(memcmp(out, out_ref, out_sz_ref), 0, \
"Output content touched when given invalid arguments"); \
} while (0)
#define TEST_UTIL_EINVAL(node, a, b, c, d, why_inval) \
do { \
assert_d_eq( \
mallctl("experimental.utilization." node, a, b, c, d), \
EINVAL, "Should fail when " why_inval); \
assert_zu_eq(out_sz, out_sz_ref, \
"Output size touched when given invalid arguments"); \
assert_d_eq(memcmp(out, out_ref, out_sz_ref), 0, \
"Output content touched when given invalid arguments"); \
} while (0)
#define TEST_UTIL_QUERY_EINVAL(a, b, c, d, why_inval) \
#define TEST_UTIL_QUERY_EINVAL(a, b, c, d, why_inval) \
TEST_UTIL_EINVAL("query", a, b, c, d, why_inval)
#define TEST_UTIL_BATCH_EINVAL(a, b, c, d, why_inval) \
#define TEST_UTIL_BATCH_EINVAL(a, b, c, d, why_inval) \
TEST_UTIL_EINVAL("batch_query", a, b, c, d, why_inval)
#define TEST_UTIL_VALID(node) do { \
assert_d_eq(mallctl("experimental.utilization." node, \
out, &out_sz, in, in_sz), 0, \
"Should return 0 on correct arguments"); \
expect_zu_eq(out_sz, out_sz_ref, "incorrect output size"); \
expect_d_ne(memcmp(out, out_ref, out_sz_ref), 0, \
"Output content should be changed"); \
} while (0)
#define TEST_UTIL_VALID(node) \
do { \
assert_d_eq(mallctl("experimental.utilization." node, out, \
&out_sz, in, in_sz), \
0, "Should return 0 on correct arguments"); \
expect_zu_eq(out_sz, out_sz_ref, "incorrect output size"); \
expect_d_ne(memcmp(out, out_ref, out_sz_ref), 0, \
"Output content should be changed"); \
} while (0)
#define TEST_UTIL_BATCH_VALID TEST_UTIL_VALID("batch_query")
@ -34,21 +37,19 @@ TEST_BEGIN(test_query) {
* numerically unrelated to any size boundaries.
*/
for (sz = 7; sz <= TEST_MAX_SIZE && sz <= SC_LARGE_MAXCLASS;
sz += (sz <= SC_SMALL_MAXCLASS ? 1009 : 99989)) {
void *p = mallocx(sz, 0);
sz += (sz <= SC_SMALL_MAXCLASS ? 1009 : 99989)) {
void *p = mallocx(sz, 0);
void **in = &p;
size_t in_sz = sizeof(const void *);
size_t out_sz = sizeof(void *) + sizeof(size_t) * 5;
void *out = mallocx(out_sz, 0);
void *out_ref = mallocx(out_sz, 0);
void *out = mallocx(out_sz, 0);
void *out_ref = mallocx(out_sz, 0);
size_t out_sz_ref = out_sz;
assert_ptr_not_null(p,
"test pointer allocation failed");
assert_ptr_not_null(out,
"test output allocation failed");
assert_ptr_not_null(out_ref,
"test reference output allocation failed");
assert_ptr_not_null(p, "test pointer allocation failed");
assert_ptr_not_null(out, "test output allocation failed");
assert_ptr_not_null(
out_ref, "test reference output allocation failed");
#define SLABCUR_READ(out) (*(void **)out)
#define COUNTS(out) ((size_t *)((void **)out + 1))
@ -64,21 +65,18 @@ TEST_BEGIN(test_query) {
memcpy(out_ref, out, out_sz);
/* Test invalid argument(s) errors */
TEST_UTIL_QUERY_EINVAL(NULL, &out_sz, in, in_sz,
"old is NULL");
TEST_UTIL_QUERY_EINVAL(out, NULL, in, in_sz,
"oldlenp is NULL");
TEST_UTIL_QUERY_EINVAL(out, &out_sz, NULL, in_sz,
"newp is NULL");
TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, 0,
"newlen is zero");
TEST_UTIL_QUERY_EINVAL(NULL, &out_sz, in, in_sz, "old is NULL");
TEST_UTIL_QUERY_EINVAL(out, NULL, in, in_sz, "oldlenp is NULL");
TEST_UTIL_QUERY_EINVAL(
out, &out_sz, NULL, in_sz, "newp is NULL");
TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, 0, "newlen is zero");
in_sz -= 1;
TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, in_sz,
"invalid newlen");
TEST_UTIL_QUERY_EINVAL(
out, &out_sz, in, in_sz, "invalid newlen");
in_sz += 1;
out_sz_ref = out_sz -= 2 * sizeof(size_t);
TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, in_sz,
"invalid *oldlenp");
TEST_UTIL_QUERY_EINVAL(
out, &out_sz, in, in_sz, "invalid *oldlenp");
out_sz_ref = out_sz += 2 * sizeof(size_t);
/* Examine output for valid call */
@ -100,8 +98,9 @@ TEST_BEGIN(test_query) {
"Extent region count exceeded size");
expect_zu_ne(NREGS_READ(out), 0,
"Extent region count must be positive");
expect_true(NFREE_READ(out) == 0 || (SLABCUR_READ(out)
!= NULL && SLABCUR_READ(out) <= p),
expect_true(NFREE_READ(out) == 0
|| (SLABCUR_READ(out) != NULL
&& SLABCUR_READ(out) <= p),
"Allocation should follow first fit principle");
if (config_stats) {
@ -117,8 +116,8 @@ TEST_BEGIN(test_query) {
BIN_NREGS_READ(out),
"Extent region count exceeded "
"bin region count");
expect_zu_eq(BIN_NREGS_READ(out)
% NREGS_READ(out), 0,
expect_zu_eq(
BIN_NREGS_READ(out) % NREGS_READ(out), 0,
"Bin region count isn't a multiple of "
"extent region count");
expect_zu_le(
@ -171,10 +170,10 @@ TEST_BEGIN(test_batch) {
* numerically unrelated to any size boundaries.
*/
for (sz = 17; sz <= TEST_MAX_SIZE && sz <= SC_LARGE_MAXCLASS;
sz += (sz <= SC_SMALL_MAXCLASS ? 1019 : 99991)) {
void *p = mallocx(sz, 0);
void *q = mallocx(sz, 0);
void *in[] = {p, q};
sz += (sz <= SC_SMALL_MAXCLASS ? 1019 : 99991)) {
void *p = mallocx(sz, 0);
void *q = mallocx(sz, 0);
void *in[] = {p, q};
size_t in_sz = sizeof(const void *) * 2;
size_t out[] = {-1, -1, -1, -1, -1, -1};
size_t out_sz = sizeof(size_t) * 6;
@ -185,17 +184,14 @@ TEST_BEGIN(test_batch) {
assert_ptr_not_null(q, "test pointer allocation failed");
/* Test invalid argument(s) errors */
TEST_UTIL_BATCH_EINVAL(NULL, &out_sz, in, in_sz,
"old is NULL");
TEST_UTIL_BATCH_EINVAL(out, NULL, in, in_sz,
"oldlenp is NULL");
TEST_UTIL_BATCH_EINVAL(out, &out_sz, NULL, in_sz,
"newp is NULL");
TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, 0,
"newlen is zero");
TEST_UTIL_BATCH_EINVAL(NULL, &out_sz, in, in_sz, "old is NULL");
TEST_UTIL_BATCH_EINVAL(out, NULL, in, in_sz, "oldlenp is NULL");
TEST_UTIL_BATCH_EINVAL(
out, &out_sz, NULL, in_sz, "newp is NULL");
TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, 0, "newlen is zero");
in_sz -= 1;
TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
"newlen is not an exact multiple");
TEST_UTIL_BATCH_EINVAL(
out, &out_sz, in, in_sz, "newlen is not an exact multiple");
in_sz += 1;
out_sz_ref = out_sz -= 2 * sizeof(size_t);
TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
@ -206,8 +202,8 @@ TEST_BEGIN(test_batch) {
"*oldlenp and newlen do not match");
in_sz += sizeof(const void *);
/* Examine output for valid calls */
#define TEST_EQUAL_REF(i, message) \
/* Examine output for valid calls */
#define TEST_EQUAL_REF(i, message) \
assert_d_eq(memcmp(out + (i) * 3, out_ref + (i) * 3, 3), 0, message)
#define NFREE_READ(out, i) out[(i) * 3]
@ -238,8 +234,8 @@ TEST_BEGIN(test_batch) {
expect_zu_eq(NREGS_READ(out, 0), 1,
"Extent region count should be one");
}
TEST_EQUAL_REF(1,
"Should not overwrite content beyond what's needed");
TEST_EQUAL_REF(
1, "Should not overwrite content beyond what's needed");
in_sz *= 2;
out_sz_ref = out_sz *= 2;

View file

@ -1,9 +1,9 @@
#include "test/jemalloc_test.h"
#define arraylen(arr) (sizeof(arr)/sizeof(arr[0]))
#define arraylen(arr) (sizeof(arr) / sizeof(arr[0]))
static size_t ptr_ind;
static void *volatile ptrs[100];
static void *last_junked_ptr;
static void *last_junked_ptr;
static size_t last_junked_usize;
static void
@ -21,17 +21,17 @@ test_junk(void *ptr, size_t usize) {
static void
do_allocs(size_t size, bool zero, size_t lg_align) {
#define JUNK_ALLOC(...) \
do { \
assert(ptr_ind + 1 < arraylen(ptrs)); \
void *ptr = __VA_ARGS__; \
assert_ptr_not_null(ptr, ""); \
ptrs[ptr_ind++] = ptr; \
if (opt_junk_alloc && !zero) { \
expect_ptr_eq(ptr, last_junked_ptr, ""); \
expect_zu_eq(last_junked_usize, \
TEST_MALLOC_SIZE(ptr), ""); \
} \
#define JUNK_ALLOC(...) \
do { \
assert(ptr_ind + 1 < arraylen(ptrs)); \
void *ptr = __VA_ARGS__; \
assert_ptr_not_null(ptr, ""); \
ptrs[ptr_ind++] = ptr; \
if (opt_junk_alloc && !zero) { \
expect_ptr_eq(ptr, last_junked_ptr, ""); \
expect_zu_eq( \
last_junked_usize, TEST_MALLOC_SIZE(ptr), ""); \
} \
} while (0)
if (!zero && lg_align == 0) {
JUNK_ALLOC(malloc(size));
@ -51,21 +51,20 @@ do_allocs(size_t size, bool zero, size_t lg_align) {
#endif
int zero_flag = zero ? MALLOCX_ZERO : 0;
JUNK_ALLOC(mallocx(size, zero_flag | MALLOCX_LG_ALIGN(lg_align)));
JUNK_ALLOC(mallocx(size, zero_flag | MALLOCX_LG_ALIGN(lg_align)
| MALLOCX_TCACHE_NONE));
JUNK_ALLOC(mallocx(size,
zero_flag | MALLOCX_LG_ALIGN(lg_align) | MALLOCX_TCACHE_NONE));
if (lg_align >= LG_SIZEOF_PTR) {
void *memalign_result;
int err = posix_memalign(&memalign_result, (1 << lg_align),
size);
int err = posix_memalign(
&memalign_result, (1 << lg_align), size);
assert_d_eq(err, 0, "");
JUNK_ALLOC(memalign_result);
}
}
TEST_BEGIN(test_junk_alloc_free) {
bool zerovals[] = {false, true};
size_t sizevals[] = {
1, 8, 100, 1000, 100*1000
bool zerovals[] = {false, true};
size_t sizevals[] = {1, 8, 100, 1000, 100 * 1000
/*
* Memory allocation failure is a real possibility in 32-bit mode.
* Rather than try to check in the face of resource exhaustion, we just
@ -75,49 +74,49 @@ TEST_BEGIN(test_junk_alloc_free) {
* mechanisms; but this is in fact the case.
*/
#if LG_SIZEOF_PTR == 3
, 10 * 1000 * 1000
,
10 * 1000 * 1000
#endif
};
size_t lg_alignvals[] = {
0, 4, 10, 15, 16, LG_PAGE
size_t lg_alignvals[] = {0, 4, 10, 15, 16, LG_PAGE
#if LG_SIZEOF_PTR == 3
, 20, 24
,
20, 24
#endif
};
#define JUNK_FREE(...) \
do { \
do_allocs(size, zero, lg_align); \
for (size_t n = 0; n < ptr_ind; n++) { \
void *ptr = ptrs[n]; \
__VA_ARGS__; \
if (opt_junk_free) { \
assert_ptr_eq(ptr, last_junked_ptr, \
""); \
assert_zu_eq(usize, last_junked_usize, \
""); \
} \
reset(); \
} \
#define JUNK_FREE(...) \
do { \
do_allocs(size, zero, lg_align); \
for (size_t n = 0; n < ptr_ind; n++) { \
void *ptr = ptrs[n]; \
__VA_ARGS__; \
if (opt_junk_free) { \
assert_ptr_eq(ptr, last_junked_ptr, ""); \
assert_zu_eq(usize, last_junked_usize, ""); \
} \
reset(); \
} \
} while (0)
for (size_t i = 0; i < arraylen(zerovals); i++) {
for (size_t j = 0; j < arraylen(sizevals); j++) {
for (size_t k = 0; k < arraylen(lg_alignvals); k++) {
bool zero = zerovals[i];
bool zero = zerovals[i];
size_t size = sizevals[j];
size_t lg_align = lg_alignvals[k];
size_t usize = nallocx(size,
MALLOCX_LG_ALIGN(lg_align));
size_t usize = nallocx(
size, MALLOCX_LG_ALIGN(lg_align));
JUNK_FREE(free(ptr));
JUNK_FREE(dallocx(ptr, 0));
JUNK_FREE(dallocx(ptr, MALLOCX_TCACHE_NONE));
JUNK_FREE(dallocx(ptr, MALLOCX_LG_ALIGN(
lg_align)));
JUNK_FREE(sdallocx(ptr, usize, MALLOCX_LG_ALIGN(
lg_align)));
JUNK_FREE(
dallocx(ptr, MALLOCX_LG_ALIGN(lg_align)));
JUNK_FREE(sdallocx(
ptr, usize, MALLOCX_LG_ALIGN(lg_align)));
JUNK_FREE(sdallocx(ptr, usize,
MALLOCX_TCACHE_NONE | MALLOCX_LG_ALIGN(lg_align)));
MALLOCX_TCACHE_NONE
| MALLOCX_LG_ALIGN(lg_align)));
if (opt_zero_realloc_action
== zero_realloc_action_free) {
JUNK_FREE(realloc(ptr, 0));
@ -138,24 +137,24 @@ TEST_BEGIN(test_realloc_expand) {
ptr = malloc(SC_SMALL_MAXCLASS);
expanded = realloc(ptr, SC_LARGE_MINCLASS);
expect_ptr_eq(last_junked_ptr, &expanded[SC_SMALL_MAXCLASS], "");
expect_zu_eq(last_junked_usize,
SC_LARGE_MINCLASS - SC_SMALL_MAXCLASS, "");
expect_zu_eq(
last_junked_usize, SC_LARGE_MINCLASS - SC_SMALL_MAXCLASS, "");
free(expanded);
/* rallocx(..., 0) */
ptr = malloc(SC_SMALL_MAXCLASS);
expanded = rallocx(ptr, SC_LARGE_MINCLASS, 0);
expect_ptr_eq(last_junked_ptr, &expanded[SC_SMALL_MAXCLASS], "");
expect_zu_eq(last_junked_usize,
SC_LARGE_MINCLASS - SC_SMALL_MAXCLASS, "");
expect_zu_eq(
last_junked_usize, SC_LARGE_MINCLASS - SC_SMALL_MAXCLASS, "");
free(expanded);
/* rallocx(..., nonzero) */
ptr = malloc(SC_SMALL_MAXCLASS);
expanded = rallocx(ptr, SC_LARGE_MINCLASS, MALLOCX_TCACHE_NONE);
expect_ptr_eq(last_junked_ptr, &expanded[SC_SMALL_MAXCLASS], "");
expect_zu_eq(last_junked_usize,
SC_LARGE_MINCLASS - SC_SMALL_MAXCLASS, "");
expect_zu_eq(
last_junked_usize, SC_LARGE_MINCLASS - SC_SMALL_MAXCLASS, "");
free(expanded);
/* rallocx(..., MALLOCX_ZERO) */
@ -189,7 +188,5 @@ main(void) {
* We check the last pointer junked. If a reentrant call happens, that
* might be an internal allocation.
*/
return test_no_reentrancy(
test_junk_alloc_free,
test_realloc_expand);
return test_no_reentrancy(test_junk_alloc_free, test_realloc_expand);
}

View file

@ -18,16 +18,13 @@ expect_no_logging(const char *names) {
int count = 0;
for (int i = 0; i < 10; i++) {
log_do_begin(log_l1)
count++;
log_do_begin(log_l1) count++;
log_do_end(log_l1)
log_do_begin(log_l2)
count++;
log_do_begin(log_l2) count++;
log_do_end(log_l2)
log_do_begin(log_l2_a)
count++;
log_do_begin(log_l2_a) count++;
log_do_end(log_l2_a)
}
expect_d_eq(count, 0, "Disabled logging not ignored!");
@ -57,8 +54,7 @@ TEST_BEGIN(test_log_enabled_direct) {
count = 0;
update_log_var_names("l1");
for (int i = 0; i < 10; i++) {
log_do_begin(log_l1)
count++;
log_do_begin(log_l1) count++;
log_do_end(log_l1)
}
expect_d_eq(count, 10, "Mis-logged!");
@ -66,8 +62,7 @@ TEST_BEGIN(test_log_enabled_direct) {
count = 0;
update_log_var_names("l1.a");
for (int i = 0; i < 10; i++) {
log_do_begin(log_l1_a)
count++;
log_do_begin(log_l1_a) count++;
log_do_end(log_l1_a)
}
expect_d_eq(count, 10, "Mis-logged!");
@ -75,12 +70,10 @@ TEST_BEGIN(test_log_enabled_direct) {
count = 0;
update_log_var_names("l1.a|abc|l2|def");
for (int i = 0; i < 10; i++) {
log_do_begin(log_l1_a)
count++;
log_do_begin(log_l1_a) count++;
log_do_end(log_l1_a)
log_do_begin(log_l2)
count++;
log_do_begin(log_l2) count++;
log_do_end(log_l2)
}
expect_d_eq(count, 20, "Mis-logged!");
@ -108,28 +101,22 @@ TEST_BEGIN(test_log_enabled_indirect) {
/* 4 are on total, so should sum to 40. */
int count = 0;
for (int i = 0; i < 10; i++) {
log_do_begin(log_l1)
count++;
log_do_begin(log_l1) count++;
log_do_end(log_l1)
log_do_begin(log_l1a)
count++;
log_do_begin(log_l1a) count++;
log_do_end(log_l1a)
log_do_begin(log_l1_a)
count++;
log_do_begin(log_l1_a) count++;
log_do_end(log_l1_a)
log_do_begin(log_l2_a)
count++;
log_do_begin(log_l2_a) count++;
log_do_end(log_l2_a)
log_do_begin(log_l2_b_a)
count++;
log_do_begin(log_l2_b_a) count++;
log_do_end(log_l2_b_a)
log_do_begin(log_l2_b_b)
count++;
log_do_begin(log_l2_b_b) count++;
log_do_end(log_l2_b_b)
}
@ -147,12 +134,10 @@ TEST_BEGIN(test_log_enabled_global) {
int count = 0;
for (int i = 0; i < 10; i++) {
log_do_begin(log_l1)
count++;
log_do_begin(log_l1) count++;
log_do_end(log_l1)
log_do_begin(log_l2_a_a)
count++;
log_do_begin(log_l2_a_a) count++;
log_do_end(log_l2_a_a)
}
expect_d_eq(count, 20, "Mis-logged!");
@ -167,8 +152,7 @@ TEST_BEGIN(test_logs_if_no_init) {
int count = 0;
for (int i = 0; i < 10; i++) {
log_do_begin(l)
count++;
log_do_begin(l) count++;
log_do_end(l)
}
expect_d_eq(count, 0, "Logging shouldn't happen if not initialized.");
@ -188,11 +172,7 @@ TEST_END
int
main(void) {
return test(
test_log_disabled,
test_log_enabled_direct,
test_log_enabled_indirect,
test_log_enabled_global,
test_logs_if_no_init,
test_log_only_format_string);
return test(test_log_disabled, test_log_enabled_direct,
test_log_enabled_indirect, test_log_enabled_global,
test_logs_if_no_init, test_log_only_format_string);
}

File diff suppressed because it is too large Load diff

View file

@ -13,12 +13,12 @@ TEST_BEGIN(test_malloc_conf_2) {
test_skip_if(windows);
ssize_t dirty_decay_ms;
size_t sz = sizeof(dirty_decay_ms);
size_t sz = sizeof(dirty_decay_ms);
int err = mallctl("opt.dirty_decay_ms", &dirty_decay_ms, &sz, NULL, 0);
assert_d_eq(err, 0, "Unexpected mallctl failure");
expect_zd_eq(dirty_decay_ms, 1234,
"malloc_conf_2 setting didn't take effect");
expect_zd_eq(
dirty_decay_ms, 1234, "malloc_conf_2 setting didn't take effect");
}
TEST_END
@ -32,22 +32,24 @@ TEST_BEGIN(test_mallctl_global_var) {
test_skip_if(windows);
const char *mc;
size_t sz = sizeof(mc);
expect_d_eq(mallctl("opt.malloc_conf.global_var",
(void *)&mc, &sz, NULL, 0), 0, "Unexpected mallctl() failure");
expect_str_eq(mc, malloc_conf, "Unexpected value for the global variable "
size_t sz = sizeof(mc);
expect_d_eq(
mallctl("opt.malloc_conf.global_var", (void *)&mc, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
expect_str_eq(mc, malloc_conf,
"Unexpected value for the global variable "
"malloc_conf");
expect_d_eq(mallctl("opt.malloc_conf.global_var_2_conf_harder",
(void *)&mc, &sz, NULL, 0), 0, "Unexpected mallctl() failure");
expect_str_eq(mc, malloc_conf_2_conf_harder, "Unexpected value for the "
(void *)&mc, &sz, NULL, 0),
0, "Unexpected mallctl() failure");
expect_str_eq(mc, malloc_conf_2_conf_harder,
"Unexpected value for the "
"global variable malloc_conf_2_conf_harder");
}
TEST_END
int
main(void) {
return test(
test_malloc_conf_2,
test_mallctl_global_var);
return test(test_malloc_conf_2, test_mallctl_global_var);
}

View file

@ -14,77 +14,68 @@ TEST_BEGIN(test_malloc_strtoumax) {
struct test_s {
const char *input;
const char *expected_remainder;
int base;
int expected_errno;
int base;
int expected_errno;
const char *expected_errno_name;
uintmax_t expected_x;
uintmax_t expected_x;
};
#define ERR(e) e, #e
#define KUMAX(x) ((uintmax_t)x##ULL)
#define KSMAX(x) ((uintmax_t)(intmax_t)x##LL)
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},
#define ERR(e) e, #e
#define KUMAX(x) ((uintmax_t)x##ULL)
#define KSMAX(x) ((uintmax_t)(intmax_t)x##LL)
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},
{"", "", 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), KUMAX(42)},
{"+42", "", 0, ERR(0), KUMAX(42)},
{"-42", "", 0, ERR(0), KSMAX(-42)},
{"042", "", 0, ERR(0), KUMAX(042)},
{"+042", "", 0, ERR(0), KUMAX(042)},
{"-042", "", 0, ERR(0), KSMAX(-042)},
{"0x42", "", 0, ERR(0), KUMAX(0x42)},
{"+0x42", "", 0, ERR(0), KUMAX(0x42)},
{"-0x42", "", 0, ERR(0), KSMAX(-0x42)},
{"42", "", 0, ERR(0), KUMAX(42)}, {"+42", "", 0, ERR(0), KUMAX(42)},
{"-42", "", 0, ERR(0), KSMAX(-42)},
{"042", "", 0, ERR(0), KUMAX(042)},
{"+042", "", 0, ERR(0), KUMAX(042)},
{"-042", "", 0, ERR(0), KSMAX(-042)},
{"0x42", "", 0, ERR(0), KUMAX(0x42)},
{"+0x42", "", 0, ERR(0), KUMAX(0x42)},
{"-0x42", "", 0, ERR(0), KSMAX(-0x42)},
{"0", "", 0, ERR(0), KUMAX(0)},
{"1", "", 0, ERR(0), KUMAX(1)},
{"0", "", 0, ERR(0), KUMAX(0)}, {"1", "", 0, ERR(0), KUMAX(1)},
{"42", "", 0, ERR(0), KUMAX(42)},
{" 42", "", 0, ERR(0), KUMAX(42)},
{"42 ", " ", 0, ERR(0), KUMAX(42)},
{"0x", "x", 0, ERR(0), KUMAX(0)},
{"42x", "x", 0, ERR(0), KUMAX(42)},
{"42", "", 0, ERR(0), KUMAX(42)}, {" 42", "", 0, ERR(0), KUMAX(42)},
{"42 ", " ", 0, ERR(0), KUMAX(42)},
{"0x", "x", 0, ERR(0), KUMAX(0)},
{"42x", "x", 0, ERR(0), KUMAX(42)},
{"07", "", 0, ERR(0), KUMAX(7)},
{"010", "", 0, ERR(0), KUMAX(8)},
{"08", "8", 0, ERR(0), KUMAX(0)},
{"0_", "_", 0, ERR(0), KUMAX(0)},
{"07", "", 0, ERR(0), KUMAX(7)}, {"010", "", 0, ERR(0), KUMAX(8)},
{"08", "8", 0, ERR(0), KUMAX(0)}, {"0_", "_", 0, ERR(0), KUMAX(0)},
{"0x", "x", 0, ERR(0), KUMAX(0)},
{"0X", "X", 0, ERR(0), KUMAX(0)},
{"0xg", "xg", 0, ERR(0), KUMAX(0)},
{"0XA", "", 0, ERR(0), KUMAX(10)},
{"0x", "x", 0, ERR(0), KUMAX(0)}, {"0X", "X", 0, ERR(0), KUMAX(0)},
{"0xg", "xg", 0, ERR(0), KUMAX(0)},
{"0XA", "", 0, ERR(0), KUMAX(10)},
{"010", "", 10, ERR(0), KUMAX(10)},
{"0x3", "x3", 10, ERR(0), KUMAX(0)},
{"010", "", 10, ERR(0), KUMAX(10)},
{"0x3", "x3", 10, ERR(0), KUMAX(0)},
{"12", "2", 2, ERR(0), KUMAX(1)},
{"78", "8", 8, ERR(0), KUMAX(7)},
{"9a", "a", 10, ERR(0), KUMAX(9)},
{"9A", "A", 10, ERR(0), KUMAX(9)},
{"fg", "g", 16, ERR(0), KUMAX(15)},
{"FG", "G", 16, ERR(0), KUMAX(15)},
{"0xfg", "g", 16, ERR(0), KUMAX(15)},
{"0XFG", "G", 16, ERR(0), KUMAX(15)},
{"z_", "_", 36, ERR(0), KUMAX(35)},
{"Z_", "_", 36, ERR(0), KUMAX(35)}
};
{"12", "2", 2, ERR(0), KUMAX(1)}, {"78", "8", 8, ERR(0), KUMAX(7)},
{"9a", "a", 10, ERR(0), KUMAX(9)},
{"9A", "A", 10, ERR(0), KUMAX(9)},
{"fg", "g", 16, ERR(0), KUMAX(15)},
{"FG", "G", 16, ERR(0), KUMAX(15)},
{"0xfg", "g", 16, ERR(0), KUMAX(15)},
{"0XFG", "G", 16, ERR(0), KUMAX(15)},
{"z_", "_", 36, ERR(0), KUMAX(35)},
{"Z_", "_", 36, ERR(0), KUMAX(35)}};
#undef ERR
#undef KUMAX
#undef KSMAX
unsigned i;
for (i = 0; i < sizeof(tests)/sizeof(struct test_s); 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;
int err;
uintmax_t result;
char *remainder;
set_errno(0);
result = malloc_strtoumax(test->input, &remainder, test->base);
@ -93,8 +84,8 @@ TEST_BEGIN(test_malloc_strtoumax) {
"Expected errno %s for \"%s\", base %d",
test->expected_errno_name, test->input, test->base);
expect_str_eq(remainder, test->expected_remainder,
"Unexpected remainder for \"%s\", base %d",
test->input, test->base);
"Unexpected remainder for \"%s\", base %d", test->input,
test->base);
if (err == 0) {
expect_ju_eq(result, test->expected_x,
"Unexpected result for \"%s\", base %d",
@ -105,31 +96,32 @@ TEST_BEGIN(test_malloc_strtoumax) {
TEST_END
TEST_BEGIN(test_malloc_snprintf_truncated) {
#define BUFLEN 15
char buf[BUFLEN];
#define BUFLEN 15
char buf[BUFLEN];
size_t result;
size_t len;
#define TEST(expected_str_untruncated, ...) do { \
result = malloc_snprintf(buf, len, __VA_ARGS__); \
expect_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0, \
"Unexpected string inequality (\"%s\" vs \"%s\")", \
buf, expected_str_untruncated); \
expect_zu_eq(result, strlen(expected_str_untruncated), \
"Unexpected result"); \
} while (0)
#define TEST(expected_str_untruncated, ...) \
do { \
result = malloc_snprintf(buf, len, __VA_ARGS__); \
expect_d_eq(strncmp(buf, expected_str_untruncated, len - 1), \
0, "Unexpected string inequality (\"%s\" vs \"%s\")", buf, \
expected_str_untruncated); \
expect_zu_eq(result, strlen(expected_str_untruncated), \
"Unexpected result"); \
} while (0)
for (len = 1; len < BUFLEN; len++) {
TEST("012346789", "012346789");
TEST("a0123b", "a%sb", "0123");
TEST("a01234567", "a%s%s", "0123", "4567");
TEST("a0123 ", "a%-6s", "0123");
TEST("a 0123", "a%6s", "0123");
TEST("a 012", "a%6.3s", "0123");
TEST("a 012", "a%*.*s", 6, 3, "0123");
TEST("a 123b", "a% db", 123);
TEST("a123b", "a%-db", 123);
TEST("a-123b", "a%-db", -123);
TEST("a+123b", "a%+db", 123);
TEST("012346789", "012346789");
TEST("a0123b", "a%sb", "0123");
TEST("a01234567", "a%s%s", "0123", "4567");
TEST("a0123 ", "a%-6s", "0123");
TEST("a 0123", "a%6s", "0123");
TEST("a 012", "a%6.3s", "0123");
TEST("a 012", "a%*.*s", 6, 3, "0123");
TEST("a 123b", "a% db", 123);
TEST("a123b", "a%-db", 123);
TEST("a-123b", "a%-db", -123);
TEST("a+123b", "a%+db", 123);
}
#undef BUFLEN
#undef TEST
@ -137,14 +129,16 @@ TEST_BEGIN(test_malloc_snprintf_truncated) {
TEST_END
TEST_BEGIN(test_malloc_snprintf) {
#define BUFLEN 128
char buf[BUFLEN];
#define BUFLEN 128
char buf[BUFLEN];
size_t result;
#define TEST(expected_str, ...) do { \
result = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__); \
expect_str_eq(buf, expected_str, "Unexpected output"); \
expect_zu_eq(result, strlen(expected_str), "Unexpected result");\
} while (0)
#define TEST(expected_str, ...) \
do { \
result = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__); \
expect_str_eq(buf, expected_str, "Unexpected output"); \
expect_zu_eq( \
result, strlen(expected_str), "Unexpected result"); \
} while (0)
TEST("hello", "hello");
@ -260,9 +254,6 @@ TEST_END
int
main(void) {
return test(
test_malloc_strtoumax_no_endptr,
test_malloc_strtoumax,
test_malloc_snprintf_truncated,
test_malloc_snprintf);
return test(test_malloc_strtoumax_no_endptr, test_malloc_strtoumax,
test_malloc_snprintf_truncated, test_malloc_snprintf);
}

View file

@ -6,11 +6,11 @@
#include <float.h>
#ifdef __PGI
#undef INFINITY
# undef INFINITY
#endif
#ifndef INFINITY
#define INFINITY (DBL_MAX + DBL_MAX)
# define INFINITY (DBL_MAX + DBL_MAX)
#endif
static bool
@ -20,7 +20,7 @@ double_eq_rel(double a, double b, double max_rel_err, double max_abs_err) {
if (fabs(a - b) < max_abs_err) {
return true;
}
rel_err = (fabs(b) > fabs(a)) ? fabs((a-b)/b) : fabs((a-b)/a);
rel_err = (fabs(b) > fabs(a)) ? fabs((a - b) / b) : fabs((a - b) / a);
return (rel_err < max_rel_err);
}
@ -41,209 +41,206 @@ TEST_BEGIN(test_ln_gamma_factorial) {
/* exp(ln_gamma(x)) == (x-1)! for integer x. */
for (x = 1; x <= 21; x++) {
expect_true(double_eq_rel(exp(ln_gamma(x)),
(double)factorial(x-1), MAX_REL_ERR, MAX_ABS_ERR),
expect_true(
double_eq_rel(exp(ln_gamma(x)), (double)factorial(x - 1),
MAX_REL_ERR, MAX_ABS_ERR),
"Incorrect factorial result for x=%u", x);
}
}
TEST_END
/* Expected ln_gamma([0.0..100.0] increment=0.25). */
static const double ln_gamma_misc_expected[] = {
INFINITY,
1.28802252469807743, 0.57236494292470008, 0.20328095143129538,
0.00000000000000000, -0.09827183642181320, -0.12078223763524518,
-0.08440112102048555, 0.00000000000000000, 0.12487171489239651,
0.28468287047291918, 0.47521466691493719, 0.69314718055994529,
0.93580193110872523, 1.20097360234707429, 1.48681557859341718,
1.79175946922805496, 2.11445692745037128, 2.45373657084244234,
2.80857141857573644, 3.17805383034794575, 3.56137591038669710,
3.95781396761871651, 4.36671603662228680, 4.78749174278204581,
5.21960398699022932, 5.66256205985714178, 6.11591589143154568,
6.57925121201010121, 7.05218545073853953, 7.53436423675873268,
8.02545839631598312, 8.52516136106541467, 9.03318691960512332,
9.54926725730099690, 10.07315123968123949, 10.60460290274525086,
11.14340011995171231, 11.68933342079726856, 12.24220494005076176,
12.80182748008146909, 13.36802367147604720, 13.94062521940376342,
14.51947222506051816, 15.10441257307551943, 15.69530137706046524,
16.29200047656724237, 16.89437797963419285, 17.50230784587389010,
18.11566950571089407, 18.73434751193644843, 19.35823122022435427,
19.98721449566188468, 20.62119544270163018, 21.26007615624470048,
21.90376249182879320, 22.55216385312342098, 23.20519299513386002,
23.86276584168908954, 24.52480131594137802, 25.19122118273868338,
25.86194990184851861, 26.53691449111561340, 27.21604439872720604,
27.89927138384089389, 28.58652940490193828, 29.27775451504081516,
29.97288476399884871, 30.67186010608067548, 31.37462231367769050,
32.08111489594735843, 32.79128302226991565, 33.50507345013689076,
34.22243445715505317, 34.94331577687681545, 35.66766853819134298,
36.39544520803305261, 37.12659953718355865, 37.86108650896109395,
38.59886229060776230, 39.33988418719949465, 40.08411059791735198,
40.83150097453079752, 41.58201578195490100, 42.33561646075348506,
43.09226539146988699, 43.85192586067515208, 44.61456202863158893,
45.38013889847690052, 46.14862228684032885, 46.91997879580877395,
47.69417578616628361, 48.47118135183522014, 49.25096429545256882,
50.03349410501914463, 50.81874093156324790, 51.60667556776436982,
52.39726942748592364, 53.19049452616926743, 53.98632346204390586,
54.78472939811231157, 55.58568604486942633, 56.38916764371992940,
57.19514895105859864, 58.00360522298051080, 58.81451220059079787,
59.62784609588432261, 60.44358357816834371, 61.26170176100199427,
62.08217818962842927, 62.90499082887649962, 63.73011805151035958,
64.55753862700632340, 65.38723171073768015, 66.21917683354901385,
67.05335389170279825, 67.88974313718154008, 68.72832516833013017,
69.56908092082363737, 70.41199165894616385, 71.25703896716800045,
72.10420474200799390, 72.95347118416940191, 73.80482079093779646,
74.65823634883015814, 75.51370092648485866, 76.37119786778275454,
77.23071078519033961, 78.09222355331530707, 78.95572030266725960,
79.82118541361435859, 80.68860351052903468, 81.55795945611502873,
82.42923834590904164, 83.30242550295004378, 84.17750647261028973,
85.05446701758152983, 85.93329311301090456, 86.81397094178107920,
87.69648688992882057, 88.58082754219766741, 89.46697967771913795,
90.35493026581838194, 91.24466646193963015, 92.13617560368709292,
93.02944520697742803, 93.92446296229978486, 94.82121673107967297,
95.71969454214321615, 96.61988458827809723, 97.52177522288820910,
98.42535495673848800, 99.33061245478741341, 100.23753653310367895,
101.14611615586458981, 102.05634043243354370, 102.96819861451382394,
103.88168009337621811, 104.79677439715833032, 105.71347118823287303,
106.63176026064346047, 107.55163153760463501, 108.47307506906540198,
109.39608102933323153, 110.32063971475740516, 111.24674154146920557,
112.17437704317786995, 113.10353686902013237, 114.03421178146170689,
114.96639265424990128, 115.90007047041454769, 116.83523632031698014,
117.77188139974506953, 118.70999700805310795, 119.64957454634490830,
120.59060551569974962, 121.53308151543865279, 122.47699424143097247,
123.42233548443955726, 124.36909712850338394, 125.31727114935689826,
126.26684961288492559, 127.21782467361175861, 128.17018857322420899,
129.12393363912724453, 130.07905228303084755, 131.03553699956862033,
131.99338036494577864, 132.95257503561629164, 133.91311374698926784,
134.87498931216194364, 135.83819462068046846, 136.80272263732638294,
137.76856640092901785, 138.73571902320256299, 139.70417368760718091,
140.67392364823425055, 141.64496222871400732, 142.61728282114600574,
143.59087888505104047, 144.56574394634486680, 145.54187159633210058,
146.51925549072063859, 147.49788934865566148, 148.47776695177302031,
149.45888214327129617, 150.44122882700193600, 151.42480096657754984,
152.40959258449737490, 153.39559776128982094, 154.38281063467164245,
155.37122539872302696, 156.36083630307879844, 157.35163765213474107,
158.34362380426921391, 159.33678917107920370, 160.33112821663092973,
161.32663545672428995, 162.32330545817117695, 163.32113283808695314,
164.32011226319519892, 165.32023844914485267, 166.32150615984036790,
167.32391020678358018, 168.32744544842768164, 169.33210678954270634,
170.33788918059275375, 171.34478761712384198, 172.35279713916281707,
173.36191283062726143, 174.37212981874515094, 175.38344327348534080,
176.39584840699734514, 177.40934047306160437, 178.42391476654847793,
179.43956662288721304, 180.45629141754378111, 181.47408456550741107,
182.49294152078630304, 183.51285777591152737, 184.53382886144947861,
185.55585034552262869, 186.57891783333786861, 187.60302696672312095,
188.62817342367162610, 189.65435291789341932, 190.68156119837468054,
191.70979404894376330, 192.73904728784492590, 193.76931676731820176,
194.80059837318714244, 195.83288802445184729, 196.86618167288995096,
197.90047530266301123, 198.93576492992946214, 199.97204660246373464,
201.00931639928148797, 202.04757043027063901, 203.08680483582807597,
204.12701578650228385, 205.16819948264117102, 206.21035215404597807,
207.25347005962987623, 208.29754948708190909, 209.34258675253678916,
210.38857820024875878, 211.43552020227099320, 212.48340915813977858,
213.53224149456323744, 214.58201366511514152, 215.63272214993284592,
216.68436345542014010, 217.73693411395422004, 218.79043068359703739,
219.84484974781133815, 220.90018791517996988, 221.95644181913033322,
223.01360811766215875, 224.07168349307951871, 225.13066465172661879,
226.19054832372759734, 227.25133126272962159, 228.31301024565024704,
229.37558207242807384, 230.43904356577689896, 231.50339157094342113,
232.56862295546847008, 233.63473460895144740, 234.70172344281823484,
235.76958639009222907, 236.83832040516844586, 237.90792246359117712,
238.97838956183431947, 240.04971871708477238, 241.12190696702904802,
242.19495136964280846, 243.26884900298270509, 244.34359696498191283,
245.41919237324782443, 246.49563236486270057, 247.57291409618682110,
248.65103474266476269, 249.72999149863338175, 250.80978157713354904,
251.89040220972316320, 252.97185064629374551, 254.05412415488834199,
255.13722002152300661, 256.22113555000953511, 257.30586806178126835,
258.39141489572085675, 259.47777340799029844, 260.56494097186322279,
261.65291497755913497, 262.74169283208021852, 263.83127195904967266,
264.92164979855277807, 266.01282380697938379, 267.10479145686849733,
268.19755023675537586, 269.29109765101975427, 270.38543121973674488,
271.48054847852881721, 272.57644697842033565, 273.67312428569374561,
274.77057798174683967, 275.86880566295326389, 276.96780494052313770,
278.06757344036617496, 279.16810880295668085, 280.26940868320008349,
281.37147075030043197, 282.47429268763045229, 283.57787219260217171,
284.68220697654078322, 285.78729476455760050, 286.89313329542699194,
287.99972032146268930, 289.10705360839756395, 290.21513093526289140,
291.32395009427028754, 292.43350889069523646, 293.54380514276073200,
294.65483668152336350, 295.76660135076059532, 296.87909700685889902,
297.99232151870342022, 299.10627276756946458, 300.22094864701409733,
301.33634706277030091, 302.45246593264130297, 303.56930318639643929,
304.68685676566872189, 305.80512462385280514, 306.92410472600477078,
308.04379504874236773, 309.16419358014690033, 310.28529831966631036,
311.40710727801865687, 312.52961847709792664, 313.65282994987899201,
314.77673974032603610, 315.90134590329950015, 317.02664650446632777,
318.15263962020929966, 319.27932333753892635, 320.40669575400545455,
321.53475497761127144, 322.66349912672620803, 323.79292633000159185,
324.92303472628691452, 326.05382246454587403, 327.18528770377525916,
328.31742861292224234, 329.45024337080525356, 330.58373016603343331,
331.71788719692847280, 332.85271267144611329, 333.98820480709991898,
335.12436183088397001, 336.26118197919845443, 337.39866349777429377,
338.53680464159958774, 339.67560367484657036, 340.81505887079896411,
341.95516851178109619, 343.09593088908627578, 344.23734430290727460,
345.37940706226686416, 346.52211748494903532, 347.66547389743118401,
348.80947463481720661, 349.95411804077025408, 351.09940246744753267,
352.24532627543504759, 353.39188783368263103, 354.53908551944078908,
355.68691771819692349, 356.83538282361303118, 357.98447923746385868,
359.13420536957539753
};
static const double ln_gamma_misc_expected[] = {INFINITY, 1.28802252469807743,
0.57236494292470008, 0.20328095143129538, 0.00000000000000000,
-0.09827183642181320, -0.12078223763524518, -0.08440112102048555,
0.00000000000000000, 0.12487171489239651, 0.28468287047291918,
0.47521466691493719, 0.69314718055994529, 0.93580193110872523,
1.20097360234707429, 1.48681557859341718, 1.79175946922805496,
2.11445692745037128, 2.45373657084244234, 2.80857141857573644,
3.17805383034794575, 3.56137591038669710, 3.95781396761871651,
4.36671603662228680, 4.78749174278204581, 5.21960398699022932,
5.66256205985714178, 6.11591589143154568, 6.57925121201010121,
7.05218545073853953, 7.53436423675873268, 8.02545839631598312,
8.52516136106541467, 9.03318691960512332, 9.54926725730099690,
10.07315123968123949, 10.60460290274525086, 11.14340011995171231,
11.68933342079726856, 12.24220494005076176, 12.80182748008146909,
13.36802367147604720, 13.94062521940376342, 14.51947222506051816,
15.10441257307551943, 15.69530137706046524, 16.29200047656724237,
16.89437797963419285, 17.50230784587389010, 18.11566950571089407,
18.73434751193644843, 19.35823122022435427, 19.98721449566188468,
20.62119544270163018, 21.26007615624470048, 21.90376249182879320,
22.55216385312342098, 23.20519299513386002, 23.86276584168908954,
24.52480131594137802, 25.19122118273868338, 25.86194990184851861,
26.53691449111561340, 27.21604439872720604, 27.89927138384089389,
28.58652940490193828, 29.27775451504081516, 29.97288476399884871,
30.67186010608067548, 31.37462231367769050, 32.08111489594735843,
32.79128302226991565, 33.50507345013689076, 34.22243445715505317,
34.94331577687681545, 35.66766853819134298, 36.39544520803305261,
37.12659953718355865, 37.86108650896109395, 38.59886229060776230,
39.33988418719949465, 40.08411059791735198, 40.83150097453079752,
41.58201578195490100, 42.33561646075348506, 43.09226539146988699,
43.85192586067515208, 44.61456202863158893, 45.38013889847690052,
46.14862228684032885, 46.91997879580877395, 47.69417578616628361,
48.47118135183522014, 49.25096429545256882, 50.03349410501914463,
50.81874093156324790, 51.60667556776436982, 52.39726942748592364,
53.19049452616926743, 53.98632346204390586, 54.78472939811231157,
55.58568604486942633, 56.38916764371992940, 57.19514895105859864,
58.00360522298051080, 58.81451220059079787, 59.62784609588432261,
60.44358357816834371, 61.26170176100199427, 62.08217818962842927,
62.90499082887649962, 63.73011805151035958, 64.55753862700632340,
65.38723171073768015, 66.21917683354901385, 67.05335389170279825,
67.88974313718154008, 68.72832516833013017, 69.56908092082363737,
70.41199165894616385, 71.25703896716800045, 72.10420474200799390,
72.95347118416940191, 73.80482079093779646, 74.65823634883015814,
75.51370092648485866, 76.37119786778275454, 77.23071078519033961,
78.09222355331530707, 78.95572030266725960, 79.82118541361435859,
80.68860351052903468, 81.55795945611502873, 82.42923834590904164,
83.30242550295004378, 84.17750647261028973, 85.05446701758152983,
85.93329311301090456, 86.81397094178107920, 87.69648688992882057,
88.58082754219766741, 89.46697967771913795, 90.35493026581838194,
91.24466646193963015, 92.13617560368709292, 93.02944520697742803,
93.92446296229978486, 94.82121673107967297, 95.71969454214321615,
96.61988458827809723, 97.52177522288820910, 98.42535495673848800,
99.33061245478741341, 100.23753653310367895, 101.14611615586458981,
102.05634043243354370, 102.96819861451382394, 103.88168009337621811,
104.79677439715833032, 105.71347118823287303, 106.63176026064346047,
107.55163153760463501, 108.47307506906540198, 109.39608102933323153,
110.32063971475740516, 111.24674154146920557, 112.17437704317786995,
113.10353686902013237, 114.03421178146170689, 114.96639265424990128,
115.90007047041454769, 116.83523632031698014, 117.77188139974506953,
118.70999700805310795, 119.64957454634490830, 120.59060551569974962,
121.53308151543865279, 122.47699424143097247, 123.42233548443955726,
124.36909712850338394, 125.31727114935689826, 126.26684961288492559,
127.21782467361175861, 128.17018857322420899, 129.12393363912724453,
130.07905228303084755, 131.03553699956862033, 131.99338036494577864,
132.95257503561629164, 133.91311374698926784, 134.87498931216194364,
135.83819462068046846, 136.80272263732638294, 137.76856640092901785,
138.73571902320256299, 139.70417368760718091, 140.67392364823425055,
141.64496222871400732, 142.61728282114600574, 143.59087888505104047,
144.56574394634486680, 145.54187159633210058, 146.51925549072063859,
147.49788934865566148, 148.47776695177302031, 149.45888214327129617,
150.44122882700193600, 151.42480096657754984, 152.40959258449737490,
153.39559776128982094, 154.38281063467164245, 155.37122539872302696,
156.36083630307879844, 157.35163765213474107, 158.34362380426921391,
159.33678917107920370, 160.33112821663092973, 161.32663545672428995,
162.32330545817117695, 163.32113283808695314, 164.32011226319519892,
165.32023844914485267, 166.32150615984036790, 167.32391020678358018,
168.32744544842768164, 169.33210678954270634, 170.33788918059275375,
171.34478761712384198, 172.35279713916281707, 173.36191283062726143,
174.37212981874515094, 175.38344327348534080, 176.39584840699734514,
177.40934047306160437, 178.42391476654847793, 179.43956662288721304,
180.45629141754378111, 181.47408456550741107, 182.49294152078630304,
183.51285777591152737, 184.53382886144947861, 185.55585034552262869,
186.57891783333786861, 187.60302696672312095, 188.62817342367162610,
189.65435291789341932, 190.68156119837468054, 191.70979404894376330,
192.73904728784492590, 193.76931676731820176, 194.80059837318714244,
195.83288802445184729, 196.86618167288995096, 197.90047530266301123,
198.93576492992946214, 199.97204660246373464, 201.00931639928148797,
202.04757043027063901, 203.08680483582807597, 204.12701578650228385,
205.16819948264117102, 206.21035215404597807, 207.25347005962987623,
208.29754948708190909, 209.34258675253678916, 210.38857820024875878,
211.43552020227099320, 212.48340915813977858, 213.53224149456323744,
214.58201366511514152, 215.63272214993284592, 216.68436345542014010,
217.73693411395422004, 218.79043068359703739, 219.84484974781133815,
220.90018791517996988, 221.95644181913033322, 223.01360811766215875,
224.07168349307951871, 225.13066465172661879, 226.19054832372759734,
227.25133126272962159, 228.31301024565024704, 229.37558207242807384,
230.43904356577689896, 231.50339157094342113, 232.56862295546847008,
233.63473460895144740, 234.70172344281823484, 235.76958639009222907,
236.83832040516844586, 237.90792246359117712, 238.97838956183431947,
240.04971871708477238, 241.12190696702904802, 242.19495136964280846,
243.26884900298270509, 244.34359696498191283, 245.41919237324782443,
246.49563236486270057, 247.57291409618682110, 248.65103474266476269,
249.72999149863338175, 250.80978157713354904, 251.89040220972316320,
252.97185064629374551, 254.05412415488834199, 255.13722002152300661,
256.22113555000953511, 257.30586806178126835, 258.39141489572085675,
259.47777340799029844, 260.56494097186322279, 261.65291497755913497,
262.74169283208021852, 263.83127195904967266, 264.92164979855277807,
266.01282380697938379, 267.10479145686849733, 268.19755023675537586,
269.29109765101975427, 270.38543121973674488, 271.48054847852881721,
272.57644697842033565, 273.67312428569374561, 274.77057798174683967,
275.86880566295326389, 276.96780494052313770, 278.06757344036617496,
279.16810880295668085, 280.26940868320008349, 281.37147075030043197,
282.47429268763045229, 283.57787219260217171, 284.68220697654078322,
285.78729476455760050, 286.89313329542699194, 287.99972032146268930,
289.10705360839756395, 290.21513093526289140, 291.32395009427028754,
292.43350889069523646, 293.54380514276073200, 294.65483668152336350,
295.76660135076059532, 296.87909700685889902, 297.99232151870342022,
299.10627276756946458, 300.22094864701409733, 301.33634706277030091,
302.45246593264130297, 303.56930318639643929, 304.68685676566872189,
305.80512462385280514, 306.92410472600477078, 308.04379504874236773,
309.16419358014690033, 310.28529831966631036, 311.40710727801865687,
312.52961847709792664, 313.65282994987899201, 314.77673974032603610,
315.90134590329950015, 317.02664650446632777, 318.15263962020929966,
319.27932333753892635, 320.40669575400545455, 321.53475497761127144,
322.66349912672620803, 323.79292633000159185, 324.92303472628691452,
326.05382246454587403, 327.18528770377525916, 328.31742861292224234,
329.45024337080525356, 330.58373016603343331, 331.71788719692847280,
332.85271267144611329, 333.98820480709991898, 335.12436183088397001,
336.26118197919845443, 337.39866349777429377, 338.53680464159958774,
339.67560367484657036, 340.81505887079896411, 341.95516851178109619,
343.09593088908627578, 344.23734430290727460, 345.37940706226686416,
346.52211748494903532, 347.66547389743118401, 348.80947463481720661,
349.95411804077025408, 351.09940246744753267, 352.24532627543504759,
353.39188783368263103, 354.53908551944078908, 355.68691771819692349,
356.83538282361303118, 357.98447923746385868, 359.13420536957539753};
TEST_BEGIN(test_ln_gamma_misc) {
unsigned i;
for (i = 1; i < sizeof(ln_gamma_misc_expected)/sizeof(double); i++) {
for (i = 1; i < sizeof(ln_gamma_misc_expected) / sizeof(double); i++) {
double x = (double)i * 0.25;
expect_true(double_eq_rel(ln_gamma(x),
ln_gamma_misc_expected[i], MAX_REL_ERR, MAX_ABS_ERR),
expect_true(
double_eq_rel(ln_gamma(x), ln_gamma_misc_expected[i],
MAX_REL_ERR, MAX_ABS_ERR),
"Incorrect ln_gamma result for i=%u", i);
}
}
TEST_END
/* Expected pt_norm([0.01..0.99] increment=0.01). */
static const double pt_norm_expected[] = {
-INFINITY,
-2.32634787404084076, -2.05374891063182252, -1.88079360815125085,
-1.75068607125216946, -1.64485362695147264, -1.55477359459685305,
-1.47579102817917063, -1.40507156030963221, -1.34075503369021654,
-1.28155156554460081, -1.22652812003661049, -1.17498679206608991,
-1.12639112903880045, -1.08031934081495606, -1.03643338949378938,
-0.99445788320975281, -0.95416525314619416, -0.91536508784281390,
-0.87789629505122846, -0.84162123357291418, -0.80642124701824025,
-0.77219321418868492, -0.73884684918521371, -0.70630256284008752,
-0.67448975019608171, -0.64334540539291685, -0.61281299101662701,
-0.58284150727121620, -0.55338471955567281, -0.52440051270804067,
-0.49585034734745320, -0.46769879911450812, -0.43991316567323380,
-0.41246312944140462, -0.38532046640756751, -0.35845879325119373,
-0.33185334643681652, -0.30548078809939738, -0.27931903444745404,
-0.25334710313579978, -0.22754497664114931, -0.20189347914185077,
-0.17637416478086135, -0.15096921549677725, -0.12566134685507399,
-0.10043372051146975, -0.07526986209982976, -0.05015358346473352,
-0.02506890825871106, 0.00000000000000000, 0.02506890825871106,
0.05015358346473366, 0.07526986209982990, 0.10043372051146990,
0.12566134685507413, 0.15096921549677739, 0.17637416478086146,
0.20189347914185105, 0.22754497664114931, 0.25334710313579978,
0.27931903444745404, 0.30548078809939738, 0.33185334643681652,
0.35845879325119373, 0.38532046640756762, 0.41246312944140484,
0.43991316567323391, 0.46769879911450835, 0.49585034734745348,
0.52440051270804111, 0.55338471955567303, 0.58284150727121620,
0.61281299101662701, 0.64334540539291685, 0.67448975019608171,
0.70630256284008752, 0.73884684918521371, 0.77219321418868492,
0.80642124701824036, 0.84162123357291441, 0.87789629505122879,
0.91536508784281423, 0.95416525314619460, 0.99445788320975348,
1.03643338949378938, 1.08031934081495606, 1.12639112903880045,
1.17498679206608991, 1.22652812003661049, 1.28155156554460081,
1.34075503369021654, 1.40507156030963265, 1.47579102817917085,
1.55477359459685394, 1.64485362695147308, 1.75068607125217102,
1.88079360815125041, 2.05374891063182208, 2.32634787404084076
};
static const double pt_norm_expected[] = {-INFINITY, -2.32634787404084076,
-2.05374891063182252, -1.88079360815125085, -1.75068607125216946,
-1.64485362695147264, -1.55477359459685305, -1.47579102817917063,
-1.40507156030963221, -1.34075503369021654, -1.28155156554460081,
-1.22652812003661049, -1.17498679206608991, -1.12639112903880045,
-1.08031934081495606, -1.03643338949378938, -0.99445788320975281,
-0.95416525314619416, -0.91536508784281390, -0.87789629505122846,
-0.84162123357291418, -0.80642124701824025, -0.77219321418868492,
-0.73884684918521371, -0.70630256284008752, -0.67448975019608171,
-0.64334540539291685, -0.61281299101662701, -0.58284150727121620,
-0.55338471955567281, -0.52440051270804067, -0.49585034734745320,
-0.46769879911450812, -0.43991316567323380, -0.41246312944140462,
-0.38532046640756751, -0.35845879325119373, -0.33185334643681652,
-0.30548078809939738, -0.27931903444745404, -0.25334710313579978,
-0.22754497664114931, -0.20189347914185077, -0.17637416478086135,
-0.15096921549677725, -0.12566134685507399, -0.10043372051146975,
-0.07526986209982976, -0.05015358346473352, -0.02506890825871106,
0.00000000000000000, 0.02506890825871106, 0.05015358346473366,
0.07526986209982990, 0.10043372051146990, 0.12566134685507413,
0.15096921549677739, 0.17637416478086146, 0.20189347914185105,
0.22754497664114931, 0.25334710313579978, 0.27931903444745404,
0.30548078809939738, 0.33185334643681652, 0.35845879325119373,
0.38532046640756762, 0.41246312944140484, 0.43991316567323391,
0.46769879911450835, 0.49585034734745348, 0.52440051270804111,
0.55338471955567303, 0.58284150727121620, 0.61281299101662701,
0.64334540539291685, 0.67448975019608171, 0.70630256284008752,
0.73884684918521371, 0.77219321418868492, 0.80642124701824036,
0.84162123357291441, 0.87789629505122879, 0.91536508784281423,
0.95416525314619460, 0.99445788320975348, 1.03643338949378938,
1.08031934081495606, 1.12639112903880045, 1.17498679206608991,
1.22652812003661049, 1.28155156554460081, 1.34075503369021654,
1.40507156030963265, 1.47579102817917085, 1.55477359459685394,
1.64485362695147308, 1.75068607125217102, 1.88079360815125041,
2.05374891063182208, 2.32634787404084076};
TEST_BEGIN(test_pt_norm) {
unsigned i;
for (i = 1; i < sizeof(pt_norm_expected)/sizeof(double); i++) {
for (i = 1; i < sizeof(pt_norm_expected) / sizeof(double); i++) {
double p = (double)i * 0.01;
expect_true(double_eq_rel(pt_norm(p), pt_norm_expected[i],
MAX_REL_ERR, MAX_ABS_ERR),
MAX_REL_ERR, MAX_ABS_ERR),
"Incorrect pt_norm result for i=%u", i);
}
}
@ -254,49 +251,49 @@ TEST_END
* df={0.1, 1.1, 10.1, 100.1, 1000.1}).
*/
static const double pt_chi2_df[] = {0.1, 1.1, 10.1, 100.1, 1000.1};
static const double pt_chi2_expected[] = {
1.168926411457320e-40, 1.347680397072034e-22, 3.886980416666260e-17,
8.245951724356564e-14, 2.068936347497604e-11, 1.562561743309233e-09,
5.459543043426564e-08, 1.114775688149252e-06, 1.532101202364371e-05,
1.553884683726585e-04, 1.239396954915939e-03, 8.153872320255721e-03,
4.631183739647523e-02, 2.473187311701327e-01, 2.175254800183617e+00,
static const double pt_chi2_expected[] = {1.168926411457320e-40,
1.347680397072034e-22, 3.886980416666260e-17, 8.245951724356564e-14,
2.068936347497604e-11, 1.562561743309233e-09, 5.459543043426564e-08,
1.114775688149252e-06, 1.532101202364371e-05, 1.553884683726585e-04,
1.239396954915939e-03, 8.153872320255721e-03, 4.631183739647523e-02,
2.473187311701327e-01, 2.175254800183617e+00,
0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113,
0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931,
0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259,
0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304,
2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839,
0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113,
0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931,
0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259,
0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304,
2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839,
2.606673548632508, 4.602913725294877, 5.646152813924212,
6.488971315540869, 7.249823275816285, 7.977314231410841,
8.700354939944047, 9.441728024225892, 10.224338321374127,
11.076435368801061, 12.039320937038386, 13.183878752697167,
14.657791935084575, 16.885728216339373, 23.361991680031817,
2.606673548632508, 4.602913725294877, 5.646152813924212, 6.488971315540869,
7.249823275816285, 7.977314231410841, 8.700354939944047, 9.441728024225892,
10.224338321374127, 11.076435368801061, 12.039320937038386,
13.183878752697167, 14.657791935084575, 16.885728216339373,
23.361991680031817,
70.14844087392152, 80.92379498849355, 85.53325420085891,
88.94433120715347, 91.83732712857017, 94.46719943606301,
96.96896479994635, 99.43412843510363, 101.94074719829733,
104.57228644307247, 107.43900093448734, 110.71844673417287,
114.76616819871325, 120.57422505959563, 135.92318818757556,
70.14844087392152, 80.92379498849355, 85.53325420085891, 88.94433120715347,
91.83732712857017, 94.46719943606301, 96.96896479994635, 99.43412843510363,
101.94074719829733, 104.57228644307247, 107.43900093448734,
110.71844673417287, 114.76616819871325, 120.57422505959563,
135.92318818757556,
899.0072447849649, 937.9271278858220, 953.8117189560207,
965.3079371501154, 974.8974061207954, 983.4936235182347,
991.5691170518946, 999.4334123954690, 1007.3391826856553,
1015.5445154999951, 1024.3777075619569, 1034.3538789836223,
1046.4872561869577, 1063.5717461999654, 1107.0741966053859
};
899.0072447849649, 937.9271278858220, 953.8117189560207, 965.3079371501154,
974.8974061207954, 983.4936235182347, 991.5691170518946, 999.4334123954690,
1007.3391826856553, 1015.5445154999951, 1024.3777075619569,
1034.3538789836223, 1046.4872561869577, 1063.5717461999654,
1107.0741966053859};
TEST_BEGIN(test_pt_chi2) {
unsigned i, j;
unsigned e = 0;
for (i = 0; i < sizeof(pt_chi2_df)/sizeof(double); i++) {
for (i = 0; i < sizeof(pt_chi2_df) / sizeof(double); i++) {
double df = pt_chi2_df[i];
double ln_gamma_df = ln_gamma(df * 0.5);
for (j = 1; j < 100; j += 7) {
double p = (double)j * 0.01;
expect_true(double_eq_rel(pt_chi2(p, df, ln_gamma_df),
pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR),
expect_true(
double_eq_rel(pt_chi2(p, df, ln_gamma_df),
pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR),
"Incorrect pt_chi2 result for i=%u, j=%u", i, j);
e++;
}
@ -309,56 +306,56 @@ TEST_END
* shape=[0.5..3.0] increment=0.5).
*/
static const double pt_gamma_shape[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0};
static const double pt_gamma_expected[] = {
7.854392895485103e-05, 5.043466107888016e-03, 1.788288957794883e-02,
3.900956150232906e-02, 6.913847560638034e-02, 1.093710833465766e-01,
1.613412523825817e-01, 2.274682115597864e-01, 3.114117323127083e-01,
4.189466220207417e-01, 5.598106789059246e-01, 7.521856146202706e-01,
1.036125427911119e+00, 1.532450860038180e+00, 3.317448300510606e+00,
static const double pt_gamma_expected[] = {7.854392895485103e-05,
5.043466107888016e-03, 1.788288957794883e-02, 3.900956150232906e-02,
6.913847560638034e-02, 1.093710833465766e-01, 1.613412523825817e-01,
2.274682115597864e-01, 3.114117323127083e-01, 4.189466220207417e-01,
5.598106789059246e-01, 7.521856146202706e-01, 1.036125427911119e+00,
1.532450860038180e+00, 3.317448300510606e+00,
0.01005033585350144, 0.08338160893905107, 0.16251892949777497,
0.24846135929849966, 0.34249030894677596, 0.44628710262841947,
0.56211891815354142, 0.69314718055994529, 0.84397007029452920,
1.02165124753198167, 1.23787435600161766, 1.51412773262977574,
1.89711998488588196, 2.52572864430825783, 4.60517018598809091,
0.01005033585350144, 0.08338160893905107, 0.16251892949777497,
0.24846135929849966, 0.34249030894677596, 0.44628710262841947,
0.56211891815354142, 0.69314718055994529, 0.84397007029452920,
1.02165124753198167, 1.23787435600161766, 1.51412773262977574,
1.89711998488588196, 2.52572864430825783, 4.60517018598809091,
0.05741590094955853, 0.24747378084860744, 0.39888572212236084,
0.54394139997444901, 0.69048812513915159, 0.84311389861296104,
1.00580622221479898, 1.18298694218766931, 1.38038096305861213,
1.60627736383027453, 1.87396970522337947, 2.20749220408081070,
2.65852391865854942, 3.37934630984842244, 5.67243336507218476,
0.05741590094955853, 0.24747378084860744, 0.39888572212236084,
0.54394139997444901, 0.69048812513915159, 0.84311389861296104,
1.00580622221479898, 1.18298694218766931, 1.38038096305861213,
1.60627736383027453, 1.87396970522337947, 2.20749220408081070,
2.65852391865854942, 3.37934630984842244, 5.67243336507218476,
0.1485547402532659, 0.4657458011640391, 0.6832386130709406,
0.8794297834672100, 1.0700752852474524, 1.2629614217350744,
1.4638400448580779, 1.6783469900166610, 1.9132338090606940,
2.1778589228618777, 2.4868823970010991, 2.8664695666264195,
3.3724415436062114, 4.1682658512758071, 6.6383520679938108,
0.1485547402532659, 0.4657458011640391, 0.6832386130709406,
0.8794297834672100, 1.0700752852474524, 1.2629614217350744,
1.4638400448580779, 1.6783469900166610, 1.9132338090606940,
2.1778589228618777, 2.4868823970010991, 2.8664695666264195,
3.3724415436062114, 4.1682658512758071, 6.6383520679938108,
0.2771490383641385, 0.7195001279643727, 0.9969081732265243,
1.2383497880608061, 1.4675206597269927, 1.6953064251816552,
1.9291243435606809, 2.1757300955477641, 2.4428032131216391,
2.7406534569230616, 3.0851445039665513, 3.5043101122033367,
4.0575997065264637, 4.9182956424675286, 7.5431362346944937,
0.2771490383641385, 0.7195001279643727, 0.9969081732265243,
1.2383497880608061, 1.4675206597269927, 1.6953064251816552,
1.9291243435606809, 2.1757300955477641, 2.4428032131216391,
2.7406534569230616, 3.0851445039665513, 3.5043101122033367,
4.0575997065264637, 4.9182956424675286, 7.5431362346944937,
0.4360451650782932, 0.9983600902486267, 1.3306365880734528,
1.6129750834753802, 1.8767241606994294, 2.1357032436097660,
2.3988853336865565, 2.6740603137235603, 2.9697561737517959,
3.2971457713883265, 3.6731795898504660, 4.1275751617770631,
4.7230515633946677, 5.6417477865306020, 8.4059469148854635
};
0.4360451650782932, 0.9983600902486267, 1.3306365880734528,
1.6129750834753802, 1.8767241606994294, 2.1357032436097660,
2.3988853336865565, 2.6740603137235603, 2.9697561737517959,
3.2971457713883265, 3.6731795898504660, 4.1275751617770631,
4.7230515633946677, 5.6417477865306020, 8.4059469148854635};
TEST_BEGIN(test_pt_gamma_shape) {
unsigned i, j;
unsigned e = 0;
for (i = 0; i < sizeof(pt_gamma_shape)/sizeof(double); i++) {
for (i = 0; i < sizeof(pt_gamma_shape) / sizeof(double); i++) {
double shape = pt_gamma_shape[i];
double ln_gamma_shape = ln_gamma(shape);
for (j = 1; j < 100; j += 7) {
double p = (double)j * 0.01;
expect_true(double_eq_rel(pt_gamma(p, shape, 1.0,
ln_gamma_shape), pt_gamma_expected[e], MAX_REL_ERR,
MAX_ABS_ERR),
expect_true(
double_eq_rel(
pt_gamma(p, shape, 1.0, ln_gamma_shape),
pt_gamma_expected[e], MAX_REL_ERR, MAX_ABS_ERR),
"Incorrect pt_gamma result for i=%u, j=%u", i, j);
e++;
}
@ -370,21 +367,16 @@ TEST_BEGIN(test_pt_gamma_scale) {
double shape = 1.0;
double ln_gamma_shape = ln_gamma(shape);
expect_true(double_eq_rel(
pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0,
pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR,
MAX_ABS_ERR),
expect_true(
double_eq_rel(pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0,
pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR,
MAX_ABS_ERR),
"Scale should be trivially equivalent to external multiplication");
}
TEST_END
int
main(void) {
return test(
test_ln_gamma_factorial,
test_ln_gamma_misc,
test_pt_norm,
test_pt_chi2,
test_pt_gamma_shape,
test_pt_gamma_scale);
return test(test_ln_gamma_factorial, test_ln_gamma_misc, test_pt_norm,
test_pt_chi2, test_pt_gamma_shape, test_pt_gamma_scale);
}

View file

@ -12,10 +12,10 @@ struct elem_s {
};
/* Include both proto and gen to make sure they match up. */
mpsc_queue_proto(static, elem_mpsc_queue_, elem_mpsc_queue_t, elem_t,
elem_list_t);
mpsc_queue_gen(static, elem_mpsc_queue_, elem_mpsc_queue_t, elem_t,
elem_list_t, link);
mpsc_queue_proto(
static, elem_mpsc_queue_, elem_mpsc_queue_t, elem_t, elem_list_t);
mpsc_queue_gen(
static, elem_mpsc_queue_, elem_mpsc_queue_t, elem_t, elem_list_t, link);
static void
init_elems_simple(elem_t *elems, int nelems, int thread) {
@ -29,8 +29,8 @@ init_elems_simple(elem_t *elems, int nelems, int thread) {
static void
check_elems_simple(elem_list_t *list, int nelems, int thread) {
elem_t *elem;
int next_idx = 0;
ql_foreach(elem, list, link) {
int next_idx = 0;
ql_foreach (elem, list, link) {
expect_d_lt(next_idx, nelems, "Too many list items");
expect_d_eq(thread, elem->thread, "");
expect_d_eq(next_idx, elem->idx, "List out of order");
@ -39,9 +39,9 @@ check_elems_simple(elem_list_t *list, int nelems, int thread) {
}
TEST_BEGIN(test_simple) {
enum {NELEMS = 10};
elem_t elems[NELEMS];
elem_list_t list;
enum { NELEMS = 10 };
elem_t elems[NELEMS];
elem_list_t list;
elem_mpsc_queue_t queue;
/* Pop empty queue onto empty list -> empty list */
@ -82,7 +82,6 @@ TEST_BEGIN(test_simple) {
}
elem_mpsc_queue_pop_batch(&queue, &list);
check_elems_simple(&list, NELEMS, 0);
}
TEST_END
@ -137,7 +136,7 @@ TEST_BEGIN(test_push_single_or_batch) {
TEST_END
TEST_BEGIN(test_multi_op) {
enum {NELEMS = 20};
enum { NELEMS = 20 };
elem_t elems[NELEMS];
init_elems_simple(elems, NELEMS, 0);
elem_list_t push_list;
@ -176,30 +175,29 @@ TEST_BEGIN(test_multi_op) {
elem_mpsc_queue_pop_batch(&queue, &result_list);
check_elems_simple(&result_list, NELEMS, 0);
}
TEST_END
typedef struct pusher_arg_s pusher_arg_t;
struct pusher_arg_s {
elem_mpsc_queue_t *queue;
int thread;
elem_t *elems;
int nelems;
int thread;
elem_t *elems;
int nelems;
};
typedef struct popper_arg_s popper_arg_t;
struct popper_arg_s {
elem_mpsc_queue_t *queue;
int npushers;
int nelems_per_pusher;
int *pusher_counts;
int npushers;
int nelems_per_pusher;
int *pusher_counts;
};
static void *
thd_pusher(void *void_arg) {
pusher_arg_t *arg = (pusher_arg_t *)void_arg;
int next_idx = 0;
int next_idx = 0;
while (next_idx < arg->nelems) {
/* Push 10 items in batch. */
elem_list_t list;
@ -216,7 +214,6 @@ thd_pusher(void *void_arg) {
elem_mpsc_queue_push(arg->queue, &arg->elems[next_idx]);
next_idx++;
}
}
return NULL;
}
@ -224,13 +221,13 @@ thd_pusher(void *void_arg) {
static void *
thd_popper(void *void_arg) {
popper_arg_t *arg = (popper_arg_t *)void_arg;
int done_pushers = 0;
int done_pushers = 0;
while (done_pushers < arg->npushers) {
elem_list_t list;
ql_new(&list);
elem_mpsc_queue_pop_batch(arg->queue, &list);
elem_t *elem;
ql_foreach(elem, &list, link) {
ql_foreach (elem, &list, link) {
int thread = elem->thread;
int idx = elem->idx;
expect_d_eq(arg->pusher_counts[thread], idx,
@ -248,12 +245,12 @@ thd_popper(void *void_arg) {
TEST_BEGIN(test_multiple_threads) {
enum {
NPUSHERS = 4,
NELEMS_PER_PUSHER = 1000*1000,
NELEMS_PER_PUSHER = 1000 * 1000,
};
thd_t pushers[NPUSHERS];
thd_t pushers[NPUSHERS];
pusher_arg_t pusher_arg[NPUSHERS];
thd_t popper;
thd_t popper;
popper_arg_t popper_arg;
elem_mpsc_queue_t queue;
@ -296,9 +293,6 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_simple,
test_push_single_or_batch,
test_multi_op,
test_multiple_threads);
return test_no_reentrancy(test_simple, test_push_single_or_batch,
test_multi_op, test_multiple_threads);
}

View file

@ -1,22 +1,22 @@
#include "test/jemalloc_test.h"
#define NSENDERS 3
#define NMSGS 100000
#define NSENDERS 3
#define NMSGS 100000
typedef struct mq_msg_s mq_msg_t;
struct mq_msg_s {
mq_msg(mq_msg_t) link;
mq_msg(mq_msg_t) link;
};
mq_gen(static, mq_, mq_t, mq_msg_t, link)
TEST_BEGIN(test_mq_basic) {
mq_t mq;
TEST_BEGIN(test_mq_basic) {
mq_t mq;
mq_msg_t msg;
expect_false(mq_init(&mq), "Unexpected mq_init() failure");
expect_u_eq(mq_count(&mq), 0, "mq should be empty");
expect_ptr_null(mq_tryget(&mq),
"mq_tryget() should fail when the queue is empty");
expect_ptr_null(
mq_tryget(&mq), "mq_tryget() should fail when the queue is empty");
mq_put(&mq, &msg);
expect_u_eq(mq_count(&mq), 1, "mq should contain one message");
@ -31,7 +31,7 @@ TEST_END
static void *
thd_receiver_start(void *arg) {
mq_t *mq = (mq_t *)arg;
mq_t *mq = (mq_t *)arg;
unsigned i;
for (i = 0; i < (NSENDERS * NMSGS); i++) {
@ -44,12 +44,12 @@ thd_receiver_start(void *arg) {
static void *
thd_sender_start(void *arg) {
mq_t *mq = (mq_t *)arg;
mq_t *mq = (mq_t *)arg;
unsigned i;
for (i = 0; i < NMSGS; i++) {
mq_msg_t *msg;
void *p;
void *p;
p = mallocx(sizeof(mq_msg_t), 0);
expect_ptr_not_null(p, "Unexpected mallocx() failure");
msg = (mq_msg_t *)p;
@ -59,9 +59,9 @@ thd_sender_start(void *arg) {
}
TEST_BEGIN(test_mq_threaded) {
mq_t mq;
thd_t receiver;
thd_t senders[NSENDERS];
mq_t mq;
thd_t receiver;
thd_t senders[NSENDERS];
unsigned i;
expect_false(mq_init(&mq), "Unexpected mq_init() failure");
@ -82,8 +82,5 @@ TEST_END
int
main(void) {
return test(
test_mq_basic,
test_mq_threaded);
return test(test_mq_basic, test_mq_threaded);
}

View file

@ -1,7 +1,7 @@
#include "test/jemalloc_test.h"
#define NTHREADS 2
#define NINCRS 2000000
#define NTHREADS 2
#define NINCRS 2000000
TEST_BEGIN(test_mtx_basic) {
mtx_t mtx;
@ -14,14 +14,14 @@ TEST_BEGIN(test_mtx_basic) {
TEST_END
typedef struct {
mtx_t mtx;
unsigned x;
mtx_t mtx;
unsigned x;
} thd_start_arg_t;
static void *
thd_start(void *varg) {
thd_start_arg_t *arg = (thd_start_arg_t *)varg;
unsigned i;
unsigned i;
for (i = 0; i < NINCRS; i++) {
mtx_lock(&arg->mtx);
@ -33,8 +33,8 @@ thd_start(void *varg) {
TEST_BEGIN(test_mtx_race) {
thd_start_arg_t arg;
thd_t thds[NTHREADS];
unsigned i;
thd_t thds[NTHREADS];
unsigned i;
expect_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure");
arg.x = 0;
@ -44,14 +44,12 @@ TEST_BEGIN(test_mtx_race) {
for (i = 0; i < NTHREADS; i++) {
thd_join(thds[i], NULL);
}
expect_u_eq(arg.x, NTHREADS * NINCRS,
"Race-related counter corruption");
expect_u_eq(
arg.x, NTHREADS * NINCRS, "Race-related counter corruption");
}
TEST_END
int
main(void) {
return test(
test_mtx_basic,
test_mtx_race);
return test(test_mtx_basic, test_mtx_race);
}

View file

@ -2,10 +2,10 @@
#include "test/san.h"
const char *malloc_conf =
"tcache_ncached_max:256-1024:1001|2048-2048:0|8192-8192:1,tcache_max:4096";
"tcache_ncached_max:256-1024:1001|2048-2048:0|8192-8192:1,tcache_max:4096";
extern void tcache_bin_info_compute(
cache_bin_info_t tcache_bin_info[TCACHE_NBINS_MAX]);
extern bool tcache_get_default_ncached_max_set(szind_t ind);
extern bool tcache_get_default_ncached_max_set(szind_t ind);
extern const cache_bin_info_t *tcache_get_default_ncached_max(void);
static void
@ -13,54 +13,54 @@ check_bins_info(cache_bin_info_t tcache_bin_info[TCACHE_NBINS_MAX]) {
size_t mib_get[4], mib_get_len;
mib_get_len = sizeof(mib_get) / sizeof(size_t);
const char *get_name = "thread.tcache.ncached_max.read_sizeclass";
size_t ncached_max;
size_t sz = sizeof(size_t);
size_t ncached_max;
size_t sz = sizeof(size_t);
expect_d_eq(mallctlnametomib(get_name, mib_get, &mib_get_len), 0,
"Unexpected mallctlnametomib() failure");
for (szind_t i = 0; i < TCACHE_NBINS_MAX; i++) {
size_t bin_size = sz_index2size(i);
expect_d_eq(mallctlbymib(mib_get, mib_get_len,
(void *)&ncached_max, &sz,
(void *)&bin_size, sizeof(size_t)), 0,
"Unexpected mallctlbymib() failure");
expect_d_eq(
mallctlbymib(mib_get, mib_get_len, (void *)&ncached_max,
&sz, (void *)&bin_size, sizeof(size_t)),
0, "Unexpected mallctlbymib() failure");
expect_zu_eq(ncached_max, tcache_bin_info[i].ncached_max,
"Unexpected ncached_max for bin %d", i);
/* Check ncached_max returned under a non-bin size. */
bin_size--;
size_t temp_ncached_max = 0;
expect_d_eq(mallctlbymib(mib_get, mib_get_len,
(void *)&temp_ncached_max, &sz,
(void *)&bin_size, sizeof(size_t)), 0,
"Unexpected mallctlbymib() failure");
(void *)&temp_ncached_max, &sz,
(void *)&bin_size, sizeof(size_t)),
0, "Unexpected mallctlbymib() failure");
expect_zu_eq(temp_ncached_max, ncached_max,
"Unexpected ncached_max for inaccurate bin size.");
}
}
static void *
ncached_max_check(void* args) {
ncached_max_check(void *args) {
cache_bin_info_t tcache_bin_info[TCACHE_NBINS_MAX];
cache_bin_info_t tcache_bin_info_backup[TCACHE_NBINS_MAX];
tsd_t *tsd = tsd_fetch();
tcache_t *tcache = tsd_tcachep_get(tsd);
tsd_t *tsd = tsd_fetch();
tcache_t *tcache = tsd_tcachep_get(tsd);
assert(tcache != NULL);
tcache_slow_t *tcache_slow = tcache->tcache_slow;
tcache_bin_info_compute(tcache_bin_info);
memcpy(tcache_bin_info_backup, tcache_bin_info,
sizeof(tcache_bin_info));
memcpy(
tcache_bin_info_backup, tcache_bin_info, sizeof(tcache_bin_info));
/* Check ncached_max set by malloc_conf. */
for (szind_t i = 0; i < TCACHE_NBINS_MAX; i++) {
bool first_range = (i >= sz_size2index(256) &&
i <= sz_size2index(1024));
bool second_range = (i == sz_size2index(2048));
bool third_range = (i == sz_size2index(8192));
bool first_range = (i >= sz_size2index(256)
&& i <= sz_size2index(1024));
bool second_range = (i == sz_size2index(2048));
bool third_range = (i == sz_size2index(8192));
cache_bin_sz_t target_ncached_max = 0;
if (first_range || second_range || third_range) {
target_ncached_max = first_range ? 1001:
(second_range ? 0: 1);
target_ncached_max = first_range
? 1001
: (second_range ? 0 : 1);
expect_true(tcache_get_default_ncached_max_set(i),
"Unexpected state for bin %u", i);
expect_zu_eq(target_ncached_max,
@ -88,13 +88,13 @@ ncached_max_check(void* args) {
"Unexpected mallctlnametomib() failure");
/* Test the ncached_max set with tcache on. */
char inputs[100] = "8-128:1|160-160:11|170-320:22|224-8388609:0";
char inputs[100] = "8-128:1|160-160:11|170-320:22|224-8388609:0";
char *inputp = inputs;
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), 0,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
0, "Unexpected mallctlbymib() failure");
for (szind_t i = 0; i < TCACHE_NBINS_MAX; i++) {
if (i >= sz_size2index(8) &&i <= sz_size2index(128)) {
if (i >= sz_size2index(8) && i <= sz_size2index(128)) {
cache_bin_info_init(&tcache_bin_info[i], 1);
}
if (i == sz_size2index(160)) {
@ -119,16 +119,17 @@ ncached_max_check(void* args) {
* the new setting will not be carried on. Instead, the default
* settings will be applied.
*/
bool e0 = false, e1;
bool e0 = false, e1;
size_t bool_sz = sizeof(bool);
expect_d_eq(mallctl("thread.tcache.enabled", (void *)&e1, &bool_sz,
(void *)&e0, bool_sz), 0, "Unexpected mallctl() error");
(void *)&e0, bool_sz),
0, "Unexpected mallctl() error");
expect_true(e1, "Unexpected previous tcache state");
strcpy(inputs, "0-112:8");
/* Setting returns ENOENT when the tcache is disabled. */
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), ENOENT,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
ENOENT, "Unexpected mallctlbymib() failure");
/* All ncached_max should return 0 once tcache is disabled. */
for (szind_t i = 0; i < TCACHE_NBINS_MAX; i++) {
cache_bin_info_init(&tcache_bin_info[i], 0);
@ -137,12 +138,13 @@ ncached_max_check(void* args) {
e0 = true;
expect_d_eq(mallctl("thread.tcache.enabled", (void *)&e1, &bool_sz,
(void *)&e0, bool_sz), 0, "Unexpected mallctl() error");
(void *)&e0, bool_sz),
0, "Unexpected mallctl() error");
expect_false(e1, "Unexpected previous tcache state");
memcpy(tcache_bin_info, tcache_bin_info_backup,
sizeof(tcache_bin_info_backup));
for (szind_t i = tcache_nbins_get(tcache_slow); i < TCACHE_NBINS_MAX;
i++) {
i++) {
cache_bin_info_init(&tcache_bin_info[i], 0);
}
check_bins_info(tcache_bin_info);
@ -152,22 +154,22 @@ ncached_max_check(void* args) {
* resetting tcache_max. The ncached_max changes should stay.
*/
size_t tcache_max = 1024;
assert_d_eq(mallctl("thread.tcache.max",
NULL, NULL, (void *)&tcache_max, sizeof(size_t)),.0,
"Unexpected.mallctl().failure");
assert_d_eq(mallctl("thread.tcache.max", NULL, NULL,
(void *)&tcache_max, sizeof(size_t)),
.0, "Unexpected.mallctl().failure");
for (szind_t i = sz_size2index(1024) + 1; i < TCACHE_NBINS_MAX; i++) {
cache_bin_info_init(&tcache_bin_info[i], 0);
}
strcpy(inputs, "2048-6144:123");
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), 0,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
0, "Unexpected mallctlbymib() failure");
check_bins_info(tcache_bin_info);
tcache_max = 6144;
assert_d_eq(mallctl("thread.tcache.max",
NULL, NULL, (void *)&tcache_max, sizeof(size_t)),.0,
"Unexpected.mallctl().failure");
assert_d_eq(mallctl("thread.tcache.max", NULL, NULL,
(void *)&tcache_max, sizeof(size_t)),
.0, "Unexpected.mallctl().failure");
memcpy(tcache_bin_info, tcache_bin_info_backup,
sizeof(tcache_bin_info_backup));
for (szind_t i = sz_size2index(2048); i < TCACHE_NBINS_MAX; i++) {
@ -182,15 +184,15 @@ ncached_max_check(void* args) {
/* Test an empty input, it should do nothing. */
strcpy(inputs, "");
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), 0,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
0, "Unexpected mallctlbymib() failure");
check_bins_info(tcache_bin_info);
/* Test a half-done string, it should return EINVAL and do nothing. */
strcpy(inputs, "4-1024:7|256-1024");
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), EINVAL,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
EINVAL, "Unexpected mallctlbymib() failure");
check_bins_info(tcache_bin_info);
/*
@ -199,8 +201,8 @@ ncached_max_check(void* args) {
*/
strcpy(inputs, "1024-256:7");
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), 0,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
0, "Unexpected mallctlbymib() failure");
check_bins_info(tcache_bin_info);
/*
@ -216,8 +218,8 @@ ncached_max_check(void* args) {
long_inputs[200 * 9 + 8] = '\0';
inputp = long_inputs;
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), EINVAL,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
EINVAL, "Unexpected mallctlbymib() failure");
check_bins_info(tcache_bin_info);
free(long_inputs);
@ -228,17 +230,17 @@ ncached_max_check(void* args) {
strcpy(inputs, "k8-1024:77p");
inputp = inputs;
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), EINVAL,
"Unexpected mallctlbymib() failure");
(void *)&inputp, sizeof(char *)),
EINVAL, "Unexpected mallctlbymib() failure");
check_bins_info(tcache_bin_info);
/* Test large ncached_max, it should return success but capped. */
strcpy(inputs, "1024-1024:65540");
expect_d_eq(mallctlbymib(mib_set, mib_set_len, NULL, NULL,
(void *)&inputp, sizeof(char *)), 0,
"Unexpected mallctlbymib() failure");
cache_bin_info_init(&tcache_bin_info[sz_size2index(1024)],
CACHE_BIN_NCACHED_MAX);
(void *)&inputp, sizeof(char *)),
0, "Unexpected mallctlbymib() failure");
cache_bin_info_init(
&tcache_bin_info[sz_size2index(1024)], CACHE_BIN_NCACHED_MAX);
check_bins_info(tcache_bin_info);
return NULL;
@ -262,7 +264,5 @@ TEST_END
int
main(void) {
return test(
test_ncached_max);
return test(test_ncached_max);
}

View file

@ -1,6 +1,6 @@
#include "test/jemalloc_test.h"
#define BILLION UINT64_C(1000000000)
#define BILLION UINT64_C(1000000000)
TEST_BEGIN(test_nstime_init) {
nstime_t nst;
@ -43,24 +43,24 @@ TEST_BEGIN(test_nstime_compare) {
nstime_init2(&nstb, 42, 42);
expect_d_eq(nstime_compare(&nsta, &nstb), 1,
"nsta should be greater than nstb");
expect_d_eq(nstime_compare(&nstb, &nsta), -1,
"nstb should be less than nsta");
expect_d_eq(
nstime_compare(&nstb, &nsta), -1, "nstb should be less than nsta");
nstime_init2(&nstb, 42, 44);
expect_d_eq(nstime_compare(&nsta, &nstb), -1,
"nsta should be less than nstb");
expect_d_eq(
nstime_compare(&nsta, &nstb), -1, "nsta should be less than nstb");
expect_d_eq(nstime_compare(&nstb, &nsta), 1,
"nstb should be greater than nsta");
nstime_init2(&nstb, 41, BILLION - 1);
expect_d_eq(nstime_compare(&nsta, &nstb), 1,
"nsta should be greater than nstb");
expect_d_eq(nstime_compare(&nstb, &nsta), -1,
"nstb should be less than nsta");
expect_d_eq(
nstime_compare(&nstb, &nsta), -1, "nstb should be less than nsta");
nstime_init2(&nstb, 43, 0);
expect_d_eq(nstime_compare(&nsta, &nstb), -1,
"nsta should be less than nstb");
expect_d_eq(
nstime_compare(&nsta, &nstb), -1, "nsta should be less than nstb");
expect_d_eq(nstime_compare(&nstb, &nsta), 1,
"nstb should be greater than nsta");
}
@ -73,15 +73,15 @@ TEST_BEGIN(test_nstime_add) {
nstime_copy(&nstb, &nsta);
nstime_add(&nsta, &nstb);
nstime_init2(&nstb, 84, 86);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect addition result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect addition result");
nstime_init2(&nsta, 42, BILLION - 1);
nstime_copy(&nstb, &nsta);
nstime_add(&nsta, &nstb);
nstime_init2(&nstb, 85, BILLION - 2);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect addition result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect addition result");
}
TEST_END
@ -91,14 +91,14 @@ TEST_BEGIN(test_nstime_iadd) {
nstime_init2(&nsta, 42, BILLION - 1);
nstime_iadd(&nsta, 1);
nstime_init2(&nstb, 43, 0);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect addition result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect addition result");
nstime_init2(&nsta, 42, 1);
nstime_iadd(&nsta, BILLION + 1);
nstime_init2(&nstb, 43, 2);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect addition result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect addition result");
}
TEST_END
@ -109,15 +109,15 @@ TEST_BEGIN(test_nstime_subtract) {
nstime_copy(&nstb, &nsta);
nstime_subtract(&nsta, &nstb);
nstime_init_zero(&nstb);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect subtraction result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect subtraction result");
nstime_init2(&nsta, 42, 43);
nstime_init2(&nstb, 41, 44);
nstime_subtract(&nsta, &nstb);
nstime_init2(&nstb, 0, BILLION - 1);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect subtraction result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect subtraction result");
}
TEST_END
@ -125,16 +125,16 @@ TEST_BEGIN(test_nstime_isubtract) {
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_isubtract(&nsta, 42*BILLION + 43);
nstime_isubtract(&nsta, 42 * BILLION + 43);
nstime_init_zero(&nstb);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect subtraction result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect subtraction result");
nstime_init2(&nsta, 42, 43);
nstime_isubtract(&nsta, 41*BILLION + 44);
nstime_isubtract(&nsta, 41 * BILLION + 44);
nstime_init2(&nstb, 0, BILLION - 1);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect subtraction result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect subtraction result");
}
TEST_END
@ -144,14 +144,14 @@ TEST_BEGIN(test_nstime_imultiply) {
nstime_init2(&nsta, 42, 43);
nstime_imultiply(&nsta, 10);
nstime_init2(&nstb, 420, 430);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect multiplication result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect multiplication result");
nstime_init2(&nsta, 42, 666666666);
nstime_imultiply(&nsta, 3);
nstime_init2(&nstb, 127, 999999998);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect multiplication result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect multiplication result");
}
TEST_END
@ -162,15 +162,15 @@ TEST_BEGIN(test_nstime_idivide) {
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 10);
nstime_idivide(&nsta, 10);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect division result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect division result");
nstime_init2(&nsta, 42, 666666666);
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 3);
nstime_idivide(&nsta, 3);
expect_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect division result");
expect_d_eq(
nstime_compare(&nsta, &nstb), 0, "Incorrect division result");
}
TEST_END
@ -180,24 +180,24 @@ TEST_BEGIN(test_nstime_divide) {
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 10);
expect_u64_eq(nstime_divide(&nsta, &nstb), 10,
"Incorrect division result");
expect_u64_eq(
nstime_divide(&nsta, &nstb), 10, "Incorrect division result");
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 10);
nstime_init(&nstc, 1);
nstime_add(&nsta, &nstc);
expect_u64_eq(nstime_divide(&nsta, &nstb), 10,
"Incorrect division result");
expect_u64_eq(
nstime_divide(&nsta, &nstb), 10, "Incorrect division result");
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 10);
nstime_init(&nstc, 1);
nstime_subtract(&nsta, &nstc);
expect_u64_eq(nstime_divide(&nsta, &nstb), 9,
"Incorrect division result");
expect_u64_eq(
nstime_divide(&nsta, &nstb), 9, "Incorrect division result");
}
TEST_END
@ -213,8 +213,8 @@ test_nstime_since_once(nstime_t *t) {
nstime_copy(&new_t, t);
nstime_subtract(&new_t, &old_t);
expect_u64_ge(nstime_ns(&new_t), ns_since,
"Incorrect time since result");
expect_u64_ge(
nstime_ns(&new_t), ns_since, "Incorrect time since result");
}
TEST_BEGIN(test_nstime_ns_since) {
@ -253,19 +253,9 @@ TEST_END
int
main(void) {
return test(
test_nstime_init,
test_nstime_init2,
test_nstime_copy,
test_nstime_compare,
test_nstime_add,
test_nstime_iadd,
test_nstime_subtract,
test_nstime_isubtract,
test_nstime_imultiply,
test_nstime_idivide,
test_nstime_divide,
test_nstime_ns_since,
test_nstime_ms_since,
test_nstime_monotonic);
return test(test_nstime_init, test_nstime_init2, test_nstime_copy,
test_nstime_compare, test_nstime_add, test_nstime_iadd,
test_nstime_subtract, test_nstime_isubtract, test_nstime_imultiply,
test_nstime_idivide, test_nstime_divide, test_nstime_ns_since,
test_nstime_ms_since, test_nstime_monotonic);
}

View file

@ -5,7 +5,7 @@
static void
arena_mallctl(const char *mallctl_str, unsigned arena, void *oldp,
size_t *oldlen, void *newp, size_t newlen) {
int err;
int err;
char buf[100];
malloc_snprintf(buf, sizeof(buf), mallctl_str, arena);
@ -14,13 +14,13 @@ arena_mallctl(const char *mallctl_str, unsigned arena, void *oldp,
}
TEST_BEGIN(test_oversize_threshold_get_set) {
int err;
int err;
size_t old_threshold;
size_t new_threshold;
size_t threshold_sz = sizeof(old_threshold);
unsigned arena;
size_t arena_sz = sizeof(arena);
size_t arena_sz = sizeof(arena);
err = mallctl("arenas.create", (void *)&arena, &arena_sz, NULL, 0);
expect_d_eq(0, err, "Arena creation failed");
@ -38,13 +38,14 @@ TEST_BEGIN(test_oversize_threshold_get_set) {
/* Just a read */
arena_mallctl("arena.%u.oversize_threshold", arena, &old_threshold,
&threshold_sz, NULL, 0);
expect_zu_eq(2 * 1024 * 1024, old_threshold, "Should have read old value");
expect_zu_eq(
2 * 1024 * 1024, old_threshold, "Should have read old value");
}
TEST_END
static size_t max_purged = 0;
static bool
purge_forced_record_max(extent_hooks_t* hooks, void *addr, size_t sz,
purge_forced_record_max(extent_hooks_t *hooks, void *addr, size_t sz,
size_t offset, size_t length, unsigned arena_ind) {
if (length > max_purged) {
max_purged = length;
@ -73,7 +74,7 @@ TEST_BEGIN(test_oversize_threshold) {
int err;
unsigned arena;
size_t arena_sz = sizeof(arena);
size_t arena_sz = sizeof(arena);
err = mallctl("arenas.create", (void *)&arena, &arena_sz, NULL, 0);
expect_d_eq(0, err, "Arena creation failed");
arena_mallctl("arena.%u.extent_hooks", arena, NULL, NULL, &extent_hooks,
@ -121,8 +122,8 @@ TEST_BEGIN(test_oversize_threshold) {
ptr = mallocx(2 * 1024 * 1024, MALLOCX_ARENA(arena));
dallocx(ptr, MALLOCX_TCACHE_NONE);
if (!is_background_thread_enabled()) {
expect_zu_ge(max_purged, 2 * 1024 * 1024,
"Expected a 2MB purge");
expect_zu_ge(
max_purged, 2 * 1024 * 1024, "Expected a 2MB purge");
}
}
TEST_END
@ -130,7 +131,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_oversize_threshold_get_set,
test_oversize_threshold);
test_oversize_threshold_get_set, test_oversize_threshold);
}

View file

@ -16,8 +16,8 @@ merge_hook(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a,
}
static bool
split_hook(extent_hooks_t *extent_hooks, void *addr, size_t size,
size_t size_a, size_t size_b, bool committed, unsigned arena_ind) {
split_hook(extent_hooks_t *extent_hooks, void *addr, size_t size, size_t size_a,
size_t size_b, bool committed, unsigned arena_ind) {
return !maps_coalesce;
}
@ -39,13 +39,13 @@ init_test_extent_hooks(extent_hooks_t *hooks) {
typedef struct test_data_s test_data_t;
struct test_data_s {
pa_shard_t shard;
pa_central_t central;
base_t *base;
emap_t emap;
pa_shard_t shard;
pa_central_t central;
base_t *base;
emap_t emap;
pa_shard_stats_t stats;
malloc_mutex_t stats_mtx;
extent_hooks_t hooks;
malloc_mutex_t stats_mtx;
extent_hooks_t hooks;
};
static test_data_t *
@ -66,8 +66,8 @@ init_test_data(ssize_t dirty_decay_ms, ssize_t muzzy_decay_ms) {
nstime_t time;
nstime_init(&time, 0);
err = pa_central_init(&test_data->central, base, opt_hpa,
&hpa_hooks_default);
err = pa_central_init(
&test_data->central, base, opt_hpa, &hpa_hooks_default);
assert_false(err, "");
const size_t pa_oversize_threshold = 8 * 1024 * 1024;
@ -80,7 +80,8 @@ init_test_data(ssize_t dirty_decay_ms, ssize_t muzzy_decay_ms) {
return test_data;
}
void destroy_test_data(test_data_t *data) {
void
destroy_test_data(test_data_t *data) {
base_delete(TSDN_NULL, data->base);
free(data);
}
@ -89,28 +90,28 @@ static void *
do_alloc_free_purge(void *arg) {
test_data_t *test_data = (test_data_t *)arg;
for (int i = 0; i < 10 * 1000; i++) {
bool deferred_work_generated = false;
bool deferred_work_generated = false;
edata_t *edata = pa_alloc(TSDN_NULL, &test_data->shard, PAGE,
PAGE, /* slab */ false, /* szind */ 0, /* zero */ false,
/* guarded */ false, &deferred_work_generated);
assert_ptr_not_null(edata, "");
pa_dalloc(TSDN_NULL, &test_data->shard, edata,
&deferred_work_generated);
malloc_mutex_lock(TSDN_NULL,
&test_data->shard.pac.decay_dirty.mtx);
malloc_mutex_lock(
TSDN_NULL, &test_data->shard.pac.decay_dirty.mtx);
pac_decay_all(TSDN_NULL, &test_data->shard.pac,
&test_data->shard.pac.decay_dirty,
&test_data->shard.pac.stats->decay_dirty,
&test_data->shard.pac.ecache_dirty, true);
malloc_mutex_unlock(TSDN_NULL,
&test_data->shard.pac.decay_dirty.mtx);
malloc_mutex_unlock(
TSDN_NULL, &test_data->shard.pac.decay_dirty.mtx);
}
return NULL;
}
TEST_BEGIN(test_alloc_free_purge_thds) {
test_data_t *test_data = init_test_data(0, 0);
thd_t thds[4];
thd_t thds[4];
for (int i = 0; i < 4; i++) {
thd_create(&thds[i], do_alloc_free_purge, test_data);
}
@ -122,6 +123,5 @@ TEST_END
int
main(void) {
return test(
test_alloc_free_purge_thds);
return test(test_alloc_free_purge_thds);
}

View file

@ -4,9 +4,9 @@
* Size class that is a divisor of the page size, ideally 4+ regions per run.
*/
#if LG_PAGE <= 14
#define SZ (ZU(1) << (LG_PAGE - 2))
# define SZ (ZU(1) << (LG_PAGE - 2))
#else
#define SZ ZU(4096)
# define SZ ZU(4096)
#endif
/*
@ -14,11 +14,11 @@
* if mmap()ed memory grows downward, downward growth of mmap()ed memory is
* tested.
*/
#define NSLABS 8
#define NSLABS 8
static unsigned
binind_compute(void) {
size_t sz;
size_t sz;
unsigned nbins, i;
sz = sizeof(nbins);
@ -27,16 +27,17 @@ binind_compute(void) {
for (i = 0; i < nbins; i++) {
size_t mib[4];
size_t miblen = sizeof(mib)/sizeof(size_t);
size_t miblen = sizeof(mib) / sizeof(size_t);
size_t size;
expect_d_eq(mallctlnametomib("arenas.bin.0.size", mib,
&miblen), 0, "Unexpected mallctlnametomb failure");
expect_d_eq(mallctlnametomib("arenas.bin.0.size", mib, &miblen),
0, "Unexpected mallctlnametomb failure");
mib[2] = (size_t)i;
sz = sizeof(size);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&size, &sz, NULL,
0), 0, "Unexpected mallctlbymib failure");
expect_d_eq(
mallctlbymib(mib, miblen, (void *)&size, &sz, NULL, 0), 0,
"Unexpected mallctlbymib failure");
if (size == SZ) {
return i;
}
@ -49,24 +50,24 @@ binind_compute(void) {
static size_t
nregs_per_run_compute(void) {
uint32_t nregs;
size_t sz;
size_t sz;
unsigned binind = binind_compute();
size_t mib[4];
size_t miblen = sizeof(mib)/sizeof(size_t);
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
expect_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
"Unexpected mallctlnametomb failure");
mib[2] = (size_t)binind;
sz = sizeof(nregs);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&nregs, &sz, NULL,
0), 0, "Unexpected mallctlbymib failure");
expect_d_eq(mallctlbymib(mib, miblen, (void *)&nregs, &sz, NULL, 0), 0,
"Unexpected mallctlbymib failure");
return nregs;
}
static unsigned
arenas_create_mallctl(void) {
unsigned arena_ind;
size_t sz;
size_t sz;
sz = sizeof(arena_ind);
expect_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz, NULL, 0),
@ -78,7 +79,7 @@ arenas_create_mallctl(void) {
static void
arena_reset_mallctl(unsigned arena_ind) {
size_t mib[3];
size_t miblen = sizeof(mib)/sizeof(size_t);
size_t miblen = sizeof(mib) / sizeof(size_t);
expect_d_eq(mallctlnametomib("arena.0.reset", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure");
@ -88,23 +89,23 @@ arena_reset_mallctl(unsigned arena_ind) {
}
TEST_BEGIN(test_pack) {
bool prof_enabled;
bool prof_enabled;
size_t sz = sizeof(prof_enabled);
if (mallctl("opt.prof", (void *)&prof_enabled, &sz, NULL, 0) == 0) {
test_skip_if(prof_enabled);
}
unsigned arena_ind = arenas_create_mallctl();
size_t nregs_per_run = nregs_per_run_compute();
size_t nregs = nregs_per_run * NSLABS;
size_t nregs_per_run = nregs_per_run_compute();
size_t nregs = nregs_per_run * NSLABS;
VARIABLE_ARRAY(void *, ptrs, nregs);
size_t i, j, offset;
/* Fill matrix. */
for (i = offset = 0; i < NSLABS; i++) {
for (j = 0; j < nregs_per_run; j++) {
void *p = mallocx(SZ, MALLOCX_ARENA(arena_ind) |
MALLOCX_TCACHE_NONE);
void *p = mallocx(
SZ, MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE);
expect_ptr_not_null(p,
"Unexpected mallocx(%zu, MALLOCX_ARENA(%u) |"
" MALLOCX_TCACHE_NONE) failure, run=%zu, reg=%zu",
@ -119,16 +120,15 @@ TEST_BEGIN(test_pack) {
* layout policy.
*/
offset = 0;
for (i = offset = 0;
i < NSLABS;
i++, offset = (offset + 1) % nregs_per_run) {
for (i = offset = 0; i < NSLABS;
i++, offset = (offset + 1) % nregs_per_run) {
for (j = 0; j < nregs_per_run; j++) {
void *p = ptrs[(i * nregs_per_run) + j];
if (offset == j) {
continue;
}
dallocx(p, MALLOCX_ARENA(arena_ind) |
MALLOCX_TCACHE_NONE);
dallocx(
p, MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE);
}
}
@ -137,17 +137,16 @@ TEST_BEGIN(test_pack) {
* that the matrix is unmodified.
*/
offset = 0;
for (i = offset = 0;
i < NSLABS;
i++, offset = (offset + 1) % nregs_per_run) {
for (i = offset = 0; i < NSLABS;
i++, offset = (offset + 1) % nregs_per_run) {
for (j = 0; j < nregs_per_run; j++) {
void *p;
if (offset == j) {
continue;
}
p = mallocx(SZ, MALLOCX_ARENA(arena_ind) |
MALLOCX_TCACHE_NONE);
p = mallocx(
SZ, MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE);
expect_ptr_eq(p, ptrs[(i * nregs_per_run) + j],
"Unexpected refill discrepancy, run=%zu, reg=%zu\n",
i, j);
@ -161,6 +160,5 @@ TEST_END
int
main(void) {
return test(
test_pack);
return test(test_pack);
}

View file

@ -2,8 +2,8 @@
TEST_BEGIN(test_pages_huge) {
size_t alloc_size;
bool commit;
void *pages, *hugepage;
bool commit;
void *pages, *hugepage;
alloc_size = HUGEPAGE * 2 - PAGE;
commit = true;
@ -11,11 +11,12 @@ TEST_BEGIN(test_pages_huge) {
expect_ptr_not_null(pages, "Unexpected pages_map() error");
if (init_system_thp_mode == thp_mode_default) {
hugepage = (void *)(ALIGNMENT_CEILING((uintptr_t)pages, HUGEPAGE));
expect_b_ne(pages_huge(hugepage, HUGEPAGE), have_madvise_huge,
"Unexpected pages_huge() result");
expect_false(pages_nohuge(hugepage, HUGEPAGE),
"Unexpected pages_nohuge() result");
hugepage = (void *)(ALIGNMENT_CEILING(
(uintptr_t)pages, HUGEPAGE));
expect_b_ne(pages_huge(hugepage, HUGEPAGE), have_madvise_huge,
"Unexpected pages_huge() result");
expect_false(pages_nohuge(hugepage, HUGEPAGE),
"Unexpected pages_nohuge() result");
}
pages_unmap(pages, alloc_size);
@ -24,6 +25,5 @@ TEST_END
int
main(void) {
return test(
test_pages_huge);
return test(test_pages_huge);
}

View file

@ -4,11 +4,10 @@
TEST_BEGIN(test_peak) {
peak_t peak = PEAK_INITIALIZER;
expect_u64_eq(0, peak_max(&peak),
"Peak should be zero at initialization");
expect_u64_eq(
0, peak_max(&peak), "Peak should be zero at initialization");
peak_update(&peak, 100, 50);
expect_u64_eq(50, peak_max(&peak),
"Missed update");
expect_u64_eq(50, peak_max(&peak), "Missed update");
peak_update(&peak, 100, 100);
expect_u64_eq(50, peak_max(&peak), "Dallocs shouldn't change peak");
peak_update(&peak, 100, 200);
@ -42,6 +41,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_peak);
return test_no_reentrancy(test_peak);
}

View file

@ -8,9 +8,9 @@ ph_structs(heap, node_t, BFS_ENUMERATE_MAX);
struct node_s {
#define NODE_MAGIC 0x9823af7e
uint32_t magic;
uint32_t magic;
heap_link_t link;
uint64_t key;
uint64_t key;
};
static int
@ -31,7 +31,6 @@ node_cmp(const node_t *a, const node_t *b) {
static int
node_cmp_magic(const node_t *a, const node_t *b) {
expect_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
expect_u32_eq(b->magic, NODE_MAGIC, "Bad magic");
@ -58,12 +57,12 @@ node_lchild_get(const node_t *node) {
static void
node_print(const node_t *node, unsigned depth) {
unsigned i;
node_t *leftmost_child, *sibling;
node_t *leftmost_child, *sibling;
for (i = 0; i < depth; i++) {
malloc_printf("\t");
}
malloc_printf("%2"FMTu64"\n", node->key);
malloc_printf("%2" FMTu64 "\n", node->key);
leftmost_child = node_lchild_get(node);
if (leftmost_child == NULL) {
@ -71,8 +70,8 @@ node_print(const node_t *node, unsigned depth) {
}
node_print(leftmost_child, depth + 1);
for (sibling = node_next_get(leftmost_child); sibling !=
NULL; sibling = node_next_get(sibling)) {
for (sibling = node_next_get(leftmost_child); sibling != NULL;
sibling = node_next_get(sibling)) {
node_print(sibling, depth + 1);
}
}
@ -89,7 +88,7 @@ heap_print(const heap_t *heap) {
node_print(heap->ph.root, 0);
for (auxelm = node_next_get(heap->ph.root); auxelm != NULL;
auxelm = node_next_get(auxelm)) {
auxelm = node_next_get(auxelm)) {
expect_ptr_eq(node_next_get(node_prev_get(auxelm)), auxelm,
"auxelm's prev doesn't link to auxelm");
node_print(auxelm, 0);
@ -102,7 +101,7 @@ label_return:
static unsigned
node_validate(const node_t *node, const node_t *parent) {
unsigned nnodes = 1;
node_t *leftmost_child, *sibling;
node_t *leftmost_child, *sibling;
if (parent != NULL) {
expect_d_ge(node_cmp_magic(node, parent), 0,
@ -113,12 +112,12 @@ node_validate(const node_t *node, const node_t *parent) {
if (leftmost_child == NULL) {
return nnodes;
}
expect_ptr_eq(node_prev_get(leftmost_child),
(void *)node, "Leftmost child does not link to node");
expect_ptr_eq(node_prev_get(leftmost_child), (void *)node,
"Leftmost child does not link to node");
nnodes += node_validate(leftmost_child, node);
for (sibling = node_next_get(leftmost_child); sibling !=
NULL; sibling = node_next_get(sibling)) {
for (sibling = node_next_get(leftmost_child); sibling != NULL;
sibling = node_next_get(sibling)) {
expect_ptr_eq(node_next_get(node_prev_get(sibling)), sibling,
"sibling's prev doesn't link to sibling");
nnodes += node_validate(sibling, node);
@ -129,7 +128,7 @@ node_validate(const node_t *node, const node_t *parent) {
static unsigned
heap_validate(const heap_t *heap) {
unsigned nnodes = 0;
node_t *auxelm;
node_t *auxelm;
if (heap->ph.root == NULL) {
goto label_return;
@ -138,7 +137,7 @@ heap_validate(const heap_t *heap) {
nnodes += node_validate(heap->ph.root, NULL);
for (auxelm = node_next_get(heap->ph.root); auxelm != NULL;
auxelm = node_next_get(auxelm)) {
auxelm = node_next_get(auxelm)) {
expect_ptr_eq(node_next_get(node_prev_get(auxelm)), auxelm,
"auxelm's prev doesn't link to auxelm");
nnodes += node_validate(auxelm, NULL);
@ -186,10 +185,10 @@ TEST_BEGIN(test_ph_random) {
#define NNODES 25
#define NBAGS 250
#define SEED 42
sfmt_t *sfmt;
sfmt_t *sfmt;
uint64_t bag[NNODES];
heap_t heap;
node_t nodes[NNODES];
heap_t heap;
node_t nodes[NNODES];
unsigned i, j, k;
sfmt = init_gen_rand(SEED);
@ -216,8 +215,8 @@ TEST_BEGIN(test_ph_random) {
for (j = 1; j <= NNODES; j++) {
/* Initialize heap and nodes. */
heap_new(&heap);
expect_u_eq(heap_validate(&heap), 0,
"Incorrect node count");
expect_u_eq(
heap_validate(&heap), 0, "Incorrect node count");
for (k = 0; k < j; k++) {
nodes[k].magic = NODE_MAGIC;
nodes[k].key = bag[k];
@ -237,8 +236,8 @@ TEST_BEGIN(test_ph_random) {
"Incorrect node count");
}
expect_false(heap_empty(&heap),
"Heap should not be empty");
expect_false(
heap_empty(&heap), "Heap should not be empty");
/* Enumerate nodes. */
heap_enumerate_helper_t helper;
@ -247,14 +246,14 @@ TEST_BEGIN(test_ph_random) {
expect_u_eq(max_queue_size, BFS_ENUMERATE_MAX,
"Incorrect bfs queue length initialized");
assert(max_queue_size == BFS_ENUMERATE_MAX);
heap_enumerate_prepare(&heap, &helper,
BFS_ENUMERATE_MAX, max_queue_size);
heap_enumerate_prepare(
&heap, &helper, BFS_ENUMERATE_MAX, max_queue_size);
size_t node_count = 0;
while(heap_enumerate_next(&heap, &helper)) {
node_count ++;
while (heap_enumerate_next(&heap, &helper)) {
node_count++;
}
expect_lu_eq(node_count, j,
"Unexpected enumeration results.");
expect_lu_eq(
node_count, j, "Unexpected enumeration results.");
/* Remove nodes. */
switch (i % 6) {
@ -263,13 +262,13 @@ TEST_BEGIN(test_ph_random) {
expect_u_eq(heap_validate(&heap), j - k,
"Incorrect node count");
node_remove(&heap, &nodes[k]);
expect_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
expect_u_eq(heap_validate(&heap),
j - k - 1, "Incorrect node count");
}
break;
case 1:
for (k = j; k > 0; k--) {
node_remove(&heap, &nodes[k-1]);
node_remove(&heap, &nodes[k - 1]);
expect_u_eq(heap_validate(&heap), k - 1,
"Incorrect node count");
}
@ -278,58 +277,62 @@ TEST_BEGIN(test_ph_random) {
node_t *prev = NULL;
for (k = 0; k < j; k++) {
node_t *node = node_remove_first(&heap);
expect_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
expect_u_eq(heap_validate(&heap),
j - k - 1, "Incorrect node count");
if (prev != NULL) {
expect_d_ge(node_cmp(node,
prev), 0,
expect_d_ge(
node_cmp(node, prev), 0,
"Bad removal order");
}
prev = node;
}
break;
} case 3: {
}
case 3: {
node_t *prev = NULL;
for (k = 0; k < j; k++) {
node_t *node = heap_first(&heap);
expect_u_eq(heap_validate(&heap), j - k,
"Incorrect node count");
if (prev != NULL) {
expect_d_ge(node_cmp(node,
prev), 0,
expect_d_ge(
node_cmp(node, prev), 0,
"Bad removal order");
}
node_remove(&heap, node);
expect_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
expect_u_eq(heap_validate(&heap),
j - k - 1, "Incorrect node count");
prev = node;
}
break;
} case 4: {
}
case 4: {
for (k = 0; k < j; k++) {
node_remove_any(&heap);
expect_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
expect_u_eq(heap_validate(&heap),
j - k - 1, "Incorrect node count");
}
break;
} case 5: {
}
case 5: {
for (k = 0; k < j; k++) {
node_t *node = heap_any(&heap);
expect_u_eq(heap_validate(&heap), j - k,
"Incorrect node count");
node_remove(&heap, node);
expect_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
expect_u_eq(heap_validate(&heap),
j - k - 1, "Incorrect node count");
}
break;
} default:
}
default:
not_reached();
}
expect_ptr_null(heap_first(&heap),
"Heap should be empty");
expect_ptr_null(heap_any(&heap),
"Heap should be empty");
expect_ptr_null(
heap_first(&heap), "Heap should be empty");
expect_ptr_null(
heap_any(&heap), "Heap should be empty");
expect_true(heap_empty(&heap), "Heap should be empty");
}
}
@ -341,7 +344,5 @@ TEST_END
int
main(void) {
return test(
test_ph_empty,
test_ph_random);
return test(test_ph_empty, test_ph_random);
}

View file

@ -9,32 +9,31 @@ TEST_BEGIN(test_prng_lg_range_u32) {
ra = prng_lg_range_u32(&sa, 32);
sa = 42;
rb = prng_lg_range_u32(&sa, 32);
expect_u32_eq(ra, rb,
"Repeated generation should produce repeated results");
expect_u32_eq(
ra, rb, "Repeated generation should produce repeated results");
sb = 42;
rb = prng_lg_range_u32(&sb, 32);
expect_u32_eq(ra, rb,
"Equivalent generation should produce equivalent results");
expect_u32_eq(
ra, rb, "Equivalent generation should produce equivalent results");
sa = 42;
ra = prng_lg_range_u32(&sa, 32);
rb = prng_lg_range_u32(&sa, 32);
expect_u32_ne(ra, rb,
"Full-width results must not immediately repeat");
expect_u32_ne(ra, rb, "Full-width results must not immediately repeat");
sa = 42;
ra = prng_lg_range_u32(&sa, 32);
for (lg_range = 31; lg_range > 0; lg_range--) {
sb = 42;
rb = prng_lg_range_u32(&sb, lg_range);
expect_u32_eq((rb & (UINT32_C(0xffffffff) << lg_range)),
0, "High order bits should be 0, lg_range=%u", lg_range);
expect_u32_eq((rb & (UINT32_C(0xffffffff) << lg_range)), 0,
"High order bits should be 0, lg_range=%u", lg_range);
expect_u32_eq(rb, (ra >> (32 - lg_range)),
"Expected high order bits of full-width result, "
"lg_range=%u", lg_range);
"lg_range=%u",
lg_range);
}
}
TEST_END
@ -46,19 +45,18 @@ TEST_BEGIN(test_prng_lg_range_u64) {
ra = prng_lg_range_u64(&sa, 64);
sa = 42;
rb = prng_lg_range_u64(&sa, 64);
expect_u64_eq(ra, rb,
"Repeated generation should produce repeated results");
expect_u64_eq(
ra, rb, "Repeated generation should produce repeated results");
sb = 42;
rb = prng_lg_range_u64(&sb, 64);
expect_u64_eq(ra, rb,
"Equivalent generation should produce equivalent results");
expect_u64_eq(
ra, rb, "Equivalent generation should produce equivalent results");
sa = 42;
ra = prng_lg_range_u64(&sa, 64);
rb = prng_lg_range_u64(&sa, 64);
expect_u64_ne(ra, rb,
"Full-width results must not immediately repeat");
expect_u64_ne(ra, rb, "Full-width results must not immediately repeat");
sa = 42;
ra = prng_lg_range_u64(&sa, 64);
@ -69,47 +67,48 @@ TEST_BEGIN(test_prng_lg_range_u64) {
0, "High order bits should be 0, lg_range=%u", lg_range);
expect_u64_eq(rb, (ra >> (64 - lg_range)),
"Expected high order bits of full-width result, "
"lg_range=%u", lg_range);
"lg_range=%u",
lg_range);
}
}
TEST_END
TEST_BEGIN(test_prng_lg_range_zu) {
size_t sa, sb;
size_t ra, rb;
size_t sa, sb;
size_t ra, rb;
unsigned lg_range;
sa = 42;
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR));
sa = 42;
rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR));
expect_zu_eq(ra, rb,
"Repeated generation should produce repeated results");
expect_zu_eq(
ra, rb, "Repeated generation should produce repeated results");
sb = 42;
rb = prng_lg_range_zu(&sb, ZU(1) << (3 + LG_SIZEOF_PTR));
expect_zu_eq(ra, rb,
"Equivalent generation should produce equivalent results");
expect_zu_eq(
ra, rb, "Equivalent generation should produce equivalent results");
sa = 42;
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR));
rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR));
expect_zu_ne(ra, rb,
"Full-width results must not immediately repeat");
expect_zu_ne(ra, rb, "Full-width results must not immediately repeat");
sa = 42;
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR));
for (lg_range = (ZU(1) << (3 + LG_SIZEOF_PTR)) - 1; lg_range > 0;
lg_range--) {
lg_range--) {
sb = 42;
rb = prng_lg_range_zu(&sb, lg_range);
expect_zu_eq((rb & (SIZE_T_MAX << lg_range)),
0, "High order bits should be 0, lg_range=%u", lg_range);
expect_zu_eq(rb, (ra >> ((ZU(1) << (3 + LG_SIZEOF_PTR)) -
lg_range)), "Expected high order bits of full-width "
"result, lg_range=%u", lg_range);
expect_zu_eq((rb & (SIZE_T_MAX << lg_range)), 0,
"High order bits should be 0, lg_range=%u", lg_range);
expect_zu_eq(rb,
(ra >> ((ZU(1) << (3 + LG_SIZEOF_PTR)) - lg_range)),
"Expected high order bits of full-width "
"result, lg_range=%u",
lg_range);
}
}
TEST_END
@ -158,13 +157,12 @@ TEST_END
TEST_BEGIN(test_prng_range_zu) {
size_t range;
const size_t max_range = 10000000;
const size_t range_step = 97;
const size_t max_range = 10000000;
const size_t range_step = 97;
const unsigned nreps = 10;
for (range = 2; range < max_range; range += range_step) {
size_t s;
size_t s;
unsigned rep;
s = range;
@ -179,11 +177,7 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_prng_lg_range_u32,
test_prng_lg_range_u64,
test_prng_lg_range_zu,
test_prng_range_u32,
test_prng_range_u64,
test_prng_range_zu);
return test_no_reentrancy(test_prng_lg_range_u32,
test_prng_lg_range_u64, test_prng_lg_range_zu, test_prng_range_u32,
test_prng_range_u64, test_prng_range_zu);
}

View file

@ -3,10 +3,10 @@
#include "jemalloc/internal/prof_data.h"
#include "jemalloc/internal/prof_sys.h"
#define NTHREADS 4
#define NALLOCS_PER_THREAD 50
#define DUMP_INTERVAL 1
#define BT_COUNT_CHECK_INTERVAL 5
#define NTHREADS 4
#define NALLOCS_PER_THREAD 50
#define DUMP_INTERVAL 1
#define BT_COUNT_CHECK_INTERVAL 5
static int
prof_dump_open_file_intercept(const char *filename, int mode) {
@ -20,13 +20,13 @@ prof_dump_open_file_intercept(const char *filename, int mode) {
static void *
alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration) {
return btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration);
return btalloc(1, thd_ind * NALLOCS_PER_THREAD + iteration);
}
static void *
thd_start(void *varg) {
unsigned thd_ind = *(unsigned *)varg;
size_t bt_count_prev, bt_count;
size_t bt_count_prev, bt_count;
unsigned i_prev, i;
i_prev = 0;
@ -39,10 +39,10 @@ thd_start(void *varg) {
0, "Unexpected error while dumping heap profile");
}
if (i % BT_COUNT_CHECK_INTERVAL == 0 ||
i+1 == NALLOCS_PER_THREAD) {
if (i % BT_COUNT_CHECK_INTERVAL == 0
|| i + 1 == NALLOCS_PER_THREAD) {
bt_count = prof_bt_count();
expect_zu_le(bt_count_prev+(i-i_prev), bt_count,
expect_zu_le(bt_count_prev + (i - i_prev), bt_count,
"Expected larger backtrace count increase");
i_prev = i;
bt_count_prev = bt_count;
@ -53,17 +53,17 @@ thd_start(void *varg) {
}
TEST_BEGIN(test_idump) {
bool active;
thd_t thds[NTHREADS];
bool active;
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
test_skip_if(!config_prof);
active = true;
expect_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
sizeof(active)), 0,
"Unexpected mallctl failure while activating profiling");
expect_d_eq(
mallctl("prof.active", NULL, NULL, (void *)&active, sizeof(active)),
0, "Unexpected mallctl failure while activating profiling");
prof_dump_open_file = prof_dump_open_file_intercept;
@ -79,6 +79,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_idump);
return test_no_reentrancy(test_idump);
}

View file

@ -4,37 +4,37 @@
static void
mallctl_bool_get(const char *name, bool expected, const char *func, int line) {
bool old;
bool old;
size_t sz;
sz = sizeof(old);
expect_d_eq(mallctl(name, (void *)&old, &sz, NULL, 0), 0,
"%s():%d: Unexpected mallctl failure reading %s", func, line, name);
expect_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line,
name);
expect_b_eq(
old, expected, "%s():%d: Unexpected %s value", func, line, name);
}
static void
mallctl_bool_set(const char *name, bool old_expected, bool val_new,
const char *func, int line) {
bool old;
bool old;
size_t sz;
sz = sizeof(old);
expect_d_eq(mallctl(name, (void *)&old, &sz, (void *)&val_new,
sizeof(val_new)), 0,
"%s():%d: Unexpected mallctl failure reading/writing %s", func,
expect_d_eq(
mallctl(name, (void *)&old, &sz, (void *)&val_new, sizeof(val_new)),
0, "%s():%d: Unexpected mallctl failure reading/writing %s", func,
line, name);
expect_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func,
line, name);
}
static void
mallctl_prof_active_get_impl(bool prof_active_old_expected, const char *func,
int line) {
mallctl_prof_active_get_impl(
bool prof_active_old_expected, const char *func, int line) {
mallctl_bool_get("prof.active", prof_active_old_expected, func, line);
}
#define mallctl_prof_active_get(a) \
#define mallctl_prof_active_get(a) \
mallctl_prof_active_get_impl(a, __func__, __LINE__)
static void
@ -43,16 +43,16 @@ mallctl_prof_active_set_impl(bool prof_active_old_expected,
mallctl_bool_set("prof.active", prof_active_old_expected,
prof_active_new, func, line);
}
#define mallctl_prof_active_set(a, b) \
#define mallctl_prof_active_set(a, b) \
mallctl_prof_active_set_impl(a, b, __func__, __LINE__)
static void
mallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected,
const char *func, int line) {
mallctl_bool_get("thread.prof.active", thread_prof_active_old_expected,
func, line);
mallctl_thread_prof_active_get_impl(
bool thread_prof_active_old_expected, const char *func, int line) {
mallctl_bool_get(
"thread.prof.active", thread_prof_active_old_expected, func, line);
}
#define mallctl_thread_prof_active_get(a) \
#define mallctl_thread_prof_active_get(a) \
mallctl_thread_prof_active_get_impl(a, __func__, __LINE__)
static void
@ -61,24 +61,23 @@ mallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected,
mallctl_bool_set("thread.prof.active", thread_prof_active_old_expected,
thread_prof_active_new, func, line);
}
#define mallctl_thread_prof_active_set(a, b) \
#define mallctl_thread_prof_active_set(a, b) \
mallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__)
static void
prof_sampling_probe_impl(bool expect_sample, const char *func, int line) {
void *p;
void *p;
size_t expected_backtraces = expect_sample ? 1 : 0;
expect_zu_eq(prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func,
line);
expect_zu_eq(
prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func, line);
p = mallocx(1, 0);
expect_ptr_not_null(p, "Unexpected mallocx() failure");
expect_zu_eq(prof_bt_count(), expected_backtraces,
"%s():%d: Unexpected backtrace count", func, line);
dallocx(p, 0);
}
#define prof_sampling_probe(a) \
prof_sampling_probe_impl(a, __func__, __LINE__)
#define prof_sampling_probe(a) prof_sampling_probe_impl(a, __func__, __LINE__)
TEST_BEGIN(test_prof_active) {
test_skip_if(!config_prof);
@ -114,6 +113,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_prof_active);
return test_no_reentrancy(test_prof_active);
}

View file

@ -18,16 +18,16 @@ prof_dump_open_file_intercept(const char *filename, int mode) {
TEST_BEGIN(test_gdump) {
test_skip_if(opt_hpa);
bool active, gdump, gdump_old;
void *p, *q, *r, *s;
bool active, gdump, gdump_old;
void *p, *q, *r, *s;
size_t sz;
test_skip_if(!config_prof);
active = true;
expect_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
sizeof(active)), 0,
"Unexpected mallctl failure while activating profiling");
expect_d_eq(
mallctl("prof.active", NULL, NULL, (void *)&active, sizeof(active)),
0, "Unexpected mallctl failure while activating profiling");
prof_dump_open_file = prof_dump_open_file_intercept;
@ -44,8 +44,8 @@ TEST_BEGIN(test_gdump) {
gdump = false;
sz = sizeof(gdump_old);
expect_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz,
(void *)&gdump, sizeof(gdump)), 0,
"Unexpected mallctl failure while disabling prof.gdump");
(void *)&gdump, sizeof(gdump)),
0, "Unexpected mallctl failure while disabling prof.gdump");
assert(gdump_old);
did_prof_dump_open = false;
r = mallocx((1U << SC_LG_LARGE_MINCLASS), 0);
@ -55,8 +55,8 @@ TEST_BEGIN(test_gdump) {
gdump = true;
sz = sizeof(gdump_old);
expect_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz,
(void *)&gdump, sizeof(gdump)), 0,
"Unexpected mallctl failure while enabling prof.gdump");
(void *)&gdump, sizeof(gdump)),
0, "Unexpected mallctl failure while enabling prof.gdump");
assert(!gdump_old);
did_prof_dump_open = false;
s = mallocx((1U << SC_LG_LARGE_MINCLASS), 0);
@ -72,6 +72,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_gdump);
return test_no_reentrancy(test_gdump);
}

View file

@ -14,10 +14,10 @@ bool mock_dump_hook_called = false;
bool mock_prof_sample_hook_called = false;
bool mock_prof_sample_free_hook_called = false;
void *sampled_ptr = NULL;
void *sampled_ptr = NULL;
size_t sampled_ptr_sz = 0;
size_t sampled_ptr_usz = 0;
void *free_sampled_ptr = NULL;
void *free_sampled_ptr = NULL;
size_t free_sampled_ptr_sz = 0;
void
@ -49,7 +49,6 @@ mock_bt_augmenting_hook(void **vec, unsigned *len, unsigned max_len) {
(*len)++;
}
mock_bt_hook_called = true;
}
@ -61,14 +60,15 @@ mock_dump_hook(const char *filename) {
}
void
mock_prof_sample_hook(const void *ptr, size_t sz, void **vec, unsigned len, size_t usz) {
mock_prof_sample_hook(
const void *ptr, size_t sz, void **vec, unsigned len, size_t usz) {
mock_prof_sample_hook_called = true;
sampled_ptr = (void *)ptr;
sampled_ptr_sz = sz;
sampled_ptr_usz = usz;
for (unsigned i = 0; i < len; i++) {
expect_ptr_not_null((void **)vec[i],
"Backtrace should not contain NULL");
expect_ptr_not_null(
(void **)vec[i], "Backtrace should not contain NULL");
}
}
@ -80,7 +80,6 @@ mock_prof_sample_free_hook(const void *ptr, size_t sz) {
}
TEST_BEGIN(test_prof_backtrace_hook_replace) {
test_skip_if(!config_prof);
mock_bt_hook_called = false;
@ -91,15 +90,16 @@ TEST_BEGIN(test_prof_backtrace_hook_replace) {
expect_false(mock_bt_hook_called, "Called mock hook before it's set");
prof_backtrace_hook_t null_hook = NULL;
expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
NULL, 0, (void *)&null_hook, sizeof(null_hook)),
EINVAL, "Incorrectly allowed NULL backtrace hook");
expect_d_eq(mallctl("experimental.hooks.prof_backtrace", NULL, 0,
(void *)&null_hook, sizeof(null_hook)),
EINVAL, "Incorrectly allowed NULL backtrace hook");
size_t default_bt_hook_sz = sizeof(prof_backtrace_hook_t);
prof_backtrace_hook_t hook = &mock_bt_hook;
expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
(void *)&default_bt_hook, &default_bt_hook_sz, (void *)&hook,
sizeof(hook)), 0, "Unexpected mallctl failure setting hook");
(void *)&default_bt_hook, &default_bt_hook_sz,
(void *)&hook, sizeof(hook)),
0, "Unexpected mallctl failure setting hook");
void *p1 = mallocx(1, 0);
assert_ptr_not_null(p1, "Failed to allocate");
@ -107,11 +107,11 @@ TEST_BEGIN(test_prof_backtrace_hook_replace) {
expect_true(mock_bt_hook_called, "Didn't call mock hook");
prof_backtrace_hook_t current_hook;
size_t current_hook_sz = sizeof(prof_backtrace_hook_t);
size_t current_hook_sz = sizeof(prof_backtrace_hook_t);
expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
(void *)&current_hook, &current_hook_sz, (void *)&default_bt_hook,
sizeof(default_bt_hook)), 0,
"Unexpected mallctl failure resetting hook to default");
(void *)&current_hook, &current_hook_sz,
(void *)&default_bt_hook, sizeof(default_bt_hook)),
0, "Unexpected mallctl failure resetting hook to default");
expect_ptr_eq(current_hook, hook,
"Hook returned by mallctl is not equal to mock hook");
@ -122,7 +122,6 @@ TEST_BEGIN(test_prof_backtrace_hook_replace) {
TEST_END
TEST_BEGIN(test_prof_backtrace_hook_augment) {
test_skip_if(!config_prof);
mock_bt_hook_called = false;
@ -135,8 +134,9 @@ TEST_BEGIN(test_prof_backtrace_hook_augment) {
size_t default_bt_hook_sz = sizeof(prof_backtrace_hook_t);
prof_backtrace_hook_t hook = &mock_bt_augmenting_hook;
expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
(void *)&default_bt_hook, &default_bt_hook_sz, (void *)&hook,
sizeof(hook)), 0, "Unexpected mallctl failure setting hook");
(void *)&default_bt_hook, &default_bt_hook_sz,
(void *)&hook, sizeof(hook)),
0, "Unexpected mallctl failure setting hook");
void *p1 = mallocx(1, 0);
assert_ptr_not_null(p1, "Failed to allocate");
@ -144,11 +144,11 @@ TEST_BEGIN(test_prof_backtrace_hook_augment) {
expect_true(mock_bt_hook_called, "Didn't call mock hook");
prof_backtrace_hook_t current_hook;
size_t current_hook_sz = sizeof(prof_backtrace_hook_t);
size_t current_hook_sz = sizeof(prof_backtrace_hook_t);
expect_d_eq(mallctl("experimental.hooks.prof_backtrace",
(void *)&current_hook, &current_hook_sz, (void *)&default_bt_hook,
sizeof(default_bt_hook)), 0,
"Unexpected mallctl failure resetting hook to default");
(void *)&current_hook, &current_hook_sz,
(void *)&default_bt_hook, sizeof(default_bt_hook)),
0, "Unexpected mallctl failure resetting hook to default");
expect_ptr_eq(current_hook, hook,
"Hook returned by mallctl is not equal to mock hook");
@ -159,34 +159,36 @@ TEST_BEGIN(test_prof_backtrace_hook_augment) {
TEST_END
TEST_BEGIN(test_prof_dump_hook) {
test_skip_if(!config_prof);
expect_u_eq(opt_prof_bt_max, 200, "Unexpected backtrace stack depth");
mock_dump_hook_called = false;
expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&dump_filename,
sizeof(dump_filename)), 0, "Failed to dump heap profile");
sizeof(dump_filename)),
0, "Failed to dump heap profile");
expect_false(mock_dump_hook_called, "Called dump hook before it's set");
size_t default_bt_hook_sz = sizeof(prof_dump_hook_t);
size_t default_bt_hook_sz = sizeof(prof_dump_hook_t);
prof_dump_hook_t hook = &mock_dump_hook;
expect_d_eq(mallctl("experimental.hooks.prof_dump",
(void *)&default_bt_hook, &default_bt_hook_sz, (void *)&hook,
sizeof(hook)), 0, "Unexpected mallctl failure setting hook");
expect_d_eq(
mallctl("experimental.hooks.prof_dump", (void *)&default_bt_hook,
&default_bt_hook_sz, (void *)&hook, sizeof(hook)),
0, "Unexpected mallctl failure setting hook");
expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&dump_filename,
sizeof(dump_filename)), 0, "Failed to dump heap profile");
sizeof(dump_filename)),
0, "Failed to dump heap profile");
expect_true(mock_dump_hook_called, "Didn't call mock hook");
prof_dump_hook_t current_hook;
size_t current_hook_sz = sizeof(prof_dump_hook_t);
size_t current_hook_sz = sizeof(prof_dump_hook_t);
expect_d_eq(mallctl("experimental.hooks.prof_dump",
(void *)&current_hook, &current_hook_sz, (void *)&default_bt_hook,
sizeof(default_bt_hook)), 0,
"Unexpected mallctl failure resetting hook to default");
(void *)&current_hook, &current_hook_sz,
(void *)&default_bt_hook, sizeof(default_bt_hook)),
0, "Unexpected mallctl failure resetting hook to default");
expect_ptr_eq(current_hook, hook,
"Hook returned by mallctl is not equal to mock hook");
@ -195,12 +197,12 @@ TEST_END
/* Need the do_write flag because NULL is a valid to_write value. */
static void
read_write_prof_sample_hook(prof_sample_hook_t *to_read, bool do_write,
prof_sample_hook_t to_write) {
read_write_prof_sample_hook(
prof_sample_hook_t *to_read, bool do_write, prof_sample_hook_t to_write) {
size_t hook_sz = sizeof(prof_sample_hook_t);
expect_d_eq(mallctl("experimental.hooks.prof_sample",
(void *)to_read, &hook_sz, do_write ? &to_write : NULL, hook_sz), 0,
"Unexpected prof_sample_hook mallctl failure");
expect_d_eq(mallctl("experimental.hooks.prof_sample", (void *)to_read,
&hook_sz, do_write ? &to_write : NULL, hook_sz),
0, "Unexpected prof_sample_hook mallctl failure");
}
static void
@ -220,9 +222,10 @@ static void
read_write_prof_sample_free_hook(prof_sample_free_hook_t *to_read,
bool do_write, prof_sample_free_hook_t to_write) {
size_t hook_sz = sizeof(prof_sample_free_hook_t);
expect_d_eq(mallctl("experimental.hooks.prof_sample_free",
(void *)to_read, &hook_sz, do_write ? &to_write : NULL, hook_sz), 0,
"Unexpected prof_sample_free_hook mallctl failure");
expect_d_eq(
mallctl("experimental.hooks.prof_sample_free", (void *)to_read,
&hook_sz, do_write ? &to_write : NULL, hook_sz),
0, "Unexpected prof_sample_free_hook mallctl failure");
}
static void
@ -248,38 +251,40 @@ check_prof_sample_hooks(bool sample_hook_set, bool sample_free_hook_set) {
expect_zu_eq(sampled_ptr_sz, 0, "Unexpected sampled ptr size");
expect_zu_eq(sampled_ptr_usz, 0, "Unexpected sampled ptr usize");
expect_ptr_null(free_sampled_ptr, "Unexpected free sampled ptr");
expect_zu_eq(free_sampled_ptr_sz, 0,
"Unexpected free sampled ptr size");
expect_zu_eq(
free_sampled_ptr_sz, 0, "Unexpected free sampled ptr size");
prof_sample_hook_t curr_hook = read_prof_sample_hook();
expect_ptr_eq(curr_hook, sample_hook_set ? mock_prof_sample_hook : NULL,
"Unexpected non NULL default hook");
prof_sample_free_hook_t curr_free_hook = read_prof_sample_free_hook();
expect_ptr_eq(curr_free_hook, sample_free_hook_set ?
mock_prof_sample_free_hook : NULL,
expect_ptr_eq(curr_free_hook,
sample_free_hook_set ? mock_prof_sample_free_hook : NULL,
"Unexpected non NULL default hook");
size_t alloc_sz = 10;
size_t alloc_usz = 16;
void *p = mallocx(alloc_sz, 0);
void *p = mallocx(alloc_sz, 0);
expect_ptr_not_null(p, "Failed to allocate");
expect_true(mock_prof_sample_hook_called == sample_hook_set,
"Incorrect prof_sample hook usage");
"Incorrect prof_sample hook usage");
if (sample_hook_set) {
expect_ptr_eq(p, sampled_ptr, "Unexpected sampled ptr");
expect_zu_eq(alloc_sz, sampled_ptr_sz,
"Unexpected sampled usize");
expect_zu_eq(alloc_usz, sampled_ptr_usz, "Unexpected sampled usize");
expect_zu_eq(
alloc_sz, sampled_ptr_sz, "Unexpected sampled usize");
expect_zu_eq(
alloc_usz, sampled_ptr_usz, "Unexpected sampled usize");
}
dallocx(p, 0);
expect_true(mock_prof_sample_free_hook_called == sample_free_hook_set,
"Incorrect prof_sample_free hook usage");
"Incorrect prof_sample_free hook usage");
if (sample_free_hook_set) {
size_t usz = sz_s2u(alloc_sz);
expect_ptr_eq(p, free_sampled_ptr, "Unexpected sampled ptr");
expect_zu_eq(usz, free_sampled_ptr_sz, "Unexpected sampled usize");
expect_zu_eq(
usz, free_sampled_ptr_sz, "Unexpected sampled usize");
}
sampled_ptr = free_sampled_ptr = NULL;
@ -312,14 +317,14 @@ TEST_BEGIN(test_prof_sample_hooks) {
check_prof_sample_hooks(true, false);
prof_sample_free_hook_t sample_free_hook;
read_write_prof_sample_free_hook(&sample_free_hook, true,
mock_prof_sample_free_hook);
read_write_prof_sample_free_hook(
&sample_free_hook, true, mock_prof_sample_free_hook);
expect_ptr_null(sample_free_hook, "Unexpected non NULL default hook");
check_prof_sample_hooks(true, true);
read_write_prof_sample_hook(&sample_hook, true, NULL);
expect_ptr_eq(sample_hook, mock_prof_sample_hook,
"Unexpected prof_sample hook");
expect_ptr_eq(
sample_hook, mock_prof_sample_hook, "Unexpected prof_sample hook");
check_prof_sample_hooks(false, true);
read_write_prof_sample_free_hook(&sample_free_hook, true, NULL);
@ -331,9 +336,7 @@ TEST_END
int
main(void) {
return test(
test_prof_backtrace_hook_replace,
test_prof_backtrace_hook_augment,
test_prof_dump_hook,
return test(test_prof_backtrace_hook_replace,
test_prof_backtrace_hook_augment, test_prof_dump_hook,
test_prof_sample_hooks);
}

View file

@ -13,8 +13,9 @@ prof_dump_open_file_intercept(const char *filename, int mode) {
did_prof_dump_open = true;
const char filename_prefix[] = TEST_PREFIX ".";
expect_d_eq(strncmp(filename_prefix, filename, sizeof(filename_prefix)
- 1), 0, "Dump file name should start with \"" TEST_PREFIX ".\"");
expect_d_eq(
strncmp(filename_prefix, filename, sizeof(filename_prefix) - 1), 0,
"Dump file name should start with \"" TEST_PREFIX ".\"");
fd = open("/dev/null", O_WRONLY);
assert_d_ne(fd, -1, "Unexpected open() failure");
@ -23,7 +24,7 @@ prof_dump_open_file_intercept(const char *filename, int mode) {
}
TEST_BEGIN(test_idump) {
bool active;
bool active;
void *p;
const char *test_prefix = TEST_PREFIX;
@ -33,12 +34,12 @@ TEST_BEGIN(test_idump) {
active = true;
expect_d_eq(mallctl("prof.prefix", NULL, NULL, (void *)&test_prefix,
sizeof(test_prefix)), 0,
"Unexpected mallctl failure while overwriting dump prefix");
sizeof(test_prefix)),
0, "Unexpected mallctl failure while overwriting dump prefix");
expect_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
sizeof(active)), 0,
"Unexpected mallctl failure while activating profiling");
expect_d_eq(
mallctl("prof.active", NULL, NULL, (void *)&active, sizeof(active)),
0, "Unexpected mallctl failure while activating profiling");
prof_dump_open_file = prof_dump_open_file_intercept;
@ -52,6 +53,5 @@ TEST_END
int
main(void) {
return test(
test_idump);
return test(test_idump);
}

View file

@ -4,22 +4,25 @@
#define N_PARAM 100
#define N_THREADS 10
static void expect_rep(void) {
static void
expect_rep(void) {
expect_b_eq(prof_log_rep_check(), false, "Rep check failed");
}
static void expect_log_empty(void) {
expect_zu_eq(prof_log_bt_count(), 0,
"The log has backtraces; it isn't empty");
expect_zu_eq(prof_log_thr_count(), 0,
"The log has threads; it isn't empty");
static void
expect_log_empty(void) {
expect_zu_eq(
prof_log_bt_count(), 0, "The log has backtraces; it isn't empty");
expect_zu_eq(
prof_log_thr_count(), 0, "The log has threads; it isn't empty");
expect_zu_eq(prof_log_alloc_count(), 0,
"The log has allocations; it isn't empty");
}
void *buf[N_PARAM];
static void f(void) {
static void
f(void) {
int i;
for (i = 0; i < N_PARAM; i++) {
buf[i] = malloc(100);
@ -46,8 +49,8 @@ TEST_BEGIN(test_prof_log_many_logs) {
f();
expect_zu_eq(prof_log_thr_count(), 1, "Wrong thread count");
expect_rep();
expect_b_eq(prof_log_is_logging(), true,
"Logging should still be on");
expect_b_eq(
prof_log_is_logging(), true, "Logging should still be on");
expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl failure when stopping logging");
expect_b_eq(prof_log_is_logging(), false,
@ -58,7 +61,8 @@ TEST_END
thd_t thr_buf[N_THREADS];
static void *f_thread(void *unused) {
static void *
f_thread(void *unused) {
int i;
for (i = 0; i < N_PARAM; i++) {
void *p = malloc(100);
@ -70,7 +74,6 @@ static void *f_thread(void *unused) {
}
TEST_BEGIN(test_prof_log_many_threads) {
test_skip_if(!config_prof);
int i;
@ -83,32 +86,34 @@ TEST_BEGIN(test_prof_log_many_threads) {
for (i = 0; i < N_THREADS; i++) {
thd_join(thr_buf[i], NULL);
}
expect_zu_eq(prof_log_thr_count(), N_THREADS,
"Wrong number of thread entries");
expect_zu_eq(
prof_log_thr_count(), N_THREADS, "Wrong number of thread entries");
expect_rep();
expect_d_eq(mallctl("prof.log_stop", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl failure when stopping logging");
}
TEST_END
static void f3(void) {
static void
f3(void) {
void *p = malloc(100);
free(p);
}
static void f1(void) {
static void
f1(void) {
void *p = malloc(100);
f3();
free(p);
}
static void f2(void) {
static void
f2(void) {
void *p = malloc(100);
free(p);
}
TEST_BEGIN(test_prof_log_many_traces) {
test_skip_if(!config_prof);
expect_d_eq(mallctl("prof.log_start", NULL, NULL, NULL, 0), 0,
@ -144,8 +149,6 @@ main(void) {
if (config_prof) {
prof_log_dummy_set(true);
}
return test_no_reentrancy(
test_prof_log_many_logs,
test_prof_log_many_traces,
test_prof_log_many_threads);
return test_no_reentrancy(test_prof_log_many_logs,
test_prof_log_many_traces, test_prof_log_many_threads);
}

View file

@ -3,7 +3,7 @@
#include "jemalloc/internal/prof_sys.h"
static const char *test_filename = "test_filename";
static bool did_prof_dump_open;
static bool did_prof_dump_open;
static int
prof_dump_open_file_intercept(const char *filename, int mode) {
@ -35,8 +35,8 @@ TEST_BEGIN(test_mdump_normal) {
prof_dump_open_file = prof_dump_open_file_intercept;
did_prof_dump_open = false;
expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&test_filename,
sizeof(test_filename)), 0,
"Unexpected mallctl failure while dumping");
sizeof(test_filename)),
0, "Unexpected mallctl failure while dumping");
expect_true(did_prof_dump_open, "Expected a profile dump");
dallocx(p, 0);
@ -89,7 +89,8 @@ static void
expect_write_failure(int count) {
prof_dump_write_file_count = count;
expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&test_filename,
sizeof(test_filename)), EFAULT, "Dump should err");
sizeof(test_filename)),
EFAULT, "Dump should err");
expect_d_eq(prof_dump_write_file_count, 0,
"Dumping stopped after a wrong number of writes");
}
@ -98,7 +99,7 @@ TEST_BEGIN(test_mdump_output_error) {
test_skip_if(!config_prof);
test_skip_if(!config_debug);
prof_dump_open_file_t *open_file_orig = prof_dump_open_file;
prof_dump_open_file_t *open_file_orig = prof_dump_open_file;
prof_dump_write_file_t *write_file_orig = prof_dump_write_file;
prof_dump_write_file = prof_dump_write_file_error;
@ -168,9 +169,9 @@ TEST_BEGIN(test_mdump_maps_error) {
test_skip_if(!config_debug);
test_skip_if(prof_dump_open_maps == NULL);
prof_dump_open_file_t *open_file_orig = prof_dump_open_file;
prof_dump_open_file_t *open_file_orig = prof_dump_open_file;
prof_dump_write_file_t *write_file_orig = prof_dump_write_file;
prof_dump_open_maps_t *open_maps_orig = prof_dump_open_maps;
prof_dump_open_maps_t *open_maps_orig = prof_dump_open_maps;
prof_dump_open_file = prof_dump_open_file_intercept;
prof_dump_write_file = prof_dump_write_maps_file_error;
@ -186,8 +187,8 @@ TEST_BEGIN(test_mdump_maps_error) {
started_piping_maps_file = false;
prof_dump_write_file_count = 0;
expect_d_eq(mallctl("prof.dump", NULL, NULL, (void *)&test_filename,
sizeof(test_filename)), 0,
"mallctl should not fail in case of maps file opening failure");
sizeof(test_filename)),
0, "mallctl should not fail in case of maps file opening failure");
expect_false(started_piping_maps_file, "Shouldn't start piping maps");
expect_d_eq(prof_dump_write_file_count, 0,
"Dumping stopped after a wrong number of writes");
@ -211,7 +212,5 @@ TEST_END
int
main(void) {
return test(
test_mdump_normal,
test_mdump_output_error,
test_mdump_maps_error);
test_mdump_normal, test_mdump_output_error, test_mdump_maps_error);
}

View file

@ -32,18 +32,20 @@ TEST_BEGIN(test_prof_recent_off) {
test_skip_if(config_prof);
const ssize_t past_ref = 0, future_ref = 0;
const size_t len_ref = sizeof(ssize_t);
const size_t len_ref = sizeof(ssize_t);
ssize_t past = past_ref, future = future_ref;
size_t len = len_ref;
size_t len = len_ref;
#define ASSERT_SHOULD_FAIL(opt, a, b, c, d) do { \
assert_d_eq(mallctl("experimental.prof_recent." opt, a, b, c, \
d), ENOENT, "Should return ENOENT when config_prof is off");\
assert_zd_eq(past, past_ref, "output was touched"); \
assert_zu_eq(len, len_ref, "output length was touched"); \
assert_zd_eq(future, future_ref, "input was touched"); \
} while (0)
#define ASSERT_SHOULD_FAIL(opt, a, b, c, d) \
do { \
assert_d_eq( \
mallctl("experimental.prof_recent." opt, a, b, c, d), \
ENOENT, "Should return ENOENT when config_prof is off"); \
assert_zd_eq(past, past_ref, "output was touched"); \
assert_zu_eq(len, len_ref, "output length was touched"); \
assert_zd_eq(future, future_ref, "input was touched"); \
} while (0)
ASSERT_SHOULD_FAIL("alloc_max", NULL, NULL, NULL, 0);
ASSERT_SHOULD_FAIL("alloc_max", &past, &len, NULL, 0);
@ -58,40 +60,45 @@ TEST_BEGIN(test_prof_recent_on) {
test_skip_if(!config_prof);
ssize_t past, future;
size_t len = sizeof(ssize_t);
size_t len = sizeof(ssize_t);
confirm_prof_setup();
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, NULL, 0), 0, "no-op mallctl should be allowed");
assert_d_eq(
mallctl("experimental.prof_recent.alloc_max", NULL, NULL, NULL, 0),
0, "no-op mallctl should be allowed");
confirm_prof_setup();
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
&past, &len, NULL, 0), 0, "Read error");
assert_d_eq(
mallctl("experimental.prof_recent.alloc_max", &past, &len, NULL, 0),
0, "Read error");
expect_zd_eq(past, OPT_ALLOC_MAX, "Wrong read result");
future = OPT_ALLOC_MAX + 1;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, len), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, len),
0, "Write error");
future = -1;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
&past, &len, &future, len), 0, "Read/write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", &past, &len,
&future, len),
0, "Read/write error");
expect_zd_eq(past, OPT_ALLOC_MAX + 1, "Wrong read result");
future = -2;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
&past, &len, &future, len), EINVAL,
"Invalid write should return EINVAL");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", &past, &len,
&future, len),
EINVAL, "Invalid write should return EINVAL");
expect_zd_eq(past, OPT_ALLOC_MAX + 1,
"Output should not be touched given invalid write");
future = OPT_ALLOC_MAX;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
&past, &len, &future, len), 0, "Read/write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", &past, &len,
&future, len),
0, "Read/write error");
expect_zd_eq(past, -1, "Wrong read result");
future = OPT_ALLOC_MAX + 2;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
&past, &len, &future, len * 2), EINVAL,
"Invalid write should return EINVAL");
expect_zd_eq(past, -1,
"Output should not be touched given invalid write");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", &past, &len,
&future, len * 2),
EINVAL, "Invalid write should return EINVAL");
expect_zd_eq(
past, -1, "Output should not be touched given invalid write");
confirm_prof_setup();
}
@ -107,8 +114,8 @@ confirm_malloc(void *p) {
assert_ptr_not_null(e, "NULL edata for living pointer");
prof_recent_t *n = edata_prof_recent_alloc_get_no_lock_test(e);
assert_ptr_not_null(n, "Record in edata should not be NULL");
expect_ptr_not_null(n->alloc_tctx,
"alloc_tctx in record should not be NULL");
expect_ptr_not_null(
n->alloc_tctx, "alloc_tctx in record should not be NULL");
expect_ptr_eq(e, prof_recent_alloc_edata_get_no_lock_test(n),
"edata pointer in record is not correct");
expect_ptr_null(n->dalloc_tctx, "dalloc_tctx in record should be NULL");
@ -116,17 +123,17 @@ confirm_malloc(void *p) {
static void
confirm_record_size(prof_recent_t *n, unsigned kth) {
expect_zu_eq(n->size, NTH_REQ_SIZE(kth),
"Recorded allocation size is wrong");
expect_zu_eq(
n->size, NTH_REQ_SIZE(kth), "Recorded allocation size is wrong");
}
static void
confirm_record_living(prof_recent_t *n) {
expect_ptr_not_null(n->alloc_tctx,
"alloc_tctx in record should not be NULL");
expect_ptr_not_null(
n->alloc_tctx, "alloc_tctx in record should not be NULL");
edata_t *edata = prof_recent_alloc_edata_get_no_lock_test(n);
assert_ptr_not_null(edata,
"Recorded edata should not be NULL for living pointer");
assert_ptr_not_null(
edata, "Recorded edata should not be NULL for living pointer");
expect_ptr_eq(n, edata_prof_recent_alloc_get_no_lock_test(edata),
"Record in edata is not correct");
expect_ptr_null(n->dalloc_tctx, "dalloc_tctx in record should be NULL");
@ -134,8 +141,8 @@ confirm_record_living(prof_recent_t *n) {
static void
confirm_record_released(prof_recent_t *n) {
expect_ptr_not_null(n->alloc_tctx,
"alloc_tctx in record should not be NULL");
expect_ptr_not_null(
n->alloc_tctx, "alloc_tctx in record should not be NULL");
expect_ptr_null(prof_recent_alloc_edata_get_no_lock_test(n),
"Recorded edata should be NULL for released pointer");
expect_ptr_not_null(n->dalloc_tctx,
@ -145,12 +152,12 @@ confirm_record_released(prof_recent_t *n) {
TEST_BEGIN(test_prof_recent_alloc) {
test_skip_if(!config_prof);
bool b;
unsigned i, c;
size_t req_size;
void *p;
bool b;
unsigned i, c;
size_t req_size;
void *p;
prof_recent_t *n;
ssize_t future;
ssize_t future;
confirm_prof_setup();
@ -175,7 +182,7 @@ TEST_BEGIN(test_prof_recent_alloc) {
continue;
}
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
++c;
confirm_record_size(n, i + c - OPT_ALLOC_MAX);
if (c == OPT_ALLOC_MAX) {
@ -184,8 +191,8 @@ TEST_BEGIN(test_prof_recent_alloc) {
confirm_record_released(n);
}
}
assert_u_eq(c, OPT_ALLOC_MAX,
"Incorrect total number of allocations");
assert_u_eq(
c, OPT_ALLOC_MAX, "Incorrect total number of allocations");
free(p);
}
@ -204,13 +211,13 @@ TEST_BEGIN(test_prof_recent_alloc) {
p = malloc(req_size);
assert_ptr_not_null(p, "malloc failed unexpectedly");
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
confirm_record_size(n, c + OPT_ALLOC_MAX);
confirm_record_released(n);
++c;
}
assert_u_eq(c, OPT_ALLOC_MAX,
"Incorrect total number of allocations");
assert_u_eq(
c, OPT_ALLOC_MAX, "Incorrect total number of allocations");
free(p);
}
@ -231,91 +238,96 @@ TEST_BEGIN(test_prof_recent_alloc) {
p = malloc(req_size);
confirm_malloc(p);
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
++c;
confirm_record_size(n,
/* Is the allocation from the third batch? */
i + c - OPT_ALLOC_MAX >= 3 * OPT_ALLOC_MAX ?
/* If yes, then it's just recorded. */
i + c - OPT_ALLOC_MAX :
/*
i + c - OPT_ALLOC_MAX >= 3 * OPT_ALLOC_MAX
?
/* If yes, then it's just recorded. */
i + c - OPT_ALLOC_MAX
:
/*
* Otherwise, it should come from the first batch
* instead of the second batch.
*/
i + c - 2 * OPT_ALLOC_MAX);
i + c - 2 * OPT_ALLOC_MAX);
if (c == OPT_ALLOC_MAX) {
confirm_record_living(n);
} else {
confirm_record_released(n);
}
}
assert_u_eq(c, OPT_ALLOC_MAX,
"Incorrect total number of allocations");
assert_u_eq(
c, OPT_ALLOC_MAX, "Incorrect total number of allocations");
free(p);
}
/* Increasing the limit shouldn't alter the list of records. */
future = OPT_ALLOC_MAX + 1;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
confirm_record_size(n, c + 3 * OPT_ALLOC_MAX);
confirm_record_released(n);
++c;
}
assert_u_eq(c, OPT_ALLOC_MAX,
"Incorrect total number of allocations");
assert_u_eq(c, OPT_ALLOC_MAX, "Incorrect total number of allocations");
/*
* Decreasing the limit shouldn't alter the list of records as long as
* the new limit is still no less than the length of the list.
*/
future = OPT_ALLOC_MAX;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
confirm_record_size(n, c + 3 * OPT_ALLOC_MAX);
confirm_record_released(n);
++c;
}
assert_u_eq(c, OPT_ALLOC_MAX,
"Incorrect total number of allocations");
assert_u_eq(c, OPT_ALLOC_MAX, "Incorrect total number of allocations");
/*
* Decreasing the limit should shorten the list of records if the new
* limit is less than the length of the list.
*/
future = OPT_ALLOC_MAX - 1;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
++c;
confirm_record_size(n, c + 3 * OPT_ALLOC_MAX);
confirm_record_released(n);
}
assert_u_eq(c, OPT_ALLOC_MAX - 1,
"Incorrect total number of allocations");
assert_u_eq(
c, OPT_ALLOC_MAX - 1, "Incorrect total number of allocations");
/* Setting to unlimited shouldn't alter the list of records. */
future = -1;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
c = 0;
ql_foreach(n, &prof_recent_alloc_list, link) {
ql_foreach (n, &prof_recent_alloc_list, link) {
++c;
confirm_record_size(n, c + 3 * OPT_ALLOC_MAX);
confirm_record_released(n);
}
assert_u_eq(c, OPT_ALLOC_MAX - 1,
"Incorrect total number of allocations");
assert_u_eq(
c, OPT_ALLOC_MAX - 1, "Incorrect total number of allocations");
/* Downshift to only one record. */
future = 1;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
assert_false(ql_empty(&prof_recent_alloc_list), "Recent list is empty");
n = ql_first(&prof_recent_alloc_list);
confirm_record_size(n, 4 * OPT_ALLOC_MAX - 1);
@ -325,17 +337,19 @@ TEST_BEGIN(test_prof_recent_alloc) {
/* Completely turn off. */
future = 0;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_true(ql_empty(&prof_recent_alloc_list),
"Recent list should be empty");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
assert_true(
ql_empty(&prof_recent_alloc_list), "Recent list should be empty");
/* Restore the settings. */
future = OPT_ALLOC_MAX;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_true(ql_empty(&prof_recent_alloc_list),
"Recent list should be empty");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
assert_true(
ql_empty(&prof_recent_alloc_list), "Recent list should be empty");
confirm_prof_setup();
}
@ -344,7 +358,7 @@ TEST_END
#undef NTH_REQ_SIZE
#define DUMP_OUT_SIZE 4096
static char dump_out[DUMP_OUT_SIZE];
static char dump_out[DUMP_OUT_SIZE];
static size_t dump_out_len = 0;
static void
@ -359,14 +373,15 @@ static void
call_dump(void) {
static void *in[2] = {test_dump_write_cb, NULL};
dump_out_len = 0;
assert_d_eq(mallctl("experimental.prof_recent.alloc_dump",
NULL, NULL, in, sizeof(in)), 0, "Dump mallctl raised error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_dump", NULL, NULL,
in, sizeof(in)),
0, "Dump mallctl raised error");
}
typedef struct {
size_t size;
size_t usize;
bool released;
bool released;
} confirm_record_t;
#define DUMP_ERROR "Dump output is wrong"
@ -375,7 +390,7 @@ static void
confirm_record(const char *template, const confirm_record_t *records,
const size_t n_records) {
static const char *types[2] = {"alloc", "dalloc"};
static char buf[64];
static char buf[64];
/*
* The template string would be in the form of:
@ -384,32 +399,35 @@ confirm_record(const char *template, const confirm_record_t *records,
* "{...,\"recent_alloc\":[...]}".
* Using "- 2" serves to cut right before the ending "]}".
*/
assert_d_eq(memcmp(dump_out, template, strlen(template) - 2), 0,
DUMP_ERROR);
assert_d_eq(
memcmp(dump_out, template, strlen(template) - 2), 0, DUMP_ERROR);
assert_d_eq(memcmp(dump_out + strlen(dump_out) - 2,
template + strlen(template) - 2, 2), 0, DUMP_ERROR);
template + strlen(template) - 2, 2),
0, DUMP_ERROR);
const char *start = dump_out + strlen(template) - 2;
const char *end = dump_out + strlen(dump_out) - 2;
const char *start = dump_out + strlen(template) - 2;
const char *end = dump_out + strlen(dump_out) - 2;
const confirm_record_t *record;
for (record = records; record < records + n_records; ++record) {
#define ASSERT_CHAR(c) \
do { \
assert_true(start < end, DUMP_ERROR); \
assert_c_eq(*start++, c, DUMP_ERROR); \
} while (0)
#define ASSERT_CHAR(c) do { \
assert_true(start < end, DUMP_ERROR); \
assert_c_eq(*start++, c, DUMP_ERROR); \
} while (0)
#define ASSERT_STR(s) \
do { \
const size_t len = strlen(s); \
assert_true(start + len <= end, DUMP_ERROR); \
assert_d_eq(memcmp(start, s, len), 0, DUMP_ERROR); \
start += len; \
} while (0)
#define ASSERT_STR(s) do { \
const size_t len = strlen(s); \
assert_true(start + len <= end, DUMP_ERROR); \
assert_d_eq(memcmp(start, s, len), 0, DUMP_ERROR); \
start += len; \
} while (0)
#define ASSERT_FORMATTED_STR(s, ...) do { \
malloc_snprintf(buf, sizeof(buf), s, __VA_ARGS__); \
ASSERT_STR(buf); \
} while (0)
#define ASSERT_FORMATTED_STR(s, ...) \
do { \
malloc_snprintf(buf, sizeof(buf), s, __VA_ARGS__); \
ASSERT_STR(buf); \
} while (0)
if (record != records) {
ASSERT_CHAR(',');
@ -442,10 +460,10 @@ confirm_record(const char *template, const confirm_record_t *records,
ASSERT_CHAR(',');
if (thd_has_setname() && opt_prof_sys_thread_name) {
ASSERT_FORMATTED_STR("\"%s_thread_name\"",
*type);
ASSERT_FORMATTED_STR(":\"%s\",",
test_thread_name);
ASSERT_FORMATTED_STR(
"\"%s_thread_name\"", *type);
ASSERT_FORMATTED_STR(
":\"%s\",", test_thread_name);
}
ASSERT_FORMATTED_STR("\"%s_time\"", *type);
@ -458,9 +476,9 @@ confirm_record(const char *template, const confirm_record_t *records,
ASSERT_FORMATTED_STR("\"%s_trace\"", *type);
ASSERT_CHAR(':');
ASSERT_CHAR('[');
while (isdigit(*start) || *start == 'x' ||
(*start >= 'a' && *start <= 'f') ||
*start == '\"' || *start == ',') {
while (isdigit(*start) || *start == 'x'
|| (*start >= 'a' && *start <= 'f')
|| *start == '\"' || *start == ',') {
++start;
}
ASSERT_CHAR(']');
@ -483,7 +501,6 @@ confirm_record(const char *template, const confirm_record_t *records,
#undef ASSERT_FORMATTED_STR
#undef ASSERT_STR
#undef ASSERT_CHAR
}
assert_ptr_eq(record, records + n_records, DUMP_ERROR);
assert_ptr_eq(start, end, DUMP_ERROR);
@ -495,25 +512,30 @@ TEST_BEGIN(test_prof_recent_alloc_dump) {
thd_setname(test_thread_name);
confirm_prof_setup();
ssize_t future;
void *p, *q;
ssize_t future;
void *p, *q;
confirm_record_t records[2];
assert_zu_eq(lg_prof_sample, (size_t)0,
"lg_prof_sample not set correctly");
assert_zu_eq(
lg_prof_sample, (size_t)0, "lg_prof_sample not set correctly");
future = 0;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
call_dump();
expect_str_eq(dump_out, "{\"sample_interval\":1,"
"\"recent_alloc_max\":0,\"recent_alloc\":[]}", DUMP_ERROR);
expect_str_eq(dump_out,
"{\"sample_interval\":1,"
"\"recent_alloc_max\":0,\"recent_alloc\":[]}",
DUMP_ERROR);
future = 2;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
call_dump();
const char *template = "{\"sample_interval\":1,"
const char *template =
"{\"sample_interval\":1,"
"\"recent_alloc_max\":2,\"recent_alloc\":[]}";
expect_str_eq(dump_out, template, DUMP_ERROR);
@ -542,8 +564,9 @@ TEST_BEGIN(test_prof_recent_alloc_dump) {
confirm_record(template, records, 2);
future = OPT_ALLOC_MAX;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &future, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&future, sizeof(ssize_t)),
0, "Write error");
confirm_prof_setup();
}
TEST_END
@ -558,14 +581,14 @@ TEST_END
#define STRESS_ALLOC_MAX 4096
typedef struct {
thd_t thd;
thd_t thd;
size_t id;
void *ptrs[N_PTRS];
void *ptrs[N_PTRS];
size_t count;
} thd_data_t;
static thd_data_t thd_data[N_THREADS];
static ssize_t test_max;
static ssize_t test_max;
static void
test_write_cb(void *cbopaque, const char *str) {
@ -575,11 +598,11 @@ test_write_cb(void *cbopaque, const char *str) {
static void *
f_thread(void *arg) {
const size_t thd_id = *(size_t *)arg;
thd_data_t *data_p = thd_data + thd_id;
thd_data_t *data_p = thd_data + thd_id;
assert(data_p->id == thd_id);
data_p->count = 0;
uint64_t rand = (uint64_t)thd_id;
tsd_t *tsd = tsd_fetch();
tsd_t *tsd = tsd_fetch();
assert(test_max > 1);
ssize_t last_max = -1;
for (int i = 0; i < N_ITERS; i++) {
@ -603,15 +626,15 @@ f_thread(void *arg) {
} else if (rand % 5 == 1) {
last_max = prof_recent_alloc_max_ctl_read();
} else if (rand % 5 == 2) {
last_max =
prof_recent_alloc_max_ctl_write(tsd, test_max * 2);
last_max = prof_recent_alloc_max_ctl_write(
tsd, test_max * 2);
} else if (rand % 5 == 3) {
last_max =
prof_recent_alloc_max_ctl_write(tsd, test_max);
last_max = prof_recent_alloc_max_ctl_write(
tsd, test_max);
} else {
assert(rand % 5 == 4);
last_max =
prof_recent_alloc_max_ctl_write(tsd, test_max / 2);
last_max = prof_recent_alloc_max_ctl_write(
tsd, test_max / 2);
}
assert_zd_ge(last_max, -1, "Illegal last-N max");
}
@ -640,8 +663,9 @@ TEST_BEGIN(test_prof_recent_stress) {
}
test_max = STRESS_ALLOC_MAX;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &test_max, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&test_max, sizeof(ssize_t)),
0, "Write error");
for (size_t i = 0; i < N_THREADS; i++) {
thd_data_t *data_p = thd_data + i;
data_p->id = i;
@ -653,8 +677,9 @@ TEST_BEGIN(test_prof_recent_stress) {
}
test_max = OPT_ALLOC_MAX;
assert_d_eq(mallctl("experimental.prof_recent.alloc_max",
NULL, NULL, &test_max, sizeof(ssize_t)), 0, "Write error");
assert_d_eq(mallctl("experimental.prof_recent.alloc_max", NULL, NULL,
&test_max, sizeof(ssize_t)),
0, "Write error");
confirm_prof_setup();
}
TEST_END
@ -666,11 +691,7 @@ TEST_END
int
main(void) {
return test(
test_confirm_setup,
test_prof_recent_off,
test_prof_recent_on,
test_prof_recent_alloc,
test_prof_recent_alloc_dump,
test_prof_recent_stress);
return test(test_confirm_setup, test_prof_recent_off,
test_prof_recent_on, test_prof_recent_alloc,
test_prof_recent_alloc_dump, test_prof_recent_stress);
}

View file

@ -15,8 +15,9 @@ prof_dump_open_file_intercept(const char *filename, int mode) {
static void
set_prof_active(bool active) {
expect_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
sizeof(active)), 0, "Unexpected mallctl failure");
expect_d_eq(
mallctl("prof.active", NULL, NULL, (void *)&active, sizeof(active)),
0, "Unexpected mallctl failure");
}
static size_t
@ -32,25 +33,26 @@ get_lg_prof_sample(void) {
static void
do_prof_reset(size_t lg_prof_sample_input) {
expect_d_eq(mallctl("prof.reset", NULL, NULL,
(void *)&lg_prof_sample_input, sizeof(size_t)), 0,
"Unexpected mallctl failure while resetting profile data");
(void *)&lg_prof_sample_input, sizeof(size_t)),
0, "Unexpected mallctl failure while resetting profile data");
expect_zu_eq(lg_prof_sample_input, get_lg_prof_sample(),
"Expected profile sample rate change");
}
TEST_BEGIN(test_prof_reset_basic) {
size_t lg_prof_sample_orig, lg_prof_sample_cur, lg_prof_sample_next;
size_t sz;
size_t lg_prof_sample_orig, lg_prof_sample_cur, lg_prof_sample_next;
size_t sz;
unsigned i;
test_skip_if(!config_prof);
sz = sizeof(size_t);
expect_d_eq(mallctl("opt.lg_prof_sample", (void *)&lg_prof_sample_orig,
&sz, NULL, 0), 0,
&sz, NULL, 0),
0,
"Unexpected mallctl failure while reading profiling sample rate");
expect_zu_eq(lg_prof_sample_orig, 0,
"Unexpected profiling sample rate");
expect_zu_eq(
lg_prof_sample_orig, 0, "Unexpected profiling sample rate");
lg_prof_sample_cur = get_lg_prof_sample();
expect_zu_eq(lg_prof_sample_orig, lg_prof_sample_cur,
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
@ -110,23 +112,24 @@ TEST_BEGIN(test_prof_reset_cleanup) {
}
TEST_END
#define NTHREADS 4
#define NALLOCS_PER_THREAD (1U << 13)
#define OBJ_RING_BUF_COUNT 1531
#define RESET_INTERVAL (1U << 10)
#define DUMP_INTERVAL 3677
#define NTHREADS 4
#define NALLOCS_PER_THREAD (1U << 13)
#define OBJ_RING_BUF_COUNT 1531
#define RESET_INTERVAL (1U << 10)
#define DUMP_INTERVAL 3677
static void *
thd_start(void *varg) {
unsigned thd_ind = *(unsigned *)varg;
unsigned i;
void *objs[OBJ_RING_BUF_COUNT];
void *objs[OBJ_RING_BUF_COUNT];
memset(objs, 0, sizeof(objs));
for (i = 0; i < NALLOCS_PER_THREAD; i++) {
if (i % RESET_INTERVAL == 0) {
expect_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0),
0, "Unexpected error while resetting heap profile "
0,
"Unexpected error while resetting heap profile "
"data");
}
@ -141,9 +144,9 @@ thd_start(void *varg) {
dallocx(*pp, 0);
*pp = NULL;
}
*pp = btalloc(1, thd_ind*NALLOCS_PER_THREAD + i);
expect_ptr_not_null(*pp,
"Unexpected btalloc() failure");
*pp = btalloc(1, thd_ind * NALLOCS_PER_THREAD + i);
expect_ptr_not_null(
*pp, "Unexpected btalloc() failure");
}
}
@ -160,17 +163,16 @@ thd_start(void *varg) {
}
TEST_BEGIN(test_prof_reset) {
size_t lg_prof_sample_orig;
thd_t thds[NTHREADS];
size_t lg_prof_sample_orig;
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
size_t bt_count, tdata_count;
size_t bt_count, tdata_count;
test_skip_if(!config_prof);
bt_count = prof_bt_count();
expect_zu_eq(bt_count, 0,
"Unexpected pre-existing tdata structures");
expect_zu_eq(bt_count, 0, "Unexpected pre-existing tdata structures");
tdata_count = prof_tdata_count();
lg_prof_sample_orig = get_lg_prof_sample();
@ -186,8 +188,8 @@ TEST_BEGIN(test_prof_reset) {
thd_join(thds[i], NULL);
}
expect_zu_eq(prof_bt_count(), bt_count,
"Unexpected bactrace count change");
expect_zu_eq(
prof_bt_count(), bt_count, "Unexpected bactrace count change");
expect_zu_eq(prof_tdata_count(), tdata_count,
"Unexpected remaining tdata structures");
@ -205,9 +207,9 @@ TEST_END
/* Test sampling at the same allocation site across resets. */
#define NITER 10
TEST_BEGIN(test_xallocx) {
size_t lg_prof_sample_orig;
size_t lg_prof_sample_orig;
unsigned i;
void *ptrs[NITER];
void *ptrs[NITER];
test_skip_if(!config_prof);
@ -218,7 +220,7 @@ TEST_BEGIN(test_xallocx) {
do_prof_reset(0);
for (i = 0; i < NITER; i++) {
void *p;
void *p;
size_t sz, nsz;
/* Reset profiling. */
@ -233,13 +235,13 @@ TEST_BEGIN(test_xallocx) {
/* Perform successful xallocx(). */
sz = sallocx(p, 0);
expect_zu_eq(xallocx(p, sz, 0, 0), sz,
"Unexpected xallocx() failure");
expect_zu_eq(
xallocx(p, sz, 0, 0), sz, "Unexpected xallocx() failure");
/* Perform unsuccessful xallocx(). */
nsz = nallocx(sz+1, 0);
expect_zu_eq(xallocx(p, nsz, 0, 0), sz,
"Unexpected xallocx() success");
nsz = nallocx(sz + 1, 0);
expect_zu_eq(
xallocx(p, nsz, 0, 0), sz, "Unexpected xallocx() success");
}
for (i = 0; i < NITER; i++) {
@ -258,9 +260,6 @@ main(void) {
/* Intercept dumping prior to running any tests. */
prof_dump_open_file = prof_dump_open_file_intercept;
return test_no_reentrancy(
test_prof_reset_basic,
test_prof_reset_cleanup,
test_prof_reset,
test_xallocx);
return test_no_reentrancy(test_prof_reset_basic,
test_prof_reset_cleanup, test_prof_reset, test_xallocx);
}

View file

@ -1,6 +1,7 @@
#include "test/jemalloc_test.h"
static void assert_small_allocation_sampled(void *ptr, size_t size) {
static void
assert_small_allocation_sampled(void *ptr, size_t size) {
assert_ptr_not_null(ptr, "Unexpected malloc failure");
assert_zu_le(size, SC_SMALL_MAXCLASS, "Unexpected large size class");
edata_t *edata = emap_edata_lookup(TSDN_NULL, &arena_emap_global, ptr);
@ -24,7 +25,7 @@ TEST_BEGIN(test_profile_small_allocations) {
for (szind_t index = 0; index < SC_NBINS; index++) {
size_t size = sz_index2size(index);
void *ptr = malloc(size);
void *ptr = malloc(size);
assert_small_allocation_sampled(ptr, size);
free(ptr);
}
@ -36,7 +37,7 @@ TEST_BEGIN(test_profile_small_allocations_sdallocx) {
for (szind_t index = 0; index < SC_NBINS; index++) {
size_t size = sz_index2size(index);
void *ptr = malloc(size);
void *ptr = malloc(size);
assert_small_allocation_sampled(ptr, size);
/*
* While free calls into ifree, sdallocx calls into isfree,
@ -86,7 +87,7 @@ TEST_BEGIN(test_profile_small_reallocations_same_size_class) {
for (szind_t index = 0; index < SC_NBINS; index++) {
size_t size = sz_index2size(index);
void *ptr = malloc(size);
void *ptr = malloc(size);
assert_small_allocation_sampled(ptr, size);
ptr = realloc(ptr, size - 1);
assert_small_allocation_sampled(ptr, size);

View file

@ -3,8 +3,8 @@
#define N_PTRS 3
static void
test_combinations(szind_t ind, size_t sizes_array[N_PTRS],
int flags_array[N_PTRS]) {
test_combinations(
szind_t ind, size_t sizes_array[N_PTRS], int flags_array[N_PTRS]) {
#define MALLCTL_STR_LEN 64
assert(opt_prof && opt_prof_stats);
@ -25,11 +25,13 @@ test_combinations(szind_t ind, size_t sizes_array[N_PTRS],
size_t stats_len = 2 * sizeof(uint64_t);
uint64_t live_stats_orig[2];
assert_d_eq(mallctl(mallctl_live_str, &live_stats_orig, &stats_len,
NULL, 0), 0, "");
assert_d_eq(
mallctl(mallctl_live_str, &live_stats_orig, &stats_len, NULL, 0), 0,
"");
uint64_t accum_stats_orig[2];
assert_d_eq(mallctl(mallctl_accum_str, &accum_stats_orig, &stats_len,
NULL, 0), 0, "");
assert_d_eq(
mallctl(mallctl_accum_str, &accum_stats_orig, &stats_len, NULL, 0),
0, "");
void *ptrs[N_PTRS];
@ -40,8 +42,8 @@ test_combinations(szind_t ind, size_t sizes_array[N_PTRS],
for (size_t i = 0; i < N_PTRS; ++i) {
size_t sz = sizes_array[i];
int flags = flags_array[i];
void *p = mallocx(sz, flags);
int flags = flags_array[i];
void *p = mallocx(sz, flags);
assert_ptr_not_null(p, "malloc() failed");
assert(TEST_MALLOC_SIZE(p) == sz_index2size(ind));
ptrs[i] = p;
@ -50,41 +52,45 @@ test_combinations(szind_t ind, size_t sizes_array[N_PTRS],
accum_req_sum += sz;
accum_count++;
uint64_t live_stats[2];
assert_d_eq(mallctl(mallctl_live_str, &live_stats, &stats_len,
NULL, 0), 0, "");
expect_u64_eq(live_stats[0] - live_stats_orig[0],
live_req_sum, "");
expect_u64_eq(live_stats[1] - live_stats_orig[1],
live_count, "");
assert_d_eq(
mallctl(mallctl_live_str, &live_stats, &stats_len, NULL, 0),
0, "");
expect_u64_eq(
live_stats[0] - live_stats_orig[0], live_req_sum, "");
expect_u64_eq(
live_stats[1] - live_stats_orig[1], live_count, "");
uint64_t accum_stats[2];
assert_d_eq(mallctl(mallctl_accum_str, &accum_stats, &stats_len,
NULL, 0), 0, "");
expect_u64_eq(accum_stats[0] - accum_stats_orig[0],
accum_req_sum, "");
expect_u64_eq(accum_stats[1] - accum_stats_orig[1],
accum_count, "");
NULL, 0),
0, "");
expect_u64_eq(
accum_stats[0] - accum_stats_orig[0], accum_req_sum, "");
expect_u64_eq(
accum_stats[1] - accum_stats_orig[1], accum_count, "");
}
for (size_t i = 0; i < N_PTRS; ++i) {
size_t sz = sizes_array[i];
int flags = flags_array[i];
int flags = flags_array[i];
sdallocx(ptrs[i], sz, flags);
live_req_sum -= sz;
live_count--;
uint64_t live_stats[2];
assert_d_eq(mallctl(mallctl_live_str, &live_stats, &stats_len,
NULL, 0), 0, "");
expect_u64_eq(live_stats[0] - live_stats_orig[0],
live_req_sum, "");
expect_u64_eq(live_stats[1] - live_stats_orig[1],
live_count, "");
assert_d_eq(
mallctl(mallctl_live_str, &live_stats, &stats_len, NULL, 0),
0, "");
expect_u64_eq(
live_stats[0] - live_stats_orig[0], live_req_sum, "");
expect_u64_eq(
live_stats[1] - live_stats_orig[1], live_count, "");
uint64_t accum_stats[2];
assert_d_eq(mallctl(mallctl_accum_str, &accum_stats, &stats_len,
NULL, 0), 0, "");
expect_u64_eq(accum_stats[0] - accum_stats_orig[0],
accum_req_sum, "");
expect_u64_eq(accum_stats[1] - accum_stats_orig[1],
accum_count, "");
NULL, 0),
0, "");
expect_u64_eq(
accum_stats[0] - accum_stats_orig[0], accum_req_sum, "");
expect_u64_eq(
accum_stats[1] - accum_stats_orig[1], accum_count, "");
}
#undef MALLCTL_STR_LEN
}
@ -92,9 +98,9 @@ test_combinations(szind_t ind, size_t sizes_array[N_PTRS],
static void
test_szind_wrapper(szind_t ind) {
size_t sizes_array[N_PTRS];
int flags_array[N_PTRS];
int flags_array[N_PTRS];
for (size_t i = 0, sz = sz_index2size(ind) - N_PTRS; i < N_PTRS;
++i, ++sz) {
++i, ++sz) {
sizes_array[i] = sz;
flags_array[i] = 0;
}
@ -115,10 +121,10 @@ TEST_END
static void
test_szind_aligned_wrapper(szind_t ind, unsigned lg_align) {
size_t sizes_array[N_PTRS];
int flags_array[N_PTRS];
int flags = MALLOCX_LG_ALIGN(lg_align);
int flags_array[N_PTRS];
int flags = MALLOCX_LG_ALIGN(lg_align);
for (size_t i = 0, sz = sz_index2size(ind) - N_PTRS; i < N_PTRS;
++i, ++sz) {
++i, ++sz) {
sizes_array[i] = sz;
flags_array[i] = flags;
}
@ -136,7 +142,7 @@ TEST_BEGIN(test_prof_stats_aligned) {
}
for (szind_t ind = SC_NBINS - 5; ind < SC_NBINS + 5; ++ind) {
for (unsigned lg_align = SC_LG_LARGE_MINCLASS - 5;
lg_align < SC_LG_LARGE_MINCLASS + 5; ++lg_align) {
lg_align < SC_LG_LARGE_MINCLASS + 5; ++lg_align) {
test_szind_aligned_wrapper(ind, lg_align);
}
}
@ -145,7 +151,5 @@ TEST_END
int
main(void) {
return test(
test_prof_stats,
test_prof_stats_aligned);
return test(test_prof_stats, test_prof_stats_aligned);
}

View file

@ -28,7 +28,7 @@ TEST_BEGIN(test_prof_sys_thread_name) {
test_skip_if(!config_prof);
test_skip_if(!opt_prof_sys_thread_name);
bool oldval;
bool oldval;
size_t sz = sizeof(oldval);
assert_d_eq(mallctl("opt.prof_sys_thread_name", &oldval, &sz, NULL, 0),
0, "mallctl failed");
@ -43,8 +43,8 @@ TEST_BEGIN(test_prof_sys_thread_name) {
thread_name = test_thread_name;
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name, sz),
ENOENT, "mallctl write for thread name should fail");
assert_ptr_eq(thread_name, test_thread_name,
"Thread name should not be touched");
assert_ptr_eq(
thread_name, test_thread_name, "Thread name should not be touched");
prof_sys_thread_name_read_t *orig_prof_sys_thread_name_read =
prof_sys_thread_name_read;
@ -69,14 +69,15 @@ TEST_BEGIN(test_prof_sys_thread_name) {
free(p);
assert_d_eq(mallctl("thread.prof.name", &thread_name, &sz, NULL, 0), 0,
"mallctl read for thread name should not fail");
expect_str_eq(thread_name, "", "Thread name should be updated if the "
expect_str_eq(thread_name, "",
"Thread name should be updated if the "
"system call returns a different name");
prof_sys_thread_name_read = orig_prof_sys_thread_name_read;
}
TEST_END
#define ITER (16*1024)
#define ITER (16 * 1024)
static void *
thd_start(void *unused) {
/* Triggering samples which loads thread names. */
@ -94,7 +95,7 @@ TEST_BEGIN(test_prof_sys_thread_name_mt) {
test_skip_if(!opt_prof_sys_thread_name);
#define NTHREADS 4
thd_t thds[NTHREADS];
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
@ -105,8 +106,8 @@ TEST_BEGIN(test_prof_sys_thread_name_mt) {
/* Prof dump which reads the thread names. */
for (i = 0; i < ITER; i++) {
expect_d_eq(mallctl("prof.dump", NULL, NULL,
(void *)&dump_filename, sizeof(dump_filename)), 0,
"Unexpected mallctl failure while dumping");
(void *)&dump_filename, sizeof(dump_filename)),
0, "Unexpected mallctl failure while dumping");
}
for (i = 0; i < NTHREADS; i++) {
@ -119,7 +120,5 @@ TEST_END
int
main(void) {
return test(
test_prof_sys_thread_name,
test_prof_sys_thread_name_mt);
return test(test_prof_sys_thread_name, test_prof_sys_thread_name_mt);
}

View file

@ -3,11 +3,11 @@
#include "jemalloc/internal/prof_data.h"
TEST_BEGIN(test_prof_realloc) {
tsd_t *tsd;
int flags;
void *p, *q;
tsd_t *tsd;
int flags;
void *p, *q;
prof_info_t prof_info_p, prof_info_q;
prof_cnt_t cnt_0, cnt_1, cnt_2, cnt_3;
prof_cnt_t cnt_0, cnt_1, cnt_2, cnt_3;
test_skip_if(!config_prof);
@ -18,8 +18,8 @@ TEST_BEGIN(test_prof_realloc) {
p = mallocx(1024, flags);
expect_ptr_not_null(p, "Unexpected mallocx() failure");
prof_info_get(tsd, p, NULL, &prof_info_p);
expect_ptr_ne(prof_info_p.alloc_tctx, PROF_TCTX_SENTINEL,
"Expected valid tctx");
expect_ptr_ne(
prof_info_p.alloc_tctx, PROF_TCTX_SENTINEL, "Expected valid tctx");
prof_cnt_all(&cnt_1);
expect_u64_eq(cnt_0.curobjs + 1, cnt_1.curobjs,
"Allocation should have increased sample size");
@ -28,8 +28,8 @@ TEST_BEGIN(test_prof_realloc) {
expect_ptr_ne(p, q, "Expected move");
expect_ptr_not_null(p, "Unexpected rmallocx() failure");
prof_info_get(tsd, q, NULL, &prof_info_q);
expect_ptr_ne(prof_info_q.alloc_tctx, PROF_TCTX_SENTINEL,
"Expected valid tctx");
expect_ptr_ne(
prof_info_q.alloc_tctx, PROF_TCTX_SENTINEL, "Expected valid tctx");
prof_cnt_all(&cnt_2);
expect_u64_eq(cnt_1.curobjs, cnt_2.curobjs,
"Reallocation should not have changed sample size");
@ -43,6 +43,5 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_prof_realloc);
return test_no_reentrancy(test_prof_realloc);
}

View file

@ -1,34 +1,34 @@
#include "test/jemalloc_test.h"
static void
mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,
int line) {
mallctl_thread_name_get_impl(
const char *thread_name_expected, const char *func, int line) {
const char *thread_name_old;
size_t sz;
size_t sz;
sz = sizeof(thread_name_old);
expect_d_eq(mallctl("thread.prof.name", (void *)&thread_name_old, &sz,
NULL, 0), 0,
"%s():%d: Unexpected mallctl failure reading thread.prof.name",
expect_d_eq(
mallctl("thread.prof.name", (void *)&thread_name_old, &sz, NULL, 0),
0, "%s():%d: Unexpected mallctl failure reading thread.prof.name",
func, line);
expect_str_eq(thread_name_old, thread_name_expected,
"%s():%d: Unexpected thread.prof.name value", func, line);
}
static void
mallctl_thread_name_set_impl(const char *thread_name, const char *func,
int line) {
mallctl_thread_name_set_impl(
const char *thread_name, const char *func, int line) {
expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
(void *)&thread_name, sizeof(thread_name)), 0,
"%s():%d: Unexpected mallctl failure writing thread.prof.name",
(void *)&thread_name, sizeof(thread_name)),
0, "%s():%d: Unexpected mallctl failure writing thread.prof.name",
func, line);
mallctl_thread_name_get_impl(thread_name, func, line);
}
#define mallctl_thread_name_get(a) \
#define mallctl_thread_name_get(a) \
mallctl_thread_name_get_impl(a, __func__, __LINE__)
#define mallctl_thread_name_set(a) \
#define mallctl_thread_name_set(a) \
mallctl_thread_name_set_impl(a, __func__, __LINE__)
TEST_BEGIN(test_prof_thread_name_validation) {
@ -44,34 +44,35 @@ TEST_BEGIN(test_prof_thread_name_validation) {
char long_name[] =
"test case longer than expected; test case longer than expected";
expect_zu_gt(strlen(long_name), PROF_THREAD_NAME_MAX_LEN,
"Long test name not long enough");
"Long test name not long enough");
const char *test_name_long = long_name;
expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
(void *)&test_name_long, sizeof(test_name_long)), 0,
"Unexpected mallctl failure from thread.prof.name");
(void *)&test_name_long, sizeof(test_name_long)),
0, "Unexpected mallctl failure from thread.prof.name");
/* Long name cut to match. */
long_name[PROF_THREAD_NAME_MAX_LEN - 1] = '\0';
mallctl_thread_name_get(test_name_long);
/* NULL input shouldn't be allowed. */
const char *test_name2 = NULL;
expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
(void *)&test_name2, sizeof(test_name2)), EINVAL,
"Unexpected mallctl result writing to thread.prof.name");
expect_d_eq(mallctl("thread.prof.name", NULL, NULL, (void *)&test_name2,
sizeof(test_name2)),
EINVAL, "Unexpected mallctl result writing to thread.prof.name");
/* '\n' shouldn't be allowed. */
const char *test_name3 = "test\ncase";
expect_d_eq(mallctl("thread.prof.name", NULL, NULL,
(void *)&test_name3, sizeof(test_name3)), EINVAL,
expect_d_eq(mallctl("thread.prof.name", NULL, NULL, (void *)&test_name3,
sizeof(test_name3)),
EINVAL,
"Unexpected mallctl result writing \"%s\" to thread.prof.name",
test_name3);
/* Simultaneous read/write shouldn't be allowed. */
const char *thread_name_old;
size_t sz = sizeof(thread_name_old);
size_t sz = sizeof(thread_name_old);
expect_d_eq(mallctl("thread.prof.name", (void *)&thread_name_old, &sz,
(void *)&test_name1, sizeof(test_name1)), EPERM,
"Unexpected mallctl result from thread.prof.name");
(void *)&test_name1, sizeof(test_name1)),
EPERM, "Unexpected mallctl result from thread.prof.name");
mallctl_thread_name_set("");
}
@ -80,7 +81,7 @@ TEST_END
static void *
thd_start(void *varg) {
unsigned thd_ind = *(unsigned *)varg;
char thread_name[16] = "";
char thread_name[16] = "";
unsigned i;
malloc_snprintf(thread_name, sizeof(thread_name), "thread %u", thd_ind);
@ -107,7 +108,7 @@ TEST_BEGIN(test_prof_thread_name_threaded) {
test_skip_if(opt_prof_sys_thread_name);
#define NTHREADS 4
thd_t thds[NTHREADS];
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
@ -125,6 +126,5 @@ TEST_END
int
main(void) {
return test(
test_prof_thread_name_validation,
test_prof_thread_name_threaded);
test_prof_thread_name_validation, test_prof_thread_name_threaded);
}

View file

@ -23,9 +23,10 @@ static void
read_write_prof_threshold_hook(prof_threshold_hook_t *to_read, bool do_write,
prof_threshold_hook_t to_write) {
size_t hook_sz = sizeof(prof_threshold_hook_t);
expect_d_eq(mallctl("experimental.hooks.prof_threshold",
(void *)to_read, &hook_sz, do_write ? &to_write : NULL, hook_sz), 0,
"Unexpected prof_threshold_hook mallctl failure");
expect_d_eq(
mallctl("experimental.hooks.prof_threshold", (void *)to_read,
&hook_sz, do_write ? &to_write : NULL, hook_sz),
0, "Unexpected prof_threshold_hook mallctl failure");
}
static void
@ -40,7 +41,8 @@ read_prof_threshold_hook() {
return hook;
}
static void reset_test_config() {
static void
reset_test_config() {
hook_calls = 0;
last_peak = 0;
alloc_baseline = last_alloc; /* We run the test multiple times */
@ -49,15 +51,20 @@ static void reset_test_config() {
chunk_size = threshold_bytes / ALLOC_ITERATIONS_IN_THRESHOLD;
}
static void expect_threshold_calls(int calls) {
expect_u64_eq(hook_calls, calls, "Hook called the right amount of times");
expect_u64_lt(last_peak, chunk_size * 2, "We allocate chunk_size at a time");
expect_u64_ge(last_alloc, threshold_bytes * calls + alloc_baseline, "Crosses");
static void
expect_threshold_calls(int calls) {
expect_u64_eq(
hook_calls, calls, "Hook called the right amount of times");
expect_u64_lt(
last_peak, chunk_size * 2, "We allocate chunk_size at a time");
expect_u64_ge(
last_alloc, threshold_bytes * calls + alloc_baseline, "Crosses");
}
static void allocate_chunks(int chunks) {
static void
allocate_chunks(int chunks) {
for (int i = 0; i < chunks; i++) {
void* p = mallocx((size_t)chunk_size, 0);
void *p = mallocx((size_t)chunk_size, 0);
expect_ptr_not_null(p, "Failed to allocate");
free(p);
}
@ -68,7 +75,8 @@ TEST_BEGIN(test_prof_threshold_hook) {
/* Test setting and reading the hook (both value and null) */
write_prof_threshold_hook(mock_prof_threshold_hook);
expect_ptr_eq(read_prof_threshold_hook(), mock_prof_threshold_hook, "Unexpected hook");
expect_ptr_eq(read_prof_threshold_hook(), mock_prof_threshold_hook,
"Unexpected hook");
write_prof_threshold_hook(NULL);
expect_ptr_null(read_prof_threshold_hook(), "Hook was erased");
@ -100,6 +108,5 @@ TEST_END
int
main(void) {
return test(
test_prof_threshold_hook);
return test(test_prof_threshold_hook);
}

View file

@ -21,8 +21,8 @@ test_psset_fake_purge(hpdata_t *ps) {
hpdata_alloc_allowed_set(ps, false);
size_t nranges;
hpdata_purge_begin(ps, &purge_state, &nranges);
(void) nranges;
void *addr;
(void)nranges;
void *addr;
size_t size;
while (hpdata_purge_next(ps, &purge_state, &addr, &size)) {
}
@ -31,8 +31,8 @@ test_psset_fake_purge(hpdata_t *ps) {
}
static void
test_psset_alloc_new(psset_t *psset, hpdata_t *ps, edata_t *r_edata,
size_t size) {
test_psset_alloc_new(
psset_t *psset, hpdata_t *ps, edata_t *r_edata, size_t size) {
hpdata_assert_empty(ps);
test_psset_fake_purge(ps);
@ -40,12 +40,12 @@ test_psset_alloc_new(psset_t *psset, hpdata_t *ps, edata_t *r_edata,
psset_insert(psset, ps);
psset_update_begin(psset, ps);
void *addr = hpdata_reserve_alloc(ps, size);
edata_init(r_edata, edata_arena_ind_get(r_edata), addr, size,
void *addr = hpdata_reserve_alloc(ps, size);
edata_init(r_edata, edata_arena_ind_get(r_edata), addr, size,
/* slab */ false, SC_NSIZES, /* sn */ 0, extent_state_active,
/* zeroed */ false, /* committed */ true, EXTENT_PAI_HPA,
EXTENT_NOT_HEAD);
edata_ps_set(r_edata, ps);
/* zeroed */ false, /* committed */ true, EXTENT_PAI_HPA,
EXTENT_NOT_HEAD);
edata_ps_set(r_edata, ps);
psset_update_end(psset, ps);
}
@ -104,15 +104,14 @@ edata_expect(edata_t *edata, size_t page_offset, size_t page_cnt) {
* Note that allocations should get the arena ind of their home
* arena, *not* the arena ind of the pageslab allocator.
*/
expect_u_eq(ALLOC_ARENA_IND, edata_arena_ind_get(edata),
"Arena ind changed");
expect_u_eq(
ALLOC_ARENA_IND, edata_arena_ind_get(edata), "Arena ind changed");
expect_ptr_eq(
(void *)((uintptr_t)PAGESLAB_ADDR + (page_offset << LG_PAGE)),
edata_addr_get(edata), "Didn't allocate in order");
expect_zu_eq(page_cnt << LG_PAGE, edata_size_get(edata), "");
expect_false(edata_slab_get(edata), "");
expect_u_eq(SC_NSIZES, edata_szind_get_maybe_invalid(edata),
"");
expect_u_eq(SC_NSIZES, edata_szind_get_maybe_invalid(edata), "");
expect_u64_eq(0, edata_sn_get(edata), "");
expect_d_eq(edata_state_get(edata), extent_state_active, "");
expect_false(edata_zeroed_get(edata), "");
@ -123,7 +122,7 @@ edata_expect(edata_t *edata, size_t page_offset, size_t page_cnt) {
TEST_BEGIN(test_empty) {
test_skip_if(hpa_hugepage_size_exceeds_limit());
bool err;
bool err;
hpdata_t pageslab;
hpdata_init(&pageslab, PAGESLAB_ADDR, PAGESLAB_AGE);
@ -176,7 +175,7 @@ TEST_END
TEST_BEGIN(test_reuse) {
test_skip_if(hpa_hugepage_size_exceeds_limit());
bool err;
bool err;
hpdata_t *ps;
hpdata_t pageslab;
@ -196,7 +195,7 @@ TEST_BEGIN(test_reuse) {
}
/* Free odd indices. */
for (size_t i = 0; i < HUGEPAGE_PAGES; i ++) {
for (size_t i = 0; i < HUGEPAGE_PAGES; i++) {
if (i % 2 == 0) {
continue;
}
@ -271,7 +270,7 @@ TEST_END
TEST_BEGIN(test_evict) {
test_skip_if(hpa_hugepage_size_exceeds_limit());
bool err;
bool err;
hpdata_t *ps;
hpdata_t pageslab;
@ -308,16 +307,15 @@ TEST_END
TEST_BEGIN(test_multi_pageslab) {
test_skip_if(hpa_hugepage_size_exceeds_limit());
bool err;
bool err;
hpdata_t *ps;
hpdata_t pageslab[2];
hpdata_init(&pageslab[0], PAGESLAB_ADDR, PAGESLAB_AGE);
hpdata_init(&pageslab[1],
(void *)((uintptr_t)PAGESLAB_ADDR + HUGEPAGE),
hpdata_init(&pageslab[1], (void *)((uintptr_t)PAGESLAB_ADDR + HUGEPAGE),
PAGESLAB_AGE + 1);
edata_t* alloc[2];
edata_t *alloc[2];
alloc[0] = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
alloc[1] = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
@ -334,9 +332,10 @@ TEST_BEGIN(test_multi_pageslab) {
for (size_t i = 0; i < 2; i++) {
for (size_t j = 1; j < HUGEPAGE_PAGES; j++) {
edata_init_test(&alloc[i][j]);
err = test_psset_alloc_reuse(&psset, &alloc[i][j], PAGE);
expect_false(err,
"Nonempty psset failed page allocation.");
err = test_psset_alloc_reuse(
&psset, &alloc[i][j], PAGE);
expect_false(
err, "Nonempty psset failed page allocation.");
assert_ptr_eq(&pageslab[i], edata_ps_get(&alloc[i][j]),
"Didn't pick pageslabs in first-fit");
}
@ -505,7 +504,8 @@ TEST_BEGIN(test_stats_huge) {
expect_zu_eq(1, psset.stats.slabs[0].npageslabs, "");
expect_zu_eq(i, psset.stats.slabs[0].nactive, "");
expect_zu_eq(HUGEPAGE_PAGES - i, psset.stats.slabs[0].ndirty, "");
expect_zu_eq(
HUGEPAGE_PAGES - i, psset.stats.slabs[0].ndirty, "");
expect_zu_eq(0, psset.stats.slabs[1].npageslabs, "");
expect_zu_eq(0, psset.stats.slabs[1].nactive, "");
@ -527,7 +527,8 @@ static void
stats_expect_empty(psset_bin_stats_t *stats) {
assert_zu_eq(0, stats->npageslabs,
"Supposedly empty bin had positive npageslabs");
expect_zu_eq(0, stats->nactive, "Unexpected nonempty bin"
expect_zu_eq(0, stats->nactive,
"Unexpected nonempty bin"
"Supposedly empty bin had positive nactive");
}
@ -536,17 +537,16 @@ stats_expect(psset_t *psset, size_t nactive) {
if (nactive == HUGEPAGE_PAGES) {
expect_zu_eq(1, psset->stats.full_slabs[0].npageslabs,
"Expected a full slab");
expect_zu_eq(HUGEPAGE_PAGES,
psset->stats.full_slabs[0].nactive,
expect_zu_eq(HUGEPAGE_PAGES, psset->stats.full_slabs[0].nactive,
"Should have exactly filled the bin");
} else {
stats_expect_empty(&psset->stats.full_slabs[0]);
}
size_t ninactive = HUGEPAGE_PAGES - nactive;
size_t ninactive = HUGEPAGE_PAGES - nactive;
pszind_t nonempty_pind = PSSET_NPSIZES;
if (ninactive != 0 && ninactive < HUGEPAGE_PAGES) {
nonempty_pind = sz_psz2ind(sz_psz_quantize_floor(
ninactive << LG_PAGE));
nonempty_pind = sz_psz2ind(
sz_psz_quantize_floor(ninactive << LG_PAGE));
}
for (pszind_t i = 0; i < PSSET_NPSIZES; i++) {
if (i == nonempty_pind) {
@ -657,24 +657,25 @@ init_test_pageslabs(psset_t *psset, hpdata_t *pageslab,
}
/* Deallocate the last page from the older pageslab. */
hpdata_t *evicted = test_psset_dalloc(psset,
&alloc[HUGEPAGE_PAGES - 1]);
hpdata_t *evicted = test_psset_dalloc(
psset, &alloc[HUGEPAGE_PAGES - 1]);
expect_ptr_null(evicted, "Unexpected eviction");
}
TEST_BEGIN(test_oldest_fit) {
test_skip_if(hpa_hugepage_size_exceeds_limit());
bool err;
bool err;
edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
edata_t *worse_alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
edata_t *worse_alloc = (edata_t *)malloc(
sizeof(edata_t) * HUGEPAGE_PAGES);
hpdata_t pageslab;
hpdata_t worse_pageslab;
psset_t psset;
init_test_pageslabs(&psset, &pageslab, &worse_pageslab, alloc,
worse_alloc);
init_test_pageslabs(
&psset, &pageslab, &worse_pageslab, alloc, worse_alloc);
/* The edata should come from the better pageslab. */
edata_t test_edata;
@ -691,23 +692,24 @@ TEST_END
TEST_BEGIN(test_insert_remove) {
test_skip_if(hpa_hugepage_size_exceeds_limit());
bool err;
bool err;
hpdata_t *ps;
edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
edata_t *worse_alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
edata_t *worse_alloc = (edata_t *)malloc(
sizeof(edata_t) * HUGEPAGE_PAGES);
hpdata_t pageslab;
hpdata_t worse_pageslab;
psset_t psset;
init_test_pageslabs(&psset, &pageslab, &worse_pageslab, alloc,
worse_alloc);
init_test_pageslabs(
&psset, &pageslab, &worse_pageslab, alloc, worse_alloc);
/* Remove better; should still be able to alloc from worse. */
psset_update_begin(&psset, &pageslab);
err = test_psset_alloc_reuse(&psset, &worse_alloc[HUGEPAGE_PAGES - 1],
PAGE);
err = test_psset_alloc_reuse(
&psset, &worse_alloc[HUGEPAGE_PAGES - 1], PAGE);
expect_false(err, "Removal should still leave an empty page");
expect_ptr_eq(&worse_pageslab,
edata_ps_get(&worse_alloc[HUGEPAGE_PAGES - 1]),
@ -755,23 +757,21 @@ TEST_BEGIN(test_purge_prefers_nonhuge) {
psset_t psset;
psset_init(&psset);
hpdata_t hpdata_huge[NHP];
hpdata_t hpdata_huge[NHP];
uintptr_t huge_begin = (uintptr_t)&hpdata_huge[0];
uintptr_t huge_end = (uintptr_t)&hpdata_huge[NHP];
hpdata_t hpdata_nonhuge[NHP];
hpdata_t hpdata_nonhuge[NHP];
uintptr_t nonhuge_begin = (uintptr_t)&hpdata_nonhuge[0];
uintptr_t nonhuge_end = (uintptr_t)&hpdata_nonhuge[NHP];
for (size_t i = 0; i < NHP; i++) {
hpdata_init(&hpdata_huge[i], (void *)((10 + i) * HUGEPAGE),
123 + i);
hpdata_init(
&hpdata_huge[i], (void *)((10 + i) * HUGEPAGE), 123 + i);
psset_insert(&psset, &hpdata_huge[i]);
hpdata_init(&hpdata_nonhuge[i],
(void *)((10 + NHP + i) * HUGEPAGE),
456 + i);
(void *)((10 + NHP + i) * HUGEPAGE), 456 + i);
psset_insert(&psset, &hpdata_nonhuge[i]);
}
for (int i = 0; i < 2 * NHP; i++) {
hpdata = psset_pick_alloc(&psset, HUGEPAGE * 3 / 4);
@ -804,7 +804,8 @@ TEST_BEGIN(test_purge_prefers_nonhuge) {
for (int i = 0; i < NHP; i++) {
hpdata = psset_pick_purge(&psset);
assert_true(nonhuge_begin <= (uintptr_t)hpdata
&& (uintptr_t)hpdata < nonhuge_end, "");
&& (uintptr_t)hpdata < nonhuge_end,
"");
psset_update_begin(&psset, hpdata);
test_psset_fake_purge(hpdata);
hpdata_purge_allowed_set(hpdata, false);
@ -813,7 +814,8 @@ TEST_BEGIN(test_purge_prefers_nonhuge) {
for (int i = 0; i < NHP; i++) {
hpdata = psset_pick_purge(&psset);
expect_true(huge_begin <= (uintptr_t)hpdata
&& (uintptr_t)hpdata < huge_end, "");
&& (uintptr_t)hpdata < huge_end,
"");
psset_update_begin(&psset, hpdata);
hpdata_dehugify(hpdata);
test_psset_fake_purge(hpdata);
@ -867,13 +869,13 @@ TEST_BEGIN(test_purge_prefers_empty_huge) {
psset_t psset;
psset_init(&psset);
enum {NHP = 10 };
enum { NHP = 10 };
hpdata_t hpdata_huge[NHP];
hpdata_t hpdata_nonhuge[NHP];
uintptr_t cur_addr = 100 * HUGEPAGE;
uint64_t cur_age = 123;
uint64_t cur_age = 123;
for (int i = 0; i < NHP; i++) {
hpdata_init(&hpdata_huge[i], (void *)cur_addr, cur_age);
cur_addr += HUGEPAGE;
@ -933,18 +935,9 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_empty,
test_fill,
test_reuse,
test_evict,
test_multi_pageslab,
test_stats_merged,
test_stats_huge,
test_stats_fullness,
test_oldest_fit,
test_insert_remove,
test_purge_prefers_nonhuge,
test_purge_prefers_empty,
return test_no_reentrancy(test_empty, test_fill, test_reuse, test_evict,
test_multi_pageslab, test_stats_merged, test_stats_huge,
test_stats_fullness, test_oldest_fit, test_insert_remove,
test_purge_prefers_nonhuge, test_purge_prefers_empty,
test_purge_prefers_empty_huge);
}

View file

@ -15,16 +15,16 @@ struct list_s {
static void
test_empty_list(list_head_t *head) {
list_t *t;
list_t *t;
unsigned i;
expect_true(ql_empty(head), "Unexpected element for empty list");
expect_ptr_null(ql_first(head), "Unexpected element for empty list");
expect_ptr_null(ql_last(head, link),
"Unexpected element for empty list");
expect_ptr_null(
ql_last(head, link), "Unexpected element for empty list");
i = 0;
ql_foreach(t, head, link) {
ql_foreach (t, head, link) {
i++;
}
expect_u_eq(i, 0, "Unexpected element for empty list");
@ -56,48 +56,48 @@ init_entries(list_t *entries, unsigned nentries) {
static void
test_entries_list(list_head_t *head, list_t *entries, unsigned nentries) {
list_t *t;
list_t *t;
unsigned i;
expect_false(ql_empty(head), "List should not be empty");
expect_c_eq(ql_first(head)->id, entries[0].id, "Element id mismatch");
expect_c_eq(ql_last(head, link)->id, entries[nentries-1].id,
expect_c_eq(ql_last(head, link)->id, entries[nentries - 1].id,
"Element id mismatch");
i = 0;
ql_foreach(t, head, link) {
ql_foreach (t, head, link) {
expect_c_eq(t->id, entries[i].id, "Element id mismatch");
i++;
}
i = 0;
ql_reverse_foreach(t, head, link) {
expect_c_eq(t->id, entries[nentries-i-1].id,
"Element id mismatch");
expect_c_eq(
t->id, entries[nentries - i - 1].id, "Element id mismatch");
i++;
}
for (i = 0; i < nentries-1; i++) {
for (i = 0; i < nentries - 1; i++) {
t = ql_next(head, &entries[i], link);
expect_c_eq(t->id, entries[i+1].id, "Element id mismatch");
expect_c_eq(t->id, entries[i + 1].id, "Element id mismatch");
}
expect_ptr_null(ql_next(head, &entries[nentries-1], link),
"Unexpected element");
expect_ptr_null(
ql_next(head, &entries[nentries - 1], link), "Unexpected element");
expect_ptr_null(ql_prev(head, &entries[0], link), "Unexpected element");
for (i = 1; i < nentries; i++) {
t = ql_prev(head, &entries[i], link);
expect_c_eq(t->id, entries[i-1].id, "Element id mismatch");
expect_c_eq(t->id, entries[i - 1].id, "Element id mismatch");
}
}
TEST_BEGIN(test_ql_tail_insert) {
list_head_t head;
list_t entries[NENTRIES];
unsigned i;
list_t entries[NENTRIES];
unsigned i;
ql_new(&head);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
for (i = 0; i < NENTRIES; i++) {
ql_tail_insert(&head, &entries[i], link);
}
@ -108,17 +108,17 @@ TEST_END
TEST_BEGIN(test_ql_tail_remove) {
list_head_t head;
list_t entries[NENTRIES];
unsigned i;
list_t entries[NENTRIES];
unsigned i;
ql_new(&head);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
for (i = 0; i < NENTRIES; i++) {
ql_tail_insert(&head, &entries[i], link);
}
for (i = 0; i < NENTRIES; i++) {
test_entries_list(&head, entries, NENTRIES-i);
test_entries_list(&head, entries, NENTRIES - i);
ql_tail_remove(&head, list_t, link);
}
test_empty_list(&head);
@ -127,13 +127,13 @@ TEST_END
TEST_BEGIN(test_ql_head_insert) {
list_head_t head;
list_t entries[NENTRIES];
unsigned i;
list_t entries[NENTRIES];
unsigned i;
ql_new(&head);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
for (i = 0; i < NENTRIES; i++) {
ql_head_insert(&head, &entries[NENTRIES-i-1], link);
ql_head_insert(&head, &entries[NENTRIES - i - 1], link);
}
test_entries_list(&head, entries, NENTRIES);
@ -142,17 +142,17 @@ TEST_END
TEST_BEGIN(test_ql_head_remove) {
list_head_t head;
list_t entries[NENTRIES];
unsigned i;
list_t entries[NENTRIES];
unsigned i;
ql_new(&head);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
for (i = 0; i < NENTRIES; i++) {
ql_head_insert(&head, &entries[NENTRIES-i-1], link);
ql_head_insert(&head, &entries[NENTRIES - i - 1], link);
}
for (i = 0; i < NENTRIES; i++) {
test_entries_list(&head, &entries[i], NENTRIES-i);
test_entries_list(&head, &entries[i], NENTRIES - i);
ql_head_remove(&head, list_t, link);
}
test_empty_list(&head);
@ -161,11 +161,11 @@ TEST_END
TEST_BEGIN(test_ql_insert) {
list_head_t head;
list_t entries[8];
list_t *a, *b, *c, *d, *e, *f, *g, *h;
list_t entries[8];
list_t *a, *b, *c, *d, *e, *f, *g, *h;
ql_new(&head);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
a = &entries[0];
b = &entries[1];
c = &entries[2];
@ -190,13 +190,13 @@ TEST_BEGIN(test_ql_insert) {
ql_after_insert(c, d, link);
ql_before_insert(&head, f, e, link);
test_entries_list(&head, entries, sizeof(entries)/sizeof(list_t));
test_entries_list(&head, entries, sizeof(entries) / sizeof(list_t));
}
TEST_END
static void
test_concat_split_entries(list_t *entries, unsigned nentries_a,
unsigned nentries_b) {
test_concat_split_entries(
list_t *entries, unsigned nentries_a, unsigned nentries_b) {
init_entries(entries, nentries_a + nentries_b);
list_head_t head_a;
@ -253,8 +253,8 @@ TEST_BEGIN(test_ql_concat_split) {
test_concat_split_entries(entries, 0, NENTRIES);
test_concat_split_entries(entries, 1, NENTRIES - 1);
test_concat_split_entries(entries, NENTRIES / 2,
NENTRIES - NENTRIES / 2);
test_concat_split_entries(
entries, NENTRIES / 2, NENTRIES - NENTRIES / 2);
test_concat_split_entries(entries, NENTRIES - 1, 1);
test_concat_split_entries(entries, NENTRIES, 0);
}
@ -262,11 +262,11 @@ TEST_END
TEST_BEGIN(test_ql_rotate) {
list_head_t head;
list_t entries[NENTRIES];
unsigned i;
list_t entries[NENTRIES];
unsigned i;
ql_new(&head);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
for (i = 0; i < NENTRIES; i++) {
ql_tail_insert(&head, &entries[i], link);
}
@ -284,15 +284,15 @@ TEST_END
TEST_BEGIN(test_ql_move) {
list_head_t head_dest, head_src;
list_t entries[NENTRIES];
unsigned i;
list_t entries[NENTRIES];
unsigned i;
ql_new(&head_src);
ql_move(&head_dest, &head_src);
test_empty_list(&head_src);
test_empty_list(&head_dest);
init_entries(entries, sizeof(entries)/sizeof(list_t));
init_entries(entries, sizeof(entries) / sizeof(list_t));
for (i = 0; i < NENTRIES; i++) {
ql_tail_insert(&head_src, &entries[i], link);
}
@ -304,14 +304,7 @@ TEST_END
int
main(void) {
return test(
test_ql_empty,
test_ql_tail_insert,
test_ql_tail_remove,
test_ql_head_insert,
test_ql_head_remove,
test_ql_insert,
test_ql_concat_split,
test_ql_rotate,
test_ql_move);
return test(test_ql_empty, test_ql_tail_insert, test_ql_tail_remove,
test_ql_head_insert, test_ql_head_remove, test_ql_insert,
test_ql_concat_split, test_ql_rotate, test_ql_move);
}

View file

@ -26,12 +26,12 @@ init_entries(ring_t *entries) {
static void
test_independent_entries(ring_t *entries) {
ring_t *t;
ring_t *t;
unsigned i, j;
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_foreach(t, &entries[i], link) {
qr_foreach (t, &entries[i], link) {
j++;
}
expect_u_eq(j, 1,
@ -71,13 +71,13 @@ TEST_END
static void
test_entries_ring(ring_t *entries) {
ring_t *t;
ring_t *t;
unsigned i, j;
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_foreach(t, &entries[i], link) {
expect_c_eq(t->id, entries[(i+j) % NENTRIES].id,
qr_foreach (t, &entries[i], link) {
expect_c_eq(t->id, entries[(i + j) % NENTRIES].id,
"Element id mismatch");
j++;
}
@ -85,25 +85,26 @@ test_entries_ring(ring_t *entries) {
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_reverse_foreach(t, &entries[i], link) {
expect_c_eq(t->id, entries[(NENTRIES+i-j-1) %
NENTRIES].id, "Element id mismatch");
expect_c_eq(t->id,
entries[(NENTRIES + i - j - 1) % NENTRIES].id,
"Element id mismatch");
j++;
}
}
for (i = 0; i < NENTRIES; i++) {
t = qr_next(&entries[i], link);
expect_c_eq(t->id, entries[(i+1) % NENTRIES].id,
expect_c_eq(t->id, entries[(i + 1) % NENTRIES].id,
"Element id mismatch");
}
for (i = 0; i < NENTRIES; i++) {
t = qr_prev(&entries[i], link);
expect_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
expect_c_eq(t->id, entries[(NENTRIES + i - 1) % NENTRIES].id,
"Element id mismatch");
}
}
TEST_BEGIN(test_qr_after_insert) {
ring_t entries[NENTRIES];
ring_t entries[NENTRIES];
unsigned i;
init_entries(entries);
@ -115,8 +116,8 @@ TEST_BEGIN(test_qr_after_insert) {
TEST_END
TEST_BEGIN(test_qr_remove) {
ring_t entries[NENTRIES];
ring_t *t;
ring_t entries[NENTRIES];
ring_t *t;
unsigned i, j;
init_entries(entries);
@ -126,15 +127,15 @@ TEST_BEGIN(test_qr_remove) {
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_foreach(t, &entries[i], link) {
expect_c_eq(t->id, entries[i+j].id,
"Element id mismatch");
qr_foreach (t, &entries[i], link) {
expect_c_eq(
t->id, entries[i + j].id, "Element id mismatch");
j++;
}
j = 0;
qr_reverse_foreach(t, &entries[i], link) {
expect_c_eq(t->id, entries[NENTRIES - 1 - j].id,
"Element id mismatch");
"Element id mismatch");
j++;
}
qr_remove(&entries[i], link);
@ -144,8 +145,8 @@ TEST_BEGIN(test_qr_remove) {
TEST_END
TEST_BEGIN(test_qr_before_insert) {
ring_t entries[NENTRIES];
ring_t *t;
ring_t entries[NENTRIES];
ring_t *t;
unsigned i, j;
init_entries(entries);
@ -154,28 +155,29 @@ TEST_BEGIN(test_qr_before_insert) {
}
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_foreach(t, &entries[i], link) {
expect_c_eq(t->id, entries[(NENTRIES+i-j) %
NENTRIES].id, "Element id mismatch");
qr_foreach (t, &entries[i], link) {
expect_c_eq(t->id,
entries[(NENTRIES + i - j) % NENTRIES].id,
"Element id mismatch");
j++;
}
}
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_reverse_foreach(t, &entries[i], link) {
expect_c_eq(t->id, entries[(i+j+1) % NENTRIES].id,
expect_c_eq(t->id, entries[(i + j + 1) % NENTRIES].id,
"Element id mismatch");
j++;
}
}
for (i = 0; i < NENTRIES; i++) {
t = qr_next(&entries[i], link);
expect_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
expect_c_eq(t->id, entries[(NENTRIES + i - 1) % NENTRIES].id,
"Element id mismatch");
}
for (i = 0; i < NENTRIES; i++) {
t = qr_prev(&entries[i], link);
expect_c_eq(t->id, entries[(i+1) % NENTRIES].id,
expect_c_eq(t->id, entries[(i + 1) % NENTRIES].id,
"Element id mismatch");
}
}
@ -183,19 +185,22 @@ TEST_END
static void
test_split_entries(ring_t *entries) {
ring_t *t;
ring_t *t;
unsigned i, j;
for (i = 0; i < NENTRIES; i++) {
j = 0;
qr_foreach(t, &entries[i], link) {
qr_foreach (t, &entries[i], link) {
if (i < SPLIT_INDEX) {
expect_c_eq(t->id,
entries[(i+j) % SPLIT_INDEX].id,
entries[(i + j) % SPLIT_INDEX].id,
"Element id mismatch");
} else {
expect_c_eq(t->id, entries[(i+j-SPLIT_INDEX) %
(NENTRIES-SPLIT_INDEX) + SPLIT_INDEX].id,
expect_c_eq(t->id,
entries[(i + j - SPLIT_INDEX)
% (NENTRIES - SPLIT_INDEX)
+ SPLIT_INDEX]
.id,
"Element id mismatch");
}
j++;
@ -204,7 +209,7 @@ test_split_entries(ring_t *entries) {
}
TEST_BEGIN(test_qr_meld_split) {
ring_t entries[NENTRIES];
ring_t entries[NENTRIES];
unsigned i;
init_entries(entries);
@ -234,10 +239,6 @@ TEST_END
int
main(void) {
return test(
test_qr_one,
test_qr_after_insert,
test_qr_remove,
test_qr_before_insert,
test_qr_meld_split);
return test(test_qr_one, test_qr_after_insert, test_qr_remove,
test_qr_before_insert, test_qr_meld_split);
}

View file

@ -4,16 +4,17 @@
#include "jemalloc/internal/rb.h"
#define rbtn_black_height(a_type, a_field, a_rbt, r_height) do { \
a_type *rbp_bh_t; \
for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0; rbp_bh_t != \
NULL; rbp_bh_t = rbtn_left_get(a_type, a_field, \
rbp_bh_t)) { \
if (!rbtn_red_get(a_type, a_field, rbp_bh_t)) { \
(r_height)++; \
} \
} \
} while (0)
#define rbtn_black_height(a_type, a_field, a_rbt, r_height) \
do { \
a_type *rbp_bh_t; \
for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0; \
rbp_bh_t != NULL; \
rbp_bh_t = rbtn_left_get(a_type, a_field, rbp_bh_t)) { \
if (!rbtn_red_get(a_type, a_field, rbp_bh_t)) { \
(r_height)++; \
} \
} \
} while (0)
static bool summarize_always_returns_true = false;
@ -55,7 +56,7 @@ struct node_s {
*/
const node_t *summary_lchild;
const node_t *summary_rchild;
uint64_t summary_max_specialness;
uint64_t summary_max_specialness;
};
static int
@ -80,8 +81,8 @@ node_cmp(const node_t *a, const node_t *b) {
}
static uint64_t
node_subtree_specialness(node_t *n, const node_t *lchild,
const node_t *rchild) {
node_subtree_specialness(
node_t *n, const node_t *lchild, const node_t *rchild) {
uint64_t subtree_specialness = n->specialness;
if (lchild != NULL
&& lchild->summary_max_specialness > subtree_specialness) {
@ -109,8 +110,8 @@ node_summarize(node_t *a, const node_t *lchild, const node_t *rchild) {
typedef rb_tree(node_t) tree_t;
rb_summarized_proto(static, tree_, tree_t, node_t);
rb_summarized_gen(static, tree_, tree_t, node_t, link, node_cmp,
node_summarize);
rb_summarized_gen(
static, tree_, tree_t, node_t, link, node_cmp, node_summarize);
static bool
specialness_filter_node(void *ctx, node_t *node) {
@ -127,24 +128,24 @@ specialness_filter_subtree(void *ctx, node_t *node) {
static node_t *
tree_iterate_cb(tree_t *tree, node_t *node, void *data) {
unsigned *i = (unsigned *)data;
node_t *search_node;
node_t *search_node;
expect_u32_eq(node->magic, NODE_MAGIC, "Bad magic");
/* Test rb_search(). */
search_node = tree_search(tree, node);
expect_ptr_eq(search_node, node,
"tree_search() returned unexpected node");
expect_ptr_eq(
search_node, node, "tree_search() returned unexpected node");
/* Test rb_nsearch(). */
search_node = tree_nsearch(tree, node);
expect_ptr_eq(search_node, node,
"tree_nsearch() returned unexpected node");
expect_ptr_eq(
search_node, node, "tree_nsearch() returned unexpected node");
/* Test rb_psearch(). */
search_node = tree_psearch(tree, node);
expect_ptr_eq(search_node, node,
"tree_psearch() returned unexpected node");
expect_ptr_eq(
search_node, node, "tree_psearch() returned unexpected node");
(*i)++;
@ -174,38 +175,44 @@ TEST_BEGIN(test_rb_empty) {
expect_ptr_null(tree_psearch(&tree, &key), "Unexpected node");
unsigned nodes = 0;
tree_iter_filtered(&tree, NULL, &tree_iterate_cb,
&nodes, &specialness_filter_node, &specialness_filter_subtree,
NULL);
tree_iter_filtered(&tree, NULL, &tree_iterate_cb, &nodes,
&specialness_filter_node, &specialness_filter_subtree, NULL);
expect_u_eq(0, nodes, "");
nodes = 0;
tree_reverse_iter_filtered(&tree, NULL, &tree_iterate_cb,
&nodes, &specialness_filter_node, &specialness_filter_subtree,
NULL);
tree_reverse_iter_filtered(&tree, NULL, &tree_iterate_cb, &nodes,
&specialness_filter_node, &specialness_filter_subtree, NULL);
expect_u_eq(0, nodes, "");
expect_ptr_null(tree_first_filtered(&tree, &specialness_filter_node,
&specialness_filter_subtree, NULL), "");
&specialness_filter_subtree, NULL),
"");
expect_ptr_null(tree_last_filtered(&tree, &specialness_filter_node,
&specialness_filter_subtree, NULL), "");
&specialness_filter_subtree, NULL),
"");
key.key = 0;
key.magic = NODE_MAGIC;
expect_ptr_null(tree_search_filtered(&tree, &key,
&specialness_filter_node, &specialness_filter_subtree, NULL), "");
expect_ptr_null(tree_nsearch_filtered(&tree, &key,
&specialness_filter_node, &specialness_filter_subtree, NULL), "");
expect_ptr_null(tree_psearch_filtered(&tree, &key,
&specialness_filter_node, &specialness_filter_subtree, NULL), "");
expect_ptr_null(
tree_search_filtered(&tree, &key, &specialness_filter_node,
&specialness_filter_subtree, NULL),
"");
expect_ptr_null(
tree_nsearch_filtered(&tree, &key, &specialness_filter_node,
&specialness_filter_subtree, NULL),
"");
expect_ptr_null(
tree_psearch_filtered(&tree, &key, &specialness_filter_node,
&specialness_filter_subtree, NULL),
"");
}
TEST_END
static unsigned
tree_recurse(node_t *node, unsigned black_height, unsigned black_depth) {
unsigned ret = 0;
node_t *left_node;
node_t *right_node;
node_t *left_node;
node_t *right_node;
if (node == NULL) {
return ret;
@ -214,13 +221,13 @@ tree_recurse(node_t *node, unsigned black_height, unsigned black_depth) {
left_node = rbtn_left_get(node_t, link, node);
right_node = rbtn_right_get(node_t, link, node);
expect_ptr_eq(left_node, node->summary_lchild,
"summary missed a tree update");
expect_ptr_eq(right_node, node->summary_rchild,
"summary missed a tree update");
expect_ptr_eq(
left_node, node->summary_lchild, "summary missed a tree update");
expect_ptr_eq(
right_node, node->summary_rchild, "summary missed a tree update");
uint64_t expected_subtree_specialness = node_subtree_specialness(node,
left_node, right_node);
uint64_t expected_subtree_specialness = node_subtree_specialness(
node, left_node, right_node);
expect_u64_eq(expected_subtree_specialness,
node->summary_max_specialness, "Incorrect summary");
@ -232,7 +239,7 @@ tree_recurse(node_t *node, unsigned black_height, unsigned black_depth) {
if (rbtn_red_get(node_t, link, node)) {
if (left_node != NULL) {
expect_false(rbtn_red_get(node_t, link, left_node),
"Node should be black");
"Node should be black");
}
if (right_node != NULL) {
expect_false(rbtn_red_get(node_t, link, right_node),
@ -282,7 +289,7 @@ tree_iterate_reverse(tree_t *tree) {
static void
node_remove(tree_t *tree, node_t *node, unsigned nnodes) {
node_t *search_node;
node_t *search_node;
unsigned black_height, imbalances;
tree_remove(tree, node);
@ -290,15 +297,15 @@ node_remove(tree_t *tree, node_t *node, unsigned nnodes) {
/* Test rb_nsearch(). */
search_node = tree_nsearch(tree, node);
if (search_node != NULL) {
expect_u64_ge(search_node->key, node->key,
"Key ordering error");
expect_u64_ge(
search_node->key, node->key, "Key ordering error");
}
/* Test rb_psearch(). */
search_node = tree_psearch(tree, node);
if (search_node != NULL) {
expect_u64_le(search_node->key, node->key,
"Key ordering error");
expect_u64_le(
search_node->key, node->key, "Key ordering error");
}
node->magic = 0;
@ -306,16 +313,16 @@ node_remove(tree_t *tree, node_t *node, unsigned nnodes) {
rbtn_black_height(node_t, link, tree, black_height);
imbalances = tree_recurse(tree->rbt_root, black_height, 0);
expect_u_eq(imbalances, 0, "Tree is unbalanced");
expect_u_eq(tree_iterate(tree), nnodes-1,
"Unexpected node iteration count");
expect_u_eq(tree_iterate_reverse(tree), nnodes-1,
expect_u_eq(
tree_iterate(tree), nnodes - 1, "Unexpected node iteration count");
expect_u_eq(tree_iterate_reverse(tree), nnodes - 1,
"Unexpected node iteration count");
}
static node_t *
remove_iterate_cb(tree_t *tree, node_t *node, void *data) {
unsigned *nnodes = (unsigned *)data;
node_t *ret = tree_next(tree, node);
node_t *ret = tree_next(tree, node);
node_remove(tree, node, *nnodes);
@ -325,7 +332,7 @@ remove_iterate_cb(tree_t *tree, node_t *node, void *data) {
static node_t *
remove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data) {
unsigned *nnodes = (unsigned *)data;
node_t *ret = tree_prev(tree, node);
node_t *ret = tree_prev(tree, node);
node_remove(tree, node, *nnodes);
@ -341,15 +348,11 @@ destroy_cb(node_t *node, void *data) {
}
TEST_BEGIN(test_rb_random) {
enum {
NNODES = 25,
NBAGS = 500,
SEED = 42
};
sfmt_t *sfmt;
enum { NNODES = 25, NBAGS = 500, SEED = 42 };
sfmt_t *sfmt;
uint64_t bag[NNODES];
tree_t tree;
node_t nodes[NNODES];
tree_t tree;
node_t nodes[NNODES];
unsigned i, j, k, black_height, imbalances;
sfmt = init_gen_rand(SEED);
@ -386,8 +389,8 @@ TEST_BEGIN(test_rb_random) {
for (k = 0; k < j; k++) {
nodes[k].magic = NODE_MAGIC;
nodes[k].key = bag[k];
nodes[k].specialness = gen_rand64_range(sfmt,
NNODES);
nodes[k].specialness = gen_rand64_range(
sfmt, NNODES);
nodes[k].mid_remove = false;
nodes[k].allow_duplicates = false;
nodes[k].summary_lchild = NULL;
@ -399,16 +402,16 @@ TEST_BEGIN(test_rb_random) {
for (k = 0; k < j; k++) {
tree_insert(&tree, &nodes[k]);
rbtn_black_height(node_t, link, &tree,
black_height);
imbalances = tree_recurse(tree.rbt_root,
black_height, 0);
expect_u_eq(imbalances, 0,
"Tree is unbalanced");
rbtn_black_height(
node_t, link, &tree, black_height);
imbalances = tree_recurse(
tree.rbt_root, black_height, 0);
expect_u_eq(
imbalances, 0, "Tree is unbalanced");
expect_u_eq(tree_iterate(&tree), k+1,
expect_u_eq(tree_iterate(&tree), k + 1,
"Unexpected node iteration count");
expect_u_eq(tree_iterate_reverse(&tree), k+1,
expect_u_eq(tree_iterate_reverse(&tree), k + 1,
"Unexpected node iteration count");
expect_false(tree_empty(&tree),
@ -431,11 +434,11 @@ TEST_BEGIN(test_rb_random) {
break;
case 1:
for (k = j; k > 0; k--) {
node_remove(&tree, &nodes[k-1], k);
node_remove(&tree, &nodes[k - 1], k);
}
break;
case 2: {
node_t *start;
node_t *start;
unsigned nnodes = j;
start = NULL;
@ -444,11 +447,12 @@ TEST_BEGIN(test_rb_random) {
remove_iterate_cb, (void *)&nnodes);
nnodes--;
} while (start != NULL);
expect_u_eq(nnodes, 0,
"Removal terminated early");
expect_u_eq(
nnodes, 0, "Removal terminated early");
break;
} case 3: {
node_t *start;
}
case 3: {
node_t *start;
unsigned nnodes = j;
start = NULL;
@ -458,16 +462,18 @@ TEST_BEGIN(test_rb_random) {
(void *)&nnodes);
nnodes--;
} while (start != NULL);
expect_u_eq(nnodes, 0,
"Removal terminated early");
expect_u_eq(
nnodes, 0, "Removal terminated early");
break;
} case 4: {
}
case 4: {
unsigned nnodes = j;
tree_destroy(&tree, destroy_cb, &nnodes);
expect_u_eq(nnodes, 0,
"Destruction terminated early");
expect_u_eq(
nnodes, 0, "Destruction terminated early");
break;
} default:
}
default:
not_reached();
}
}
@ -479,7 +485,7 @@ TEST_END
static void
expect_simple_consistency(tree_t *tree, uint64_t specialness,
bool expected_empty, node_t *expected_first, node_t *expected_last) {
bool empty;
bool empty;
node_t *first;
node_t *last;
@ -487,19 +493,17 @@ expect_simple_consistency(tree_t *tree, uint64_t specialness,
&specialness_filter_subtree, &specialness);
expect_b_eq(expected_empty, empty, "");
first = tree_first_filtered(tree,
&specialness_filter_node, &specialness_filter_subtree,
(void *)&specialness);
first = tree_first_filtered(tree, &specialness_filter_node,
&specialness_filter_subtree, (void *)&specialness);
expect_ptr_eq(expected_first, first, "");
last = tree_last_filtered(tree,
&specialness_filter_node, &specialness_filter_subtree,
(void *)&specialness);
last = tree_last_filtered(tree, &specialness_filter_node,
&specialness_filter_subtree, (void *)&specialness);
expect_ptr_eq(expected_last, last, "");
}
TEST_BEGIN(test_rb_filter_simple) {
enum {FILTER_NODES = 10};
enum { FILTER_NODES = 10 };
node_t nodes[FILTER_NODES];
for (unsigned i = 0; i < FILTER_NODES; i++) {
nodes[i].magic = NODE_MAGIC;
@ -583,10 +587,10 @@ TEST_END
typedef struct iter_ctx_s iter_ctx_t;
struct iter_ctx_s {
int ncalls;
int ncalls;
node_t *last_node;
int ncalls_max;
int ncalls_max;
bool forward;
};
@ -624,8 +628,8 @@ static void
check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
uint64_t specialness = 1;
bool empty;
bool real_empty = true;
bool empty;
bool real_empty = true;
node_t *first;
node_t *real_first = NULL;
node_t *last;
@ -667,12 +671,14 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
}
if (node_cmp(&nodes[j], &nodes[i]) < 0
&& (real_prev_filtered == NULL
|| node_cmp(&nodes[j], real_prev_filtered) > 0)) {
|| node_cmp(&nodes[j], real_prev_filtered)
> 0)) {
real_prev_filtered = &nodes[j];
}
if (node_cmp(&nodes[j], &nodes[i]) > 0
&& (real_next_filtered == NULL
|| node_cmp(&nodes[j], real_next_filtered) < 0)) {
|| node_cmp(&nodes[j], real_next_filtered)
< 0)) {
real_next_filtered = &nodes[j];
}
}
@ -707,8 +713,9 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
&specialness);
expect_ptr_eq(real_search_filtered, search_filtered, "");
real_nsearch_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : real_next_filtered);
real_nsearch_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: real_next_filtered);
nsearch_filtered = tree_nsearch_filtered(tree, &before,
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
@ -721,22 +728,25 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
expect_ptr_eq(real_psearch_filtered, psearch_filtered, "");
/* search, nsearch, psearch from nodes[i] */
real_search_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : NULL);
real_search_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: NULL);
search_filtered = tree_search_filtered(tree, &nodes[i],
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
expect_ptr_eq(real_search_filtered, search_filtered, "");
real_nsearch_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : real_next_filtered);
real_nsearch_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: real_next_filtered);
nsearch_filtered = tree_nsearch_filtered(tree, &nodes[i],
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
expect_ptr_eq(real_nsearch_filtered, nsearch_filtered, "");
real_psearch_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : real_prev_filtered);
real_psearch_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: real_prev_filtered);
psearch_filtered = tree_psearch_filtered(tree, &nodes[i],
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
@ -750,22 +760,25 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
equiv.magic = NODE_MAGIC;
equiv.key = nodes[i].key;
equiv.allow_duplicates = true;
real_search_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : NULL);
real_search_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: NULL);
search_filtered = tree_search_filtered(tree, &equiv,
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
expect_ptr_eq(real_search_filtered, search_filtered, "");
real_nsearch_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : real_next_filtered);
real_nsearch_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: real_next_filtered);
nsearch_filtered = tree_nsearch_filtered(tree, &equiv,
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
expect_ptr_eq(real_nsearch_filtered, nsearch_filtered, "");
real_psearch_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : real_prev_filtered);
real_psearch_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: real_prev_filtered);
psearch_filtered = tree_psearch_filtered(tree, &equiv,
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
@ -791,8 +804,9 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
&specialness);
expect_ptr_eq(real_nsearch_filtered, nsearch_filtered, "");
real_psearch_filtered = (nodes[i].specialness >= specialness ?
&nodes[i] : real_prev_filtered);
real_psearch_filtered = (nodes[i].specialness >= specialness
? &nodes[i]
: real_prev_filtered);
psearch_filtered = tree_psearch_filtered(tree, &after,
&specialness_filter_node, &specialness_filter_subtree,
&specialness);
@ -800,7 +814,7 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
}
/* Filtered iteration test setup. */
int nspecial = 0;
int nspecial = 0;
node_t *sorted_nodes[UPDATE_TEST_MAX];
node_t *sorted_filtered_nodes[UPDATE_TEST_MAX];
for (int i = 0; i < nnodes; i++) {
@ -862,8 +876,9 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
&specialness_filter_node,
&specialness_filter_subtree, &specialness);
expect_d_eq(j + 1, ctx.ncalls, "");
expect_ptr_eq(sorted_filtered_nodes[
nodes[i].filtered_rank + j], iter_result, "");
expect_ptr_eq(
sorted_filtered_nodes[nodes[i].filtered_rank + j],
iter_result, "");
}
}
@ -888,8 +903,8 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
&specialness_filter_subtree, &specialness);
expect_ptr_null(iter_result, "");
int surplus_rank = (nodes[i].specialness >= 1 ? 1 : 0);
expect_d_eq(nodes[i].filtered_rank + surplus_rank, ctx.ncalls,
"");
expect_d_eq(
nodes[i].filtered_rank + surplus_rank, ctx.ncalls, "");
}
/* Filtered backward iteration from the end, with stopping */
for (int i = 0; i < nspecial; i++) {
@ -899,15 +914,15 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
iter_result = tree_reverse_iter_filtered(tree, NULL,
&tree_iterate_filtered_cb, &ctx, &specialness_filter_node,
&specialness_filter_subtree, &specialness);
expect_ptr_eq(sorted_filtered_nodes[nspecial - i - 1],
iter_result, "");
expect_ptr_eq(
sorted_filtered_nodes[nspecial - i - 1], iter_result, "");
expect_d_eq(ctx.ncalls, i + 1, "");
}
/* Filtered backward iteration from a starting point, with stopping. */
for (int i = 0; i < nnodes; i++) {
int surplus_rank = (nodes[i].specialness >= 1 ? 1 : 0);
for (int j = 0; j < nodes[i].filtered_rank + surplus_rank;
j++) {
j++) {
ctx.ncalls = 0;
ctx.last_node = NULL;
ctx.ncalls_max = j + 1;
@ -916,16 +931,16 @@ check_consistency(tree_t *tree, node_t nodes[UPDATE_TEST_MAX], int nnodes) {
&specialness_filter_node,
&specialness_filter_subtree, &specialness);
expect_d_eq(j + 1, ctx.ncalls, "");
expect_ptr_eq(sorted_filtered_nodes[
nodes[i].filtered_rank - j - 1 + surplus_rank],
expect_ptr_eq(
sorted_filtered_nodes[nodes[i].filtered_rank - j - 1
+ surplus_rank],
iter_result, "");
}
}
}
static void
do_update_search_test(int nnodes, int ntrees, int nremovals,
int nupdates) {
do_update_search_test(int nnodes, int ntrees, int nremovals, int nupdates) {
node_t nodes[UPDATE_TEST_MAX];
assert(nnodes <= UPDATE_TEST_MAX);
@ -987,8 +1002,8 @@ rb_gen(static UNUSED, unsummarized_tree_, unsummarized_tree_t, node_t, link,
node_cmp);
static node_t *
unsummarized_tree_iterate_cb(unsummarized_tree_t *tree, node_t *node,
void *data) {
unsummarized_tree_iterate_cb(
unsummarized_tree_t *tree, node_t *node, void *data) {
unsigned *i = (unsigned *)data;
(*i)++;
return NULL;
@ -1002,18 +1017,14 @@ TEST_BEGIN(test_rb_unsummarized) {
unsummarized_tree_t tree;
unsummarized_tree_new(&tree);
unsigned nnodes = 0;
unsummarized_tree_iter(&tree, NULL, &unsummarized_tree_iterate_cb,
&nnodes);
unsummarized_tree_iter(
&tree, NULL, &unsummarized_tree_iterate_cb, &nnodes);
expect_u_eq(0, nnodes, "");
}
TEST_END
int
main(void) {
return test_no_reentrancy(
test_rb_empty,
test_rb_random,
test_rb_filter_simple,
test_rb_update_search,
test_rb_unsummarized);
return test_no_reentrancy(test_rb_empty, test_rb_random,
test_rb_filter_simple, test_rb_update_search, test_rb_unsummarized);
}

View file

@ -3,21 +3,22 @@
#include "jemalloc/internal/san.h"
#include "jemalloc/internal/spin.h"
static unsigned arena_ind;
static size_t sz;
static size_t esz;
#define NEPOCHS 8
#define PER_THD_NALLOCS 1
static atomic_u_t epoch;
static atomic_u_t nfinished;
static unsigned arena_ind;
static size_t sz;
static size_t esz;
#define NEPOCHS 8
#define PER_THD_NALLOCS 1
static atomic_u_t epoch;
static atomic_u_t nfinished;
static unsigned
do_arena_create(extent_hooks_t *h) {
unsigned new_arena_ind;
size_t ind_sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.create", (void *)&new_arena_ind, &ind_sz,
(void *)(h != NULL ? &h : NULL), (h != NULL ? sizeof(h) : 0)), 0,
"Unexpected mallctl() failure");
size_t ind_sz = sizeof(unsigned);
expect_d_eq(
mallctl("arenas.create", (void *)&new_arena_ind, &ind_sz,
(void *)(h != NULL ? &h : NULL), (h != NULL ? sizeof(h) : 0)),
0, "Unexpected mallctl() failure");
return new_arena_ind;
}
@ -26,7 +27,7 @@ do_arena_destroy(unsigned ind) {
size_t mib[3];
size_t miblen;
miblen = sizeof(mib)/sizeof(size_t);
miblen = sizeof(mib) / sizeof(size_t);
expect_d_eq(mallctlnametomib("arena.0.destroy", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure");
mib[1] = (size_t)ind;
@ -38,7 +39,8 @@ static void
do_refresh(void) {
uint64_t refresh_epoch = 1;
expect_d_eq(mallctl("epoch", NULL, NULL, (void *)&refresh_epoch,
sizeof(refresh_epoch)), 0, "Unexpected mallctl() failure");
sizeof(refresh_epoch)),
0, "Unexpected mallctl() failure");
}
static size_t
@ -47,12 +49,12 @@ do_get_size_impl(const char *cmd, unsigned ind) {
size_t miblen = sizeof(mib) / sizeof(size_t);
size_t z = sizeof(size_t);
expect_d_eq(mallctlnametomib(cmd, mib, &miblen),
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
expect_d_eq(mallctlnametomib(cmd, mib, &miblen), 0,
"Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
mib[2] = ind;
size_t size;
expect_d_eq(mallctlbymib(mib, miblen, (void *)&size, &z, NULL, 0),
0, "Unexpected mallctlbymib([\"%s\"], ...) failure", cmd);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&size, &z, NULL, 0), 0,
"Unexpected mallctlbymib([\"%s\"], ...) failure", cmd);
return size;
}
@ -72,9 +74,9 @@ thd_start(void *arg) {
for (unsigned next_epoch = 1; next_epoch < NEPOCHS; next_epoch++) {
/* Busy-wait for next epoch. */
unsigned cur_epoch;
spin_t spinner = SPIN_INITIALIZER;
while ((cur_epoch = atomic_load_u(&epoch, ATOMIC_ACQUIRE)) !=
next_epoch) {
spin_t spinner = SPIN_INITIALIZER;
while ((cur_epoch = atomic_load_u(&epoch, ATOMIC_ACQUIRE))
!= next_epoch) {
spin_adaptive(&spinner);
}
expect_u_eq(cur_epoch, next_epoch, "Unexpected epoch");
@ -84,11 +86,10 @@ thd_start(void *arg) {
* no need to deallocate.
*/
for (unsigned i = 0; i < PER_THD_NALLOCS; i++) {
void *p = mallocx(sz, MALLOCX_ARENA(arena_ind) |
MALLOCX_TCACHE_NONE
);
expect_ptr_not_null(p,
"Unexpected mallocx() failure\n");
void *p = mallocx(
sz, MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE);
expect_ptr_not_null(
p, "Unexpected mallocx() failure\n");
}
/* Let the main thread know we've finished this iteration. */
@ -142,17 +143,17 @@ TEST_BEGIN(test_retained) {
*/
do_refresh();
size_t allocated = (esz - guard_sz) * nthreads *
PER_THD_NALLOCS;
size_t allocated = (esz - guard_sz) * nthreads
* PER_THD_NALLOCS;
size_t active = do_get_active(arena_ind);
expect_zu_le(allocated, active, "Unexpected active memory");
size_t mapped = do_get_mapped(arena_ind);
expect_zu_le(active, mapped, "Unexpected mapped memory");
arena_t *arena = arena_get(tsdn_fetch(), arena_ind, false);
size_t usable = 0;
for (pszind_t pind = sz_psz2ind(HUGEPAGE); pind <
arena->pa_shard.pac.exp_grow.next; pind++) {
size_t usable = 0;
for (pszind_t pind = sz_psz2ind(HUGEPAGE);
pind < arena->pa_shard.pac.exp_grow.next; pind++) {
size_t psz = sz_pind2sz(pind);
size_t psz_fragmented = psz % esz;
size_t psz_usable = psz - psz_fragmented;
@ -162,8 +163,8 @@ TEST_BEGIN(test_retained) {
if (psz_usable > 0) {
expect_zu_lt(usable, allocated,
"Excessive retained memory "
"(%#zx[+%#zx] > %#zx)", usable, psz_usable,
allocated);
"(%#zx[+%#zx] > %#zx)",
usable, psz_usable, allocated);
usable += psz_usable;
}
}
@ -174,8 +175,8 @@ TEST_BEGIN(test_retained) {
* (rather than retaining) during reset.
*/
do_arena_destroy(arena_ind);
expect_u_eq(do_arena_create(NULL), arena_ind,
"Unexpected arena index");
expect_u_eq(
do_arena_create(NULL), arena_ind, "Unexpected arena index");
}
for (unsigned i = 0; i < nthreads; i++) {
@ -188,6 +189,5 @@ TEST_END
int
main(void) {
return test(
test_retained);
return test(test_retained);
}

View file

@ -16,14 +16,15 @@ TEST_BEGIN(test_rtree_read_empty) {
/* metadata_use_hooks */ true);
expect_ptr_not_null(base, "Unexpected base_new failure");
rtree_t *rtree = &test_rtree;
rtree_t *rtree = &test_rtree;
rtree_ctx_t rtree_ctx;
rtree_ctx_data_init(&rtree_ctx);
expect_false(rtree_new(rtree, base, false),
"Unexpected rtree_new() failure");
expect_false(
rtree_new(rtree, base, false), "Unexpected rtree_new() failure");
rtree_contents_t contents;
expect_true(rtree_read_independent(tsdn, rtree, &rtree_ctx, PAGE,
&contents), "rtree_read_independent() should fail on empty rtree.");
expect_true(
rtree_read_independent(tsdn, rtree, &rtree_ctx, PAGE, &contents),
"rtree_read_independent() should fail on empty rtree.");
base_delete(tsdn, base);
}
@ -45,9 +46,9 @@ TEST_BEGIN(test_rtree_extrema) {
edata_t *edata_a, *edata_b;
edata_a = alloc_edata();
edata_b = alloc_edata();
edata_init(edata_a, INVALID_ARENA_IND, NULL, SC_LARGE_MINCLASS,
false, sz_size2index(SC_LARGE_MINCLASS), 0,
extent_state_active, false, false, EXTENT_PAI_PAC, EXTENT_NOT_HEAD);
edata_init(edata_a, INVALID_ARENA_IND, NULL, SC_LARGE_MINCLASS, false,
sz_size2index(SC_LARGE_MINCLASS), 0, extent_state_active, false,
false, EXTENT_PAI_PAC, EXTENT_NOT_HEAD);
edata_init(edata_b, INVALID_ARENA_IND, NULL, 0, false, SC_NSIZES, 0,
extent_state_active, false, false, EXTENT_PAI_PAC, EXTENT_NOT_HEAD);
@ -57,11 +58,11 @@ TEST_BEGIN(test_rtree_extrema) {
/* metadata_use_hooks */ true);
expect_ptr_not_null(base, "Unexpected base_new failure");
rtree_t *rtree = &test_rtree;
rtree_t *rtree = &test_rtree;
rtree_ctx_t rtree_ctx;
rtree_ctx_data_init(&rtree_ctx);
expect_false(rtree_new(rtree, base, false),
"Unexpected rtree_new() failure");
expect_false(
rtree_new(rtree, base, false), "Unexpected rtree_new() failure");
rtree_contents_t contents_a;
contents_a.edata = edata_a;
@ -73,13 +74,14 @@ TEST_BEGIN(test_rtree_extrema) {
"Unexpected rtree_write() failure");
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, PAGE, contents_a),
"Unexpected rtree_write() failure");
rtree_contents_t read_contents_a = rtree_read(tsdn, rtree, &rtree_ctx,
PAGE);
rtree_contents_t read_contents_a = rtree_read(
tsdn, rtree, &rtree_ctx, PAGE);
expect_true(contents_a.edata == read_contents_a.edata
&& contents_a.metadata.szind == read_contents_a.metadata.szind
&& contents_a.metadata.slab == read_contents_a.metadata.slab
&& contents_a.metadata.is_head == read_contents_a.metadata.is_head
&& contents_a.metadata.state == read_contents_a.metadata.state,
&& contents_a.metadata.szind == read_contents_a.metadata.szind
&& contents_a.metadata.slab == read_contents_a.metadata.slab
&& contents_a.metadata.is_head
== read_contents_a.metadata.is_head
&& contents_a.metadata.state == read_contents_a.metadata.state,
"rtree_read() should return previously set value");
rtree_contents_t contents_b;
@ -88,15 +90,17 @@ TEST_BEGIN(test_rtree_extrema) {
contents_b.metadata.slab = edata_slab_get(edata_b);
contents_b.metadata.is_head = edata_is_head_get(edata_b);
contents_b.metadata.state = edata_state_get(edata_b);
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, ~((uintptr_t)0),
contents_b), "Unexpected rtree_write() failure");
rtree_contents_t read_contents_b = rtree_read(tsdn, rtree, &rtree_ctx,
~((uintptr_t)0));
expect_false(
rtree_write(tsdn, rtree, &rtree_ctx, ~((uintptr_t)0), contents_b),
"Unexpected rtree_write() failure");
rtree_contents_t read_contents_b = rtree_read(
tsdn, rtree, &rtree_ctx, ~((uintptr_t)0));
assert_true(contents_b.edata == read_contents_b.edata
&& contents_b.metadata.szind == read_contents_b.metadata.szind
&& contents_b.metadata.slab == read_contents_b.metadata.slab
&& contents_b.metadata.is_head == read_contents_b.metadata.is_head
&& contents_b.metadata.state == read_contents_b.metadata.state,
&& contents_b.metadata.szind == read_contents_b.metadata.szind
&& contents_b.metadata.slab == read_contents_b.metadata.slab
&& contents_b.metadata.is_head
== read_contents_b.metadata.is_head
&& contents_b.metadata.state == read_contents_b.metadata.state,
"rtree_read() should return previously set value");
base_delete(tsdn, base);
@ -109,19 +113,19 @@ TEST_BEGIN(test_rtree_bits) {
/* metadata_use_hooks */ true);
expect_ptr_not_null(base, "Unexpected base_new failure");
uintptr_t keys[] = {PAGE, PAGE + 1,
PAGE + (((uintptr_t)1) << LG_PAGE) - 1};
uintptr_t keys[] = {
PAGE, PAGE + 1, PAGE + (((uintptr_t)1) << LG_PAGE) - 1};
edata_t *edata_c = alloc_edata();
edata_init(edata_c, INVALID_ARENA_IND, NULL, 0, false, SC_NSIZES, 0,
extent_state_active, false, false, EXTENT_PAI_PAC, EXTENT_NOT_HEAD);
rtree_t *rtree = &test_rtree;
rtree_t *rtree = &test_rtree;
rtree_ctx_t rtree_ctx;
rtree_ctx_data_init(&rtree_ctx);
expect_false(rtree_new(rtree, base, false),
"Unexpected rtree_new() failure");
expect_false(
rtree_new(rtree, base, false), "Unexpected rtree_new() failure");
for (unsigned i = 0; i < sizeof(keys)/sizeof(uintptr_t); i++) {
for (unsigned i = 0; i < sizeof(keys) / sizeof(uintptr_t); i++) {
rtree_contents_t contents;
contents.edata = edata_c;
contents.metadata.szind = SC_NSIZES;
@ -129,18 +133,22 @@ TEST_BEGIN(test_rtree_bits) {
contents.metadata.is_head = false;
contents.metadata.state = extent_state_active;
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, keys[i],
contents), "Unexpected rtree_write() failure");
for (unsigned j = 0; j < sizeof(keys)/sizeof(uintptr_t); j++) {
expect_ptr_eq(rtree_read(tsdn, rtree, &rtree_ctx,
keys[j]).edata, edata_c,
expect_false(
rtree_write(tsdn, rtree, &rtree_ctx, keys[i], contents),
"Unexpected rtree_write() failure");
for (unsigned j = 0; j < sizeof(keys) / sizeof(uintptr_t);
j++) {
expect_ptr_eq(
rtree_read(tsdn, rtree, &rtree_ctx, keys[j]).edata,
edata_c,
"rtree_edata_read() should return previously set "
"value and ignore insignificant key bits; i=%u, "
"j=%u, set key=%#"FMTxPTR", get key=%#"FMTxPTR, i,
j, keys[i], keys[j]);
"j=%u, set key=%#" FMTxPTR ", get key=%#" FMTxPTR,
i, j, keys[i], keys[j]);
}
expect_ptr_null(rtree_read(tsdn, rtree, &rtree_ctx,
(((uintptr_t)2) << LG_PAGE)).edata,
(((uintptr_t)2) << LG_PAGE))
.edata,
"Only leftmost rtree leaf should be set; i=%u", i);
rtree_clear(tsdn, rtree, &rtree_ctx, keys[i]);
}
@ -159,8 +167,8 @@ TEST_BEGIN(test_rtree_random) {
/* metadata_use_hooks */ true);
expect_ptr_not_null(base, "Unexpected base_new failure");
uintptr_t keys[NSET];
rtree_t *rtree = &test_rtree;
uintptr_t keys[NSET];
rtree_t *rtree = &test_rtree;
rtree_ctx_t rtree_ctx;
rtree_ctx_data_init(&rtree_ctx);
@ -168,15 +176,15 @@ TEST_BEGIN(test_rtree_random) {
edata_init(edata_d, INVALID_ARENA_IND, NULL, 0, false, SC_NSIZES, 0,
extent_state_active, false, false, EXTENT_PAI_PAC, EXTENT_NOT_HEAD);
expect_false(rtree_new(rtree, base, false),
"Unexpected rtree_new() failure");
expect_false(
rtree_new(rtree, base, false), "Unexpected rtree_new() failure");
for (unsigned i = 0; i < NSET; i++) {
keys[i] = (uintptr_t)gen_rand64(sfmt);
rtree_leaf_elm_t *elm = rtree_leaf_elm_lookup(tsdn, rtree,
&rtree_ctx, keys[i], false, true);
expect_ptr_not_null(elm,
"Unexpected rtree_leaf_elm_lookup() failure");
rtree_leaf_elm_t *elm = rtree_leaf_elm_lookup(
tsdn, rtree, &rtree_ctx, keys[i], false, true);
expect_ptr_not_null(
elm, "Unexpected rtree_leaf_elm_lookup() failure");
rtree_contents_t contents;
contents.edata = edata_d;
contents.metadata.szind = SC_NSIZES;
@ -184,26 +192,27 @@ TEST_BEGIN(test_rtree_random) {
contents.metadata.is_head = false;
contents.metadata.state = edata_state_get(edata_d);
rtree_leaf_elm_write(tsdn, rtree, elm, contents);
expect_ptr_eq(rtree_read(tsdn, rtree, &rtree_ctx,
keys[i]).edata, edata_d,
expect_ptr_eq(
rtree_read(tsdn, rtree, &rtree_ctx, keys[i]).edata, edata_d,
"rtree_edata_read() should return previously set value");
}
for (unsigned i = 0; i < NSET; i++) {
expect_ptr_eq(rtree_read(tsdn, rtree, &rtree_ctx,
keys[i]).edata, edata_d,
expect_ptr_eq(
rtree_read(tsdn, rtree, &rtree_ctx, keys[i]).edata, edata_d,
"rtree_edata_read() should return previously set value, "
"i=%u", i);
"i=%u",
i);
}
for (unsigned i = 0; i < NSET; i++) {
rtree_clear(tsdn, rtree, &rtree_ctx, keys[i]);
expect_ptr_null(rtree_read(tsdn, rtree, &rtree_ctx,
keys[i]).edata,
"rtree_edata_read() should return previously set value");
expect_ptr_null(
rtree_read(tsdn, rtree, &rtree_ctx, keys[i]).edata,
"rtree_edata_read() should return previously set value");
}
for (unsigned i = 0; i < NSET; i++) {
expect_ptr_null(rtree_read(tsdn, rtree, &rtree_ctx,
keys[i]).edata,
expect_ptr_null(
rtree_read(tsdn, rtree, &rtree_ctx, keys[i]).edata,
"rtree_edata_read() should return previously set value");
}
@ -215,8 +224,8 @@ TEST_BEGIN(test_rtree_random) {
TEST_END
static void
test_rtree_range_write(tsdn_t *tsdn, rtree_t *rtree, uintptr_t start,
uintptr_t end) {
test_rtree_range_write(
tsdn_t *tsdn, rtree_t *rtree, uintptr_t start, uintptr_t end) {
rtree_ctx_t rtree_ctx;
rtree_ctx_data_init(&rtree_ctx);
@ -230,15 +239,17 @@ test_rtree_range_write(tsdn_t *tsdn, rtree_t *rtree, uintptr_t start,
contents.metadata.is_head = false;
contents.metadata.state = extent_state_active;
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, start,
contents), "Unexpected rtree_write() failure");
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, end,
contents), "Unexpected rtree_write() failure");
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, start, contents),
"Unexpected rtree_write() failure");
expect_false(rtree_write(tsdn, rtree, &rtree_ctx, end, contents),
"Unexpected rtree_write() failure");
rtree_write_range(tsdn, rtree, &rtree_ctx, start, end, contents);
for (uintptr_t i = 0; i < ((end - start) >> LG_PAGE); i++) {
expect_ptr_eq(rtree_read(tsdn, rtree, &rtree_ctx,
start + (i << LG_PAGE)).edata, edata_e,
expect_ptr_eq(
rtree_read(tsdn, rtree, &rtree_ctx, start + (i << LG_PAGE))
.edata,
edata_e,
"rtree_edata_read() should return previously set value");
}
rtree_clear_range(tsdn, rtree, &rtree_ctx, start, end);
@ -247,8 +258,9 @@ test_rtree_range_write(tsdn_t *tsdn, rtree_t *rtree, uintptr_t start,
elm = rtree_leaf_elm_lookup(tsdn, rtree, &rtree_ctx,
start + (i << LG_PAGE), false, false);
expect_ptr_not_null(elm, "Should have been initialized.");
expect_ptr_null(rtree_leaf_elm_read(tsdn, rtree, elm,
false).edata, "Should have been cleared.");
expect_ptr_null(
rtree_leaf_elm_read(tsdn, rtree, elm, false).edata,
"Should have been cleared.");
}
}
@ -259,8 +271,8 @@ TEST_BEGIN(test_rtree_range) {
expect_ptr_not_null(base, "Unexpected base_new failure");
rtree_t *rtree = &test_rtree;
expect_false(rtree_new(rtree, base, false),
"Unexpected rtree_new() failure");
expect_false(
rtree_new(rtree, base, false), "Unexpected rtree_new() failure");
/* Not crossing rtree node boundary first. */
uintptr_t start = ZU(1) << rtree_leaf_maskbits();
@ -280,10 +292,6 @@ TEST_END
int
main(void) {
return test(
test_rtree_read_empty,
test_rtree_extrema,
test_rtree_bits,
test_rtree_random,
test_rtree_range);
return test(test_rtree_read_empty, test_rtree_extrema, test_rtree_bits,
test_rtree_random, test_rtree_range);
}

View file

@ -8,7 +8,8 @@
*/
bool fake_abort_called;
void fake_abort(const char *message) {
void
fake_abort(const char *message) {
(void)message;
fake_abort_called = true;
}
@ -26,7 +27,7 @@ TEST_BEGIN(test_malloc_free_overflow) {
safety_check_set_abort(&fake_abort);
/* Buffer overflow! */
char* ptr = malloc(128);
char *ptr = malloc(128);
buffer_overflow_write(ptr, 128);
free(ptr);
safety_check_set_abort(NULL);
@ -42,7 +43,7 @@ TEST_BEGIN(test_mallocx_dallocx_overflow) {
safety_check_set_abort(&fake_abort);
/* Buffer overflow! */
char* ptr = mallocx(128, 0);
char *ptr = mallocx(128, 0);
buffer_overflow_write(ptr, 128);
dallocx(ptr, 0);
safety_check_set_abort(NULL);
@ -58,7 +59,7 @@ TEST_BEGIN(test_malloc_sdallocx_overflow) {
safety_check_set_abort(&fake_abort);
/* Buffer overflow! */
char* ptr = malloc(128);
char *ptr = malloc(128);
buffer_overflow_write(ptr, 128);
sdallocx(ptr, 128, 0);
safety_check_set_abort(NULL);
@ -74,7 +75,7 @@ TEST_BEGIN(test_realloc_overflow) {
safety_check_set_abort(&fake_abort);
/* Buffer overflow! */
char* ptr = malloc(128);
char *ptr = malloc(128);
buffer_overflow_write(ptr, 128);
ptr = realloc(ptr, 129);
safety_check_set_abort(NULL);
@ -91,7 +92,7 @@ TEST_BEGIN(test_rallocx_overflow) {
safety_check_set_abort(&fake_abort);
/* Buffer overflow! */
char* ptr = malloc(128);
char *ptr = malloc(128);
buffer_overflow_write(ptr, 128);
ptr = rallocx(ptr, 129, 0);
safety_check_set_abort(NULL);
@ -108,7 +109,7 @@ TEST_BEGIN(test_xallocx_overflow) {
safety_check_set_abort(&fake_abort);
/* Buffer overflow! */
char* ptr = malloc(128);
char *ptr = malloc(128);
buffer_overflow_write(ptr, 128);
size_t result = xallocx(ptr, 129, 0, 0);
expect_zu_eq(result, 128, "");
@ -120,7 +121,7 @@ TEST_BEGIN(test_xallocx_overflow) {
TEST_END
TEST_BEGIN(test_realloc_no_overflow) {
char* ptr = malloc(128);
char *ptr = malloc(128);
ptr = realloc(ptr, 256);
ptr[128] = 0;
ptr[255] = 0;
@ -135,7 +136,7 @@ TEST_BEGIN(test_realloc_no_overflow) {
TEST_END
TEST_BEGIN(test_rallocx_no_overflow) {
char* ptr = malloc(128);
char *ptr = malloc(128);
ptr = rallocx(ptr, 256, 0);
ptr[128] = 0;
ptr[255] = 0;
@ -151,13 +152,8 @@ TEST_END
int
main(void) {
return test(
test_malloc_free_overflow,
test_mallocx_dallocx_overflow,
test_malloc_sdallocx_overflow,
test_realloc_overflow,
test_rallocx_overflow,
test_xallocx_overflow,
test_realloc_no_overflow,
test_rallocx_no_overflow);
return test(test_malloc_free_overflow, test_mallocx_dallocx_overflow,
test_malloc_sdallocx_overflow, test_realloc_overflow,
test_rallocx_overflow, test_xallocx_overflow,
test_realloc_no_overflow, test_rallocx_no_overflow);
}

View file

@ -6,8 +6,8 @@
static void
verify_extent_guarded(tsdn_t *tsdn, void *ptr) {
expect_true(extent_is_guarded(tsdn, ptr),
"All extents should be guarded.");
expect_true(
extent_is_guarded(tsdn, ptr), "All extents should be guarded.");
}
#define MAX_SMALL_ALLOCATIONS 4096
@ -21,13 +21,13 @@ void *small_alloc[MAX_SMALL_ALLOCATIONS];
TEST_BEGIN(test_guarded_small) {
test_skip_if(opt_prof);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
unsigned npages = 16, pages_found = 0, ends_found = 0;
VARIABLE_ARRAY(uintptr_t, pages, npages);
/* Allocate to get sanitized pointers. */
size_t slab_sz = PAGE;
size_t sz = slab_sz / 8;
size_t slab_sz = PAGE;
size_t sz = slab_sz / 8;
unsigned n_alloc = 0;
while (n_alloc < MAX_SMALL_ALLOCATIONS) {
void *ptr = malloc(sz);
@ -54,8 +54,9 @@ TEST_BEGIN(test_guarded_small) {
/* Verify the pages are not continuous, i.e. separated by guards. */
for (unsigned i = 0; i < npages - 1; i++) {
for (unsigned j = i + 1; j < npages; j++) {
uintptr_t ptr_diff = pages[i] > pages[j] ?
pages[i] - pages[j] : pages[j] - pages[i];
uintptr_t ptr_diff = pages[i] > pages[j]
? pages[i] - pages[j]
: pages[j] - pages[i];
expect_zu_ge((size_t)ptr_diff, slab_sz + PAGE,
"There should be at least one pages between "
"guarded slabs");
@ -69,7 +70,7 @@ TEST_BEGIN(test_guarded_small) {
TEST_END
TEST_BEGIN(test_guarded_large) {
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
unsigned nlarge = 32;
VARIABLE_ARRAY(uintptr_t, large, nlarge);
@ -85,8 +86,9 @@ TEST_BEGIN(test_guarded_large) {
/* Verify the pages are not continuous, i.e. separated by guards. */
for (unsigned i = 0; i < nlarge; i++) {
for (unsigned j = i + 1; j < nlarge; j++) {
uintptr_t ptr_diff = large[i] > large[j] ?
large[i] - large[j] : large[j] - large[i];
uintptr_t ptr_diff = large[i] > large[j]
? large[i] - large[j]
: large[j] - large[i];
expect_zu_ge((size_t)ptr_diff, large_sz + 2 * PAGE,
"There should be at least two pages between "
" guarded large allocations");
@ -102,15 +104,13 @@ TEST_END
static void
verify_pdirty(unsigned arena_ind, uint64_t expected) {
uint64_t pdirty = get_arena_pdirty(arena_ind);
expect_u64_eq(pdirty, expected / PAGE,
"Unexpected dirty page amount.");
expect_u64_eq(pdirty, expected / PAGE, "Unexpected dirty page amount.");
}
static void
verify_pmuzzy(unsigned arena_ind, uint64_t expected) {
uint64_t pmuzzy = get_arena_pmuzzy(arena_ind);
expect_u64_eq(pmuzzy, expected / PAGE,
"Unexpected muzzy page amount.");
expect_u64_eq(pmuzzy, expected / PAGE, "Unexpected muzzy page amount.");
}
TEST_BEGIN(test_guarded_decay) {
@ -140,7 +140,7 @@ TEST_BEGIN(test_guarded_decay) {
verify_pmuzzy(arena_ind, 0);
tsdn_t *tsdn = tsd_tsdn(tsd_fetch());
int flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
int flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
/* Should reuse dirty extents for the two mallocx. */
void *p1 = do_mallocx(sz1, flags);
@ -200,8 +200,5 @@ TEST_END
int
main(void) {
return test(
test_guarded_small,
test_guarded_large,
test_guarded_decay);
return test(test_guarded_small, test_guarded_large, test_guarded_decay);
}

View file

@ -16,12 +16,12 @@ TEST_BEGIN(test_san_bump_alloc) {
assert_u_ne(arena_ind, UINT_MAX, "Failed to create an arena");
arena_t *arena = arena_get(tsdn, arena_ind, false);
pac_t *pac = &arena->pa_shard.pac;
pac_t *pac = &arena->pa_shard.pac;
size_t alloc_size = PAGE * 16;
size_t alloc_n = alloc_size / sizeof(unsigned);
edata_t* edata = san_bump_alloc(tsdn, &sba, pac, pac_ehooks_get(pac),
alloc_size, /* zero */ false);
size_t alloc_size = PAGE * 16;
size_t alloc_n = alloc_size / sizeof(unsigned);
edata_t *edata = san_bump_alloc(
tsdn, &sba, pac, pac_ehooks_get(pac), alloc_size, /* zero */ false);
expect_ptr_not_null(edata, "Failed to allocate edata");
expect_u_eq(edata_arena_ind_get(edata), arena_ind,
@ -39,10 +39,10 @@ TEST_BEGIN(test_san_bump_alloc) {
((unsigned *)ptr)[i] = 1;
}
size_t alloc_size2 = PAGE * 28;
size_t alloc_n2 = alloc_size / sizeof(unsigned);
edata_t *edata2 = san_bump_alloc(tsdn, &sba, pac, pac_ehooks_get(pac),
alloc_size2, /* zero */ true);
size_t alloc_size2 = PAGE * 28;
size_t alloc_n2 = alloc_size / sizeof(unsigned);
edata_t *edata2 = san_bump_alloc(
tsdn, &sba, pac, pac_ehooks_get(pac), alloc_size2, /* zero */ true);
expect_ptr_not_null(edata2, "Failed to allocate edata");
expect_u_eq(edata_arena_ind_get(edata2), arena_ind,
@ -57,11 +57,11 @@ TEST_BEGIN(test_san_bump_alloc) {
expect_ptr_not_null(ptr, "Edata was assigned an invalid address");
uintptr_t ptrdiff = ptr2 > ptr ? (uintptr_t)ptr2 - (uintptr_t)ptr
: (uintptr_t)ptr - (uintptr_t)ptr2;
size_t between_allocs = (size_t)ptrdiff - alloc_size;
: (uintptr_t)ptr - (uintptr_t)ptr2;
size_t between_allocs = (size_t)ptrdiff - alloc_size;
expect_zu_ge(between_allocs, PAGE,
"Guard page between allocs is missing");
expect_zu_ge(
between_allocs, PAGE, "Guard page between allocs is missing");
for (unsigned i = 0; i < alloc_n2; ++i) {
expect_u_eq(((unsigned *)ptr2)[i], 0, "Memory is not zeroed");
@ -81,11 +81,11 @@ TEST_BEGIN(test_large_alloc_size) {
assert_u_ne(arena_ind, UINT_MAX, "Failed to create an arena");
arena_t *arena = arena_get(tsdn, arena_ind, false);
pac_t *pac = &arena->pa_shard.pac;
pac_t *pac = &arena->pa_shard.pac;
size_t alloc_size = SBA_RETAINED_ALLOC_SIZE * 2;
edata_t* edata = san_bump_alloc(tsdn, &sba, pac, pac_ehooks_get(pac),
alloc_size, /* zero */ false);
size_t alloc_size = SBA_RETAINED_ALLOC_SIZE * 2;
edata_t *edata = san_bump_alloc(
tsdn, &sba, pac, pac_ehooks_get(pac), alloc_size, /* zero */ false);
expect_u_eq(edata_arena_ind_get(edata), arena_ind,
"Edata was assigned an incorrect arena id");
expect_zu_eq(edata_size_get(edata), alloc_size,
@ -105,7 +105,5 @@ TEST_END
int
main(void) {
return test(
test_san_bump_alloc,
test_large_alloc_size);
return test(test_san_bump_alloc, test_large_alloc_size);
}

View file

@ -4,7 +4,7 @@ TEST_BEGIN(test_update_slab_size) {
sc_data_t data;
memset(&data, 0, sizeof(data));
sc_data_init(&data);
sc_t *tiny = &data.sc[0];
sc_t *tiny = &data.sc[0];
size_t tiny_size = (ZU(1) << tiny->lg_base)
+ (ZU(tiny->ndelta) << tiny->lg_delta);
size_t pgs_too_big = (tiny_size * BITMAP_MAXBITS + PAGE - 1) / PAGE + 1;
@ -13,14 +13,14 @@ TEST_BEGIN(test_update_slab_size) {
sc_data_update_slab_size(&data, 1, 10 * PAGE, 1);
for (int i = 0; i < data.nbins; i++) {
sc_t *sc = &data.sc[i];
sc_t *sc = &data.sc[i];
size_t reg_size = (ZU(1) << sc->lg_base)
+ (ZU(sc->ndelta) << sc->lg_delta);
if (reg_size <= PAGE) {
expect_d_eq(sc->pgs, 1, "Ignored valid page size hint");
} else {
expect_d_gt(sc->pgs, 1,
"Allowed invalid page size hint");
expect_d_gt(
sc->pgs, 1, "Allowed invalid page size hint");
}
}
}
@ -28,6 +28,5 @@ TEST_END
int
main(void) {
return test(
test_update_slab_size);
return test(test_update_slab_size);
}

View file

@ -4,8 +4,8 @@
typedef struct pai_test_allocator_s pai_test_allocator_t;
struct pai_test_allocator_s {
pai_t pai;
bool alloc_fail;
pai_t pai;
bool alloc_fail;
size_t alloc_count;
size_t alloc_batch_count;
size_t dalloc_count;
@ -17,10 +17,10 @@ struct pai_test_allocator_s {
* pointers it gets back; this is mostly just helpful for debugging.
*/
uintptr_t next_ptr;
size_t expand_count;
bool expand_return_value;
size_t shrink_count;
bool shrink_return_value;
size_t expand_count;
bool expand_return_value;
size_t shrink_count;
bool shrink_return_value;
};
static void
@ -82,8 +82,7 @@ pai_test_allocator_alloc_batch(tsdn_t *tsdn, pai_t *self, size_t size,
for (size_t i = 0; i < nallocs; i++) {
edata_t *edata = malloc(sizeof(edata_t));
assert_ptr_not_null(edata, "");
edata_init(edata, /* arena_ind */ 0,
(void *)ta->next_ptr, size,
edata_init(edata, /* arena_ind */ 0, (void *)ta->next_ptr, size,
/* slab */ false, /* szind */ 0, /* sn */ 1,
extent_state_active, /* zero */ false, /* comitted */ true,
/* ranged */ false, EXTENT_NOT_HEAD);
@ -112,8 +111,8 @@ pai_test_allocator_shrink(tsdn_t *tsdn, pai_t *self, edata_t *edata,
}
static void
pai_test_allocator_dalloc(tsdn_t *tsdn, pai_t *self, edata_t *edata,
bool *deferred_work_generated) {
pai_test_allocator_dalloc(
tsdn_t *tsdn, pai_t *self, edata_t *edata, bool *deferred_work_generated) {
pai_test_allocator_t *ta = (pai_test_allocator_t *)self;
ta->dalloc_count++;
free(edata);
@ -174,7 +173,7 @@ TEST_BEGIN(test_reuse) {
enum { NALLOCS = 11 };
edata_t *one_page[NALLOCS];
edata_t *two_page[NALLOCS];
bool deferred_work_generated = false;
bool deferred_work_generated = false;
test_sec_init(&sec, &ta.pai, /* nshards */ 1, /* max_alloc */ 2 * PAGE,
/* max_bytes */ 2 * (NALLOCS * PAGE + NALLOCS * 2 * PAGE));
for (int i = 0; i < NALLOCS; i++) {
@ -189,26 +188,24 @@ TEST_BEGIN(test_reuse) {
}
expect_zu_eq(0, ta.alloc_count, "Should be using batch allocs");
size_t max_allocs = ta.alloc_count + ta.alloc_batch_count;
expect_zu_le(2 * NALLOCS, max_allocs,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count,
"Incorrect number of allocations");
expect_zu_le(
2 * NALLOCS, max_allocs, "Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count, "Incorrect number of allocations");
/*
* Free in a different order than we allocated, to make sure free-list
* separation works correctly.
*/
for (int i = NALLOCS - 1; i >= 0; i--) {
pai_dalloc(tsdn, &sec.pai, one_page[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &sec.pai, one_page[i], &deferred_work_generated);
}
for (int i = NALLOCS - 1; i >= 0; i--) {
pai_dalloc(tsdn, &sec.pai, two_page[i],
&deferred_work_generated);
pai_dalloc(
tsdn, &sec.pai, two_page[i], &deferred_work_generated);
}
expect_zu_eq(max_allocs, ta.alloc_count + ta.alloc_batch_count,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count, "Incorrect number of allocations");
/*
* Check that the n'th most recent deallocated extent is returned for
* the n'th alloc request of a given size.
@ -220,19 +217,15 @@ TEST_BEGIN(test_reuse) {
edata_t *alloc2 = pai_alloc(tsdn, &sec.pai, 2 * PAGE, PAGE,
/* zero */ false, /* guarded */ false, /* frequent_reuse */
false, &deferred_work_generated);
expect_ptr_eq(one_page[i], alloc1,
"Got unexpected allocation");
expect_ptr_eq(two_page[i], alloc2,
"Got unexpected allocation");
expect_ptr_eq(one_page[i], alloc1, "Got unexpected allocation");
expect_ptr_eq(two_page[i], alloc2, "Got unexpected allocation");
}
expect_zu_eq(max_allocs, ta.alloc_count + ta.alloc_batch_count,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count, "Incorrect number of allocations");
}
TEST_END
TEST_BEGIN(test_auto_flush) {
pai_test_allocator_t ta;
pai_test_allocator_init(&ta);
@ -251,7 +244,7 @@ TEST_BEGIN(test_auto_flush) {
enum { NALLOCS = 10 };
edata_t *extra_alloc;
edata_t *allocs[NALLOCS];
bool deferred_work_generated = false;
bool deferred_work_generated = false;
test_sec_init(&sec, &ta.pai, /* nshards */ 1, /* max_alloc */ PAGE,
/* max_bytes */ NALLOCS * PAGE);
for (int i = 0; i < NALLOCS; i++) {
@ -265,18 +258,16 @@ TEST_BEGIN(test_auto_flush) {
&deferred_work_generated);
expect_ptr_not_null(extra_alloc, "Unexpected alloc failure");
size_t max_allocs = ta.alloc_count + ta.alloc_batch_count;
expect_zu_le(NALLOCS + 1, max_allocs,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count,
"Incorrect number of allocations");
expect_zu_le(
NALLOCS + 1, max_allocs, "Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count, "Incorrect number of allocations");
/* Free until the SEC is full, but should not have flushed yet. */
for (int i = 0; i < NALLOCS; i++) {
pai_dalloc(tsdn, &sec.pai, allocs[i], &deferred_work_generated);
}
expect_zu_le(NALLOCS + 1, max_allocs,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count,
"Incorrect number of allocations");
expect_zu_le(
NALLOCS + 1, max_allocs, "Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count, "Incorrect number of allocations");
/*
* Free the extra allocation; this should trigger a flush. The internal
* flushing logic is allowed to get complicated; for now, we rely on our
@ -308,7 +299,7 @@ do_disable_flush_test(bool is_disable) {
enum { NALLOCS = 11 };
edata_t *allocs[NALLOCS];
bool deferred_work_generated = false;
bool deferred_work_generated = false;
test_sec_init(&sec, &ta.pai, /* nshards */ 1, /* max_alloc */ PAGE,
/* max_bytes */ NALLOCS * PAGE);
for (int i = 0; i < NALLOCS; i++) {
@ -324,8 +315,7 @@ do_disable_flush_test(bool is_disable) {
size_t max_allocs = ta.alloc_count + ta.alloc_batch_count;
expect_zu_le(NALLOCS, max_allocs, "Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count,
"Incorrect number of allocations");
expect_zu_eq(0, ta.dalloc_count, "Incorrect number of allocations");
if (is_disable) {
sec_disable(tsdn, &sec);
@ -345,8 +335,8 @@ do_disable_flush_test(bool is_disable) {
* If we free into a disabled SEC, it should forward to the fallback.
* Otherwise, the SEC should accept the allocation.
*/
pai_dalloc(tsdn, &sec.pai, allocs[NALLOCS - 1],
&deferred_work_generated);
pai_dalloc(
tsdn, &sec.pai, allocs[NALLOCS - 1], &deferred_work_generated);
expect_zu_eq(max_allocs, ta.alloc_count + ta.alloc_batch_count,
"Incorrect number of allocations");
@ -382,18 +372,18 @@ TEST_BEGIN(test_max_alloc_respected) {
/* max_bytes */ 1000 * PAGE);
for (size_t i = 0; i < 100; i++) {
expect_zu_eq(i, ta.alloc_count,
"Incorrect number of allocations");
expect_zu_eq(i, ta.dalloc_count,
"Incorrect number of deallocations");
expect_zu_eq(
i, ta.alloc_count, "Incorrect number of allocations");
expect_zu_eq(
i, ta.dalloc_count, "Incorrect number of deallocations");
edata_t *edata = pai_alloc(tsdn, &sec.pai, attempted_alloc,
PAGE, /* zero */ false, /* guarded */ false,
/* frequent_reuse */ false, &deferred_work_generated);
expect_ptr_not_null(edata, "Unexpected alloc failure");
expect_zu_eq(i + 1, ta.alloc_count,
"Incorrect number of allocations");
expect_zu_eq(i, ta.dalloc_count,
"Incorrect number of deallocations");
expect_zu_eq(
i + 1, ta.alloc_count, "Incorrect number of allocations");
expect_zu_eq(
i, ta.dalloc_count, "Incorrect number of deallocations");
pai_dalloc(tsdn, &sec.pai, edata, &deferred_work_generated);
}
}
@ -435,8 +425,8 @@ TEST_BEGIN(test_expand_shrink_delegate) {
expect_false(err, "Unexpected shrink failure");
expect_zu_eq(1, ta.shrink_count, "");
ta.shrink_return_value = true;
err = pai_shrink(tsdn, &sec.pai, edata, 2 * PAGE, PAGE,
&deferred_work_generated);
err = pai_shrink(
tsdn, &sec.pai, edata, 2 * PAGE, PAGE, &deferred_work_generated);
expect_true(err, "Unexpected shrink success");
expect_zu_eq(2, ta.shrink_count, "");
}
@ -455,7 +445,7 @@ TEST_BEGIN(test_nshards_0) {
opts.nshards = 0;
sec_init(TSDN_NULL, &sec, base, &ta.pai, &opts);
bool deferred_work_generated = false;
bool deferred_work_generated = false;
edata_t *edata = pai_alloc(tsdn, &sec.pai, PAGE, PAGE,
/* zero */ false, /* guarded */ false, /* frequent_reuse */ false,
&deferred_work_generated);
@ -570,8 +560,9 @@ TEST_BEGIN(test_stats_auto_flush) {
pai_dalloc(tsdn, &sec.pai, extra_alloc1, &deferred_work_generated);
expect_stats_pages(tsdn, &sec, ta.alloc_count + ta.alloc_batch_count
- ta.dalloc_count - ta.dalloc_batch_count);
expect_stats_pages(tsdn, &sec,
ta.alloc_count + ta.alloc_batch_count - ta.dalloc_count
- ta.dalloc_batch_count);
}
TEST_END
@ -590,7 +581,7 @@ TEST_BEGIN(test_stats_manual_flush) {
test_sec_init(&sec, &ta.pai, /* nshards */ 1, /* max_alloc */ PAGE,
/* max_bytes */ FLUSH_PAGES * PAGE);
bool deferred_work_generated = false;
bool deferred_work_generated = false;
edata_t *allocs[FLUSH_PAGES];
for (size_t i = 0; i < FLUSH_PAGES; i++) {
allocs[i] = pai_alloc(tsdn, &sec.pai, PAGE, PAGE,
@ -621,15 +612,8 @@ TEST_END
int
main(void) {
return test(
test_reuse,
test_auto_flush,
test_disable,
test_flush,
test_max_alloc_respected,
test_expand_shrink_delegate,
test_nshards_0,
test_stats_simple,
test_stats_auto_flush,
return test(test_reuse, test_auto_flush, test_disable, test_flush,
test_max_alloc_respected, test_expand_shrink_delegate,
test_nshards_0, test_stats_simple, test_stats_auto_flush,
test_stats_manual_flush);
}

View file

@ -24,7 +24,7 @@ expect_data(data_t *data) {
seq_define(data_t, data)
typedef struct thd_data_s thd_data_t;
typedef struct thd_data_s thd_data_t;
struct thd_data_s {
seq_data_t data;
};
@ -32,8 +32,8 @@ struct thd_data_s {
static void *
seq_reader_thd(void *arg) {
thd_data_t *thd_data = (thd_data_t *)arg;
int iter = 0;
data_t local_data;
int iter = 0;
data_t local_data;
while (iter < 1000 * 1000 - 1) {
bool success = seq_try_load_data(&local_data, &thd_data->data);
if (success) {
@ -49,7 +49,7 @@ seq_reader_thd(void *arg) {
static void *
seq_writer_thd(void *arg) {
thd_data_t *thd_data = (thd_data_t *)arg;
data_t local_data;
data_t local_data;
memset(&local_data, 0, sizeof(local_data));
for (int i = 0; i < 1000 * 1000; i++) {
set_data(&local_data, i);
@ -74,7 +74,7 @@ TEST_BEGIN(test_seq_threaded) {
TEST_END
TEST_BEGIN(test_seq_simple) {
data_t data;
data_t data;
seq_data_t seq;
memset(&seq, 0, sizeof(seq));
for (int i = 0; i < 1000 * 1000; i++) {
@ -88,8 +88,7 @@ TEST_BEGIN(test_seq_simple) {
}
TEST_END
int main(void) {
return test_no_reentrancy(
test_seq_simple,
test_seq_threaded);
int
main(void) {
return test_no_reentrancy(test_seq_simple, test_seq_threaded);
}

View file

@ -3,7 +3,8 @@
#include "jemalloc/internal/safety_check.h"
bool fake_abort_called;
void fake_abort(const char *message) {
void
fake_abort(const char *message) {
(void)message;
fake_abort_called = true;
}
@ -72,8 +73,7 @@ TEST_END
int
main(void) {
return test(
test_invalid_size_sdallocx,
return test(test_invalid_size_sdallocx,
test_invalid_size_sdallocx_nonzero_flag,
test_invalid_size_sdallocx_noflags);
}

View file

@ -3,12 +3,13 @@
static size_t
get_max_size_class(void) {
unsigned nlextents;
size_t mib[4];
size_t sz, miblen, max_size_class;
size_t mib[4];
size_t sz, miblen, max_size_class;
sz = sizeof(unsigned);
expect_d_eq(mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL,
0), 0, "Unexpected mallctl() error");
expect_d_eq(
mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL, 0), 0,
"Unexpected mallctl() error");
miblen = sizeof(mib) / sizeof(size_t);
expect_d_eq(mallctlnametomib("arenas.lextent.0.size", mib, &miblen), 0,
@ -16,30 +17,34 @@ get_max_size_class(void) {
mib[2] = nlextents - 1;
sz = sizeof(size_t);
expect_d_eq(mallctlbymib(mib, miblen, (void *)&max_size_class, &sz,
NULL, 0), 0, "Unexpected mallctlbymib() error");
expect_d_eq(
mallctlbymib(mib, miblen, (void *)&max_size_class, &sz, NULL, 0), 0,
"Unexpected mallctlbymib() error");
return max_size_class;
}
TEST_BEGIN(test_size_classes) {
size_t size_class, max_size_class;
size_t size_class, max_size_class;
szind_t index, gen_index, max_index;
max_size_class = sz_large_size_classes_disabled()? SC_SMALL_MAXCLASS:
get_max_size_class();
max_size_class = sz_large_size_classes_disabled()
? SC_SMALL_MAXCLASS
: get_max_size_class();
max_index = sz_size2index(max_size_class);
for (index = 0, size_class = sz_index2size(index); index < max_index ||
size_class < max_size_class; index++, size_class =
sz_index2size(index)) {
for (index = 0, size_class = sz_index2size(index);
index < max_index || size_class < max_size_class;
index++, size_class = sz_index2size(index)) {
gen_index = sz_size2index(size_class);
expect_true(index < max_index,
"Loop conditionals should be equivalent; index=%u, "
"size_class=%zu (%#zx)", index, size_class, size_class);
"size_class=%zu (%#zx)",
index, size_class, size_class);
expect_true(size_class < max_size_class,
"Loop conditionals should be equivalent; index=%u, "
"size_class=%zu (%#zx)", index, size_class, size_class);
"size_class=%zu (%#zx)",
index, size_class, size_class);
expect_u_eq(index, gen_index,
"sz_size2index() does not reverse sz_index2size(): index=%u"
@ -51,29 +56,30 @@ TEST_BEGIN(test_size_classes) {
" --> size_class=%zu --> index=%u --> size_class=%zu",
index, size_class, gen_index, sz_index2size(gen_index));
expect_u_eq(index+1, sz_size2index(size_class+1),
expect_u_eq(index + 1, sz_size2index(size_class + 1),
"Next size_class does not round up properly");
expect_zu_eq(size_class, (index > 0) ?
sz_s2u(sz_index2size(index-1)+1) : sz_s2u(1),
expect_zu_eq(size_class,
(index > 0) ? sz_s2u(sz_index2size(index - 1) + 1)
: sz_s2u(1),
"sz_s2u() does not round up to size class");
expect_zu_eq(size_class, sz_s2u(size_class-1),
expect_zu_eq(size_class, sz_s2u(size_class - 1),
"sz_s2u() does not round up to size class");
expect_zu_eq(size_class, sz_s2u(size_class),
"sz_s2u() does not compute same size class");
expect_zu_eq(sz_s2u(size_class+1), sz_index2size(index+1),
expect_zu_eq(sz_s2u(size_class + 1), sz_index2size(index + 1),
"sz_s2u() does not round up to next size class");
}
expect_u_eq(index, sz_size2index(sz_index2size(index)),
"sz_size2index() does not reverse sz_index2size()");
expect_zu_eq(max_size_class, sz_index2size(
sz_size2index(max_size_class)),
expect_zu_eq(max_size_class,
sz_index2size(sz_size2index(max_size_class)),
"sz_index2size() does not reverse sz_size2index()");
expect_zu_eq(size_class, sz_s2u(sz_index2size(index-1)+1),
expect_zu_eq(size_class, sz_s2u(sz_index2size(index - 1) + 1),
"sz_s2u() does not round up to size class");
expect_zu_eq(size_class, sz_s2u(size_class-1),
expect_zu_eq(size_class, sz_s2u(size_class - 1),
"sz_s2u() does not round up to size class");
expect_zu_eq(size_class, sz_s2u(size_class),
"sz_s2u() does not compute same size class");
@ -115,31 +121,33 @@ TEST_BEGIN(test_grow_slow_size_classes) {
TEST_END
TEST_BEGIN(test_psize_classes) {
size_t size_class, max_psz;
size_t size_class, max_psz;
pszind_t pind, max_pind;
max_psz = get_max_size_class() + PAGE;
max_pind = sz_psz2ind(max_psz);
for (pind = 0, size_class = sz_pind2sz(pind);
pind < max_pind || size_class < max_psz;
pind++, size_class = sz_pind2sz(pind)) {
pind < max_pind || size_class < max_psz;
pind++, size_class = sz_pind2sz(pind)) {
expect_true(pind < max_pind,
"Loop conditionals should be equivalent; pind=%u, "
"size_class=%zu (%#zx)", pind, size_class, size_class);
"size_class=%zu (%#zx)",
pind, size_class, size_class);
expect_true(size_class < max_psz,
"Loop conditionals should be equivalent; pind=%u, "
"size_class=%zu (%#zx)", pind, size_class, size_class);
"size_class=%zu (%#zx)",
pind, size_class, size_class);
expect_u_eq(pind, sz_psz2ind(size_class),
"sz_psz2ind() does not reverse sz_pind2sz(): pind=%u -->"
" size_class=%zu --> pind=%u --> size_class=%zu", pind,
size_class, sz_psz2ind(size_class),
" size_class=%zu --> pind=%u --> size_class=%zu",
pind, size_class, sz_psz2ind(size_class),
sz_pind2sz(sz_psz2ind(size_class)));
expect_zu_eq(size_class, sz_pind2sz(sz_psz2ind(size_class)),
"sz_pind2sz() does not reverse sz_psz2ind(): pind=%u -->"
" size_class=%zu --> pind=%u --> size_class=%zu", pind,
size_class, sz_psz2ind(size_class),
" size_class=%zu --> pind=%u --> size_class=%zu",
pind, size_class, sz_psz2ind(size_class),
sz_pind2sz(sz_psz2ind(size_class)));
if (size_class == SC_LARGE_MAXCLASS) {
@ -150,14 +158,15 @@ TEST_BEGIN(test_psize_classes) {
"Next size_class does not round up properly");
}
expect_zu_eq(size_class, (pind > 0) ?
sz_psz2u(sz_pind2sz(pind-1)+1) : sz_psz2u(1),
expect_zu_eq(size_class,
(pind > 0) ? sz_psz2u(sz_pind2sz(pind - 1) + 1)
: sz_psz2u(1),
"sz_psz2u() does not round up to size class");
expect_zu_eq(size_class, sz_psz2u(size_class-1),
expect_zu_eq(size_class, sz_psz2u(size_class - 1),
"sz_psz2u() does not round up to size class");
expect_zu_eq(size_class, sz_psz2u(size_class),
"sz_psz2u() does not compute same size class");
expect_zu_eq(sz_psz2u(size_class+1), sz_pind2sz(pind+1),
expect_zu_eq(sz_psz2u(size_class + 1), sz_pind2sz(pind + 1),
"sz_psz2u() does not round up to next size class");
}
@ -166,9 +175,9 @@ TEST_BEGIN(test_psize_classes) {
expect_zu_eq(max_psz, sz_pind2sz(sz_psz2ind(max_psz)),
"sz_pind2sz() does not reverse sz_psz2ind()");
expect_zu_eq(size_class, sz_psz2u(sz_pind2sz(pind-1)+1),
expect_zu_eq(size_class, sz_psz2u(sz_pind2sz(pind - 1) + 1),
"sz_psz2u() does not round up to size class");
expect_zu_eq(size_class, sz_psz2u(size_class-1),
expect_zu_eq(size_class, sz_psz2u(size_class - 1),
"sz_psz2u() does not round up to size class");
expect_zu_eq(size_class, sz_psz2u(size_class),
"sz_psz2u() does not compute same size class");
@ -181,31 +190,31 @@ TEST_BEGIN(test_overflow) {
max_size_class = get_max_size_class();
max_psz = max_size_class + PAGE;
expect_u_eq(sz_size2index(max_size_class+1), SC_NSIZES,
expect_u_eq(sz_size2index(max_size_class + 1), SC_NSIZES,
"sz_size2index() should return NSIZES on overflow");
expect_u_eq(sz_size2index(ZU(PTRDIFF_MAX)+1), SC_NSIZES,
expect_u_eq(sz_size2index(ZU(PTRDIFF_MAX) + 1), SC_NSIZES,
"sz_size2index() should return NSIZES on overflow");
expect_u_eq(sz_size2index(SIZE_T_MAX), SC_NSIZES,
"sz_size2index() should return NSIZES on overflow");
expect_zu_eq(sz_s2u(max_size_class+1), 0,
expect_zu_eq(sz_s2u(max_size_class + 1), 0,
"sz_s2u() should return 0 for unsupported size");
expect_zu_eq(sz_s2u(ZU(PTRDIFF_MAX)+1), 0,
expect_zu_eq(sz_s2u(ZU(PTRDIFF_MAX) + 1), 0,
"sz_s2u() should return 0 for unsupported size");
expect_zu_eq(sz_s2u(SIZE_T_MAX), 0,
"sz_s2u() should return 0 on overflow");
expect_zu_eq(
sz_s2u(SIZE_T_MAX), 0, "sz_s2u() should return 0 on overflow");
expect_u_eq(sz_psz2ind(max_size_class+1), SC_NPSIZES,
expect_u_eq(sz_psz2ind(max_size_class + 1), SC_NPSIZES,
"sz_psz2ind() should return NPSIZES on overflow");
expect_u_eq(sz_psz2ind(ZU(PTRDIFF_MAX)+1), SC_NPSIZES,
expect_u_eq(sz_psz2ind(ZU(PTRDIFF_MAX) + 1), SC_NPSIZES,
"sz_psz2ind() should return NPSIZES on overflow");
expect_u_eq(sz_psz2ind(SIZE_T_MAX), SC_NPSIZES,
"sz_psz2ind() should return NPSIZES on overflow");
expect_zu_eq(sz_psz2u(max_size_class+1), max_psz,
expect_zu_eq(sz_psz2u(max_size_class + 1), max_psz,
"sz_psz2u() should return (LARGE_MAXCLASS + PAGE) for unsupported"
" size");
expect_zu_eq(sz_psz2u(ZU(PTRDIFF_MAX)+1), max_psz,
expect_zu_eq(sz_psz2u(ZU(PTRDIFF_MAX) + 1), max_psz,
"sz_psz2u() should return (LARGE_MAXCLASS + PAGE) for unsupported "
"size");
expect_zu_eq(sz_psz2u(SIZE_T_MAX), max_psz,
@ -215,9 +224,6 @@ TEST_END
int
main(void) {
return test(
test_size_classes,
test_grow_slow_size_classes,
test_psize_classes,
test_overflow);
return test(test_size_classes, test_grow_slow_size_classes,
test_psize_classes, test_overflow);
}

View file

@ -6,23 +6,22 @@ TEST_BEGIN(test_arena_slab_regind) {
szind_t binind;
for (binind = 0; binind < SC_NBINS; binind++) {
size_t regind;
edata_t slab;
size_t regind;
edata_t slab;
const bin_info_t *bin_info = &bin_infos[binind];
edata_init(&slab, INVALID_ARENA_IND,
mallocx(bin_info->slab_size, MALLOCX_LG_ALIGN(LG_PAGE)),
bin_info->slab_size, true,
binind, 0, extent_state_active, false, true, EXTENT_PAI_PAC,
EXTENT_NOT_HEAD);
expect_ptr_not_null(edata_addr_get(&slab),
"Unexpected malloc() failure");
bin_info->slab_size, true, binind, 0, extent_state_active,
false, true, EXTENT_PAI_PAC, EXTENT_NOT_HEAD);
expect_ptr_not_null(
edata_addr_get(&slab), "Unexpected malloc() failure");
arena_dalloc_bin_locked_info_t dalloc_info;
arena_dalloc_bin_locked_begin(&dalloc_info, binind);
for (regind = 0; regind < bin_info->nregs; regind++) {
void *reg = (void *)((uintptr_t)edata_addr_get(&slab) +
(bin_info->reg_size * regind));
expect_zu_eq(arena_slab_regind(&dalloc_info, binind,
&slab, reg),
void *reg = (void *)((uintptr_t)edata_addr_get(&slab)
+ (bin_info->reg_size * regind));
expect_zu_eq(
arena_slab_regind(&dalloc_info, binind, &slab, reg),
regind,
"Incorrect region index computed for size %zu",
bin_info->reg_size);
@ -34,6 +33,5 @@ TEST_END
int
main(void) {
return test(
test_arena_slab_regind);
return test(test_arena_slab_regind);
}

View file

@ -1,9 +1,8 @@
#include "test/jemalloc_test.h"
static const uint64_t smoothstep_tab[] = {
#define STEP(step, h, x, y) \
h,
SMOOTHSTEP
#define STEP(step, h, x, y) h,
SMOOTHSTEP
#undef STEP
};
@ -23,14 +22,14 @@ TEST_BEGIN(test_smoothstep_integral) {
sum += smoothstep_tab[i];
}
max = (KQU(1) << (SMOOTHSTEP_BFP-1)) * (SMOOTHSTEP_NSTEPS+1);
max = (KQU(1) << (SMOOTHSTEP_BFP - 1)) * (SMOOTHSTEP_NSTEPS + 1);
min = max - SMOOTHSTEP_NSTEPS;
expect_u64_ge(sum, min,
"Integral too small, even accounting for truncation");
expect_u64_ge(
sum, min, "Integral too small, even accounting for truncation");
expect_u64_le(sum, max, "Integral exceeds 1/2");
if (false) {
malloc_printf("%"FMTu64" ulps under 1/2 (limit %d)\n",
malloc_printf("%" FMTu64 " ulps under 1/2 (limit %d)\n",
max - sum, SMOOTHSTEP_NSTEPS);
}
}
@ -52,7 +51,7 @@ TEST_BEGIN(test_smoothstep_monotonic) {
expect_u64_ge(h, prev_h, "Piecewise non-monotonic, i=%u", i);
prev_h = h;
}
expect_u64_eq(smoothstep_tab[SMOOTHSTEP_NSTEPS-1],
expect_u64_eq(smoothstep_tab[SMOOTHSTEP_NSTEPS - 1],
(KQU(1) << SMOOTHSTEP_BFP), "Last step must equal 1");
}
TEST_END
@ -74,19 +73,21 @@ TEST_BEGIN(test_smoothstep_slope) {
uint64_t delta = h - prev_h;
expect_u64_ge(delta, prev_delta,
"Slope must monotonically increase in 0.0 <= x <= 0.5, "
"i=%u", i);
"i=%u",
i);
prev_h = h;
prev_delta = delta;
}
prev_h = KQU(1) << SMOOTHSTEP_BFP;
prev_delta = 0;
for (i = SMOOTHSTEP_NSTEPS-1; i >= SMOOTHSTEP_NSTEPS / 2; i--) {
for (i = SMOOTHSTEP_NSTEPS - 1; i >= SMOOTHSTEP_NSTEPS / 2; i--) {
uint64_t h = smoothstep_tab[i];
uint64_t delta = prev_h - h;
expect_u64_ge(delta, prev_delta,
"Slope must monotonically decrease in 0.5 <= x <= 1.0, "
"i=%u", i);
"i=%u",
i);
prev_h = h;
prev_delta = delta;
}
@ -95,8 +96,6 @@ TEST_END
int
main(void) {
return test(
test_smoothstep_integral,
test_smoothstep_monotonic,
return test(test_smoothstep_integral, test_smoothstep_monotonic,
test_smoothstep_slope);
}

View file

@ -13,6 +13,5 @@ TEST_END
int
main(void) {
return test(
test_spin);
return test(test_spin);
}

View file

@ -4,13 +4,14 @@
#define STRINGIFY(x) STRINGIFY_HELPER(x)
TEST_BEGIN(test_stats_summary) {
size_t sz, allocated, active, resident, mapped,
metadata, metadata_edata, metadata_rtree;
size_t sz, allocated, active, resident, mapped, metadata,
metadata_edata, metadata_rtree;
int expected = config_stats ? 0 : ENOENT;
sz = sizeof(size_t);
expect_d_eq(mallctl("stats.allocated", (void *)&allocated, &sz, NULL,
0), expected, "Unexpected mallctl() result");
expect_d_eq(
mallctl("stats.allocated", (void *)&allocated, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.active", (void *)&active, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.resident", (void *)&resident, &sz, NULL, 0),
@ -21,17 +22,19 @@ TEST_BEGIN(test_stats_summary) {
expect_d_eq(mallctl("stats.metadata", (void *)&metadata, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.metadata_edata", (void *)&metadata_edata,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.metadata_rtree", (void *)&metadata_rtree,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
if (config_stats) {
expect_zu_le(allocated, active,
"allocated should be no larger than active");
expect_zu_lt(active, resident,
"active should be less than resident");
expect_zu_lt(active, mapped,
"active should be less than mapped");
expect_zu_lt(
active, resident, "active should be less than resident");
expect_zu_lt(
active, mapped, "active should be less than mapped");
expect_zu_le(metadata_edata + metadata_rtree, metadata,
"the sum of metadata_edata and metadata_rtree "
"should be no larger than metadata");
@ -40,12 +43,12 @@ TEST_BEGIN(test_stats_summary) {
TEST_END
TEST_BEGIN(test_stats_large) {
void *p;
void *p;
uint64_t epoch;
size_t allocated;
size_t allocated;
uint64_t nmalloc, ndalloc, nrequests;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
p = mallocx(SC_SMALL_MAXCLASS + 1, MALLOCX_ARENA(0));
expect_ptr_not_null(p, "Unexpected mallocx() failure");
@ -55,20 +58,22 @@ TEST_BEGIN(test_stats_large) {
sz = sizeof(size_t);
expect_d_eq(mallctl("stats.arenas.0.large.allocated",
(void *)&allocated, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&allocated, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
expect_d_eq(mallctl("stats.arenas.0.large.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.large.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.large.nrequests",
(void *)&nrequests, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&nrequests, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
if (config_stats) {
expect_zu_gt(allocated, 0,
"allocated should be greater than zero");
expect_zu_gt(
allocated, 0, "allocated should be greater than zero");
expect_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
expect_u64_le(nmalloc, nrequests,
@ -80,18 +85,17 @@ TEST_BEGIN(test_stats_large) {
TEST_END
TEST_BEGIN(test_stats_arenas_summary) {
void *little, *large;
void *little, *large;
uint64_t epoch;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
size_t mapped;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
size_t mapped;
uint64_t dirty_npurge, dirty_nmadvise, dirty_purged;
uint64_t muzzy_npurge, muzzy_nmadvise, muzzy_purged;
little = mallocx(SC_SMALL_MAXCLASS, MALLOCX_ARENA(0));
expect_ptr_not_null(little, "Unexpected mallocx() failure");
large = mallocx((1U << SC_LG_LARGE_MINCLASS),
MALLOCX_ARENA(0));
large = mallocx((1U << SC_LG_LARGE_MINCLASS), MALLOCX_ARENA(0));
expect_ptr_not_null(large, "Unexpected mallocx() failure");
dallocx(little, 0);
@ -106,28 +110,29 @@ TEST_BEGIN(test_stats_arenas_summary) {
0, "Unexpected mallctl() failure");
sz = sizeof(size_t);
expect_d_eq(mallctl("stats.arenas.0.mapped", (void *)&mapped, &sz, NULL,
0), expected, "Unexepected mallctl() result");
expect_d_eq(
mallctl("stats.arenas.0.mapped", (void *)&mapped, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
sz = sizeof(uint64_t);
expect_d_eq(mallctl("stats.arenas.0.dirty_npurge",
(void *)&dirty_npurge, &sz, NULL, 0), expected,
"Unexepected mallctl() result");
(void *)&dirty_npurge, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.dirty_nmadvise",
(void *)&dirty_nmadvise, &sz, NULL, 0), expected,
"Unexepected mallctl() result");
(void *)&dirty_nmadvise, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.dirty_purged",
(void *)&dirty_purged, &sz, NULL, 0), expected,
"Unexepected mallctl() result");
(void *)&dirty_purged, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.muzzy_npurge",
(void *)&muzzy_npurge, &sz, NULL, 0), expected,
"Unexepected mallctl() result");
(void *)&muzzy_npurge, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.muzzy_nmadvise",
(void *)&muzzy_nmadvise, &sz, NULL, 0), expected,
"Unexepected mallctl() result");
(void *)&muzzy_nmadvise, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.muzzy_purged",
(void *)&muzzy_purged, &sz, NULL, 0), expected,
"Unexepected mallctl() result");
(void *)&muzzy_purged, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
if (config_stats) {
if (!is_background_thread_enabled() && !opt_hpa) {
@ -156,10 +161,10 @@ no_lazy_lock(void) {
}
TEST_BEGIN(test_stats_arenas_small) {
void *p;
size_t sz, allocated;
void *p;
size_t sz, allocated;
uint64_t epoch, nmalloc, ndalloc, nrequests;
int expected = config_stats ? 0 : ENOENT;
int expected = config_stats ? 0 : ENOENT;
no_lazy_lock(); /* Lazy locking would dodge tcache testing. */
@ -174,26 +179,28 @@ TEST_BEGIN(test_stats_arenas_small) {
sz = sizeof(size_t);
expect_d_eq(mallctl("stats.arenas.0.small.allocated",
(void *)&allocated, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&allocated, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
expect_d_eq(mallctl("stats.arenas.0.small.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.small.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.small.nrequests",
(void *)&nrequests, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&nrequests, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
if (config_stats) {
expect_zu_gt(allocated, 0,
"allocated should be greater than zero");
expect_u64_gt(nmalloc, 0,
"nmalloc should be no greater than zero");
expect_zu_gt(
allocated, 0, "allocated should be greater than zero");
expect_u64_gt(
nmalloc, 0, "nmalloc should be no greater than zero");
expect_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
expect_u64_gt(nrequests, 0,
"nrequests should be greater than zero");
expect_u64_gt(
nrequests, 0, "nrequests should be greater than zero");
}
dallocx(p, 0);
@ -201,16 +208,16 @@ TEST_BEGIN(test_stats_arenas_small) {
TEST_END
TEST_BEGIN(test_stats_arenas_large) {
void *p;
size_t sz, allocated, allocated_before;
void *p;
size_t sz, allocated, allocated_before;
uint64_t epoch, nmalloc, ndalloc;
size_t malloc_size = (1U << (SC_LG_LARGE_MINCLASS + 1)) + 1;
int expected = config_stats ? 0 : ENOENT;
size_t malloc_size = (1U << (SC_LG_LARGE_MINCLASS + 1)) + 1;
int expected = config_stats ? 0 : ENOENT;
sz = sizeof(size_t);
expect_d_eq(mallctl("stats.arenas.0.large.allocated",
(void *)&allocated_before, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&allocated_before, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
p = mallocx(malloc_size, MALLOCX_ARENA(0));
expect_ptr_not_null(p, "Unexpected mallocx() failure");
@ -219,21 +226,23 @@ TEST_BEGIN(test_stats_arenas_large) {
0, "Unexpected mallctl() failure");
expect_d_eq(mallctl("stats.arenas.0.large.allocated",
(void *)&allocated, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&allocated, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
expect_d_eq(mallctl("stats.arenas.0.large.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.large.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
&sz, NULL, 0),
expected, "Unexpected mallctl() result");
if (config_stats) {
expect_zu_ge(allocated_before, 0,
"allocated should be greater than zero");
expect_zu_ge(allocated - allocated_before, sz_s2u(malloc_size),
"the diff between allocated should be greater than the allocation made");
expect_u64_gt(nmalloc, 0,
"nmalloc should be greater than zero");
expect_u64_gt(
nmalloc, 0, "nmalloc should be greater than zero");
expect_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
}
@ -248,11 +257,11 @@ gen_mallctl_str(char *cmd, char *name, unsigned arena_ind) {
}
TEST_BEGIN(test_stats_arenas_bins) {
void *p;
size_t sz, curslabs, curregs, nonfull_slabs;
void *p;
size_t sz, curslabs, curregs, nonfull_slabs;
uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;
uint64_t nslabs, nreslabs;
int expected = config_stats ? 0 : ENOENT;
int expected = config_stats ? 0 : ENOENT;
/* Make sure allocation below isn't satisfied by tcache. */
expect_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
@ -264,8 +273,8 @@ TEST_BEGIN(test_stats_arenas_bins) {
0, "Arena creation failure");
sz = sizeof(arena_ind);
expect_d_eq(mallctl("thread.arena", (void *)&old_arena_ind, &sz,
(void *)&arena_ind, sizeof(arena_ind)), 0,
"Unexpected mallctl() failure");
(void *)&arena_ind, sizeof(arena_ind)),
0, "Unexpected mallctl() failure");
p = malloc(bin_infos[0].reg_size);
expect_ptr_not_null(p, "Unexpected malloc() failure");
@ -315,26 +324,25 @@ TEST_BEGIN(test_stats_arenas_bins) {
expected, "Unexpected mallctl() result");
if (config_stats) {
expect_u64_gt(nmalloc, 0,
"nmalloc should be greater than zero");
expect_u64_gt(
nmalloc, 0, "nmalloc should be greater than zero");
expect_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
expect_u64_gt(nrequests, 0,
"nrequests should be greater than zero");
expect_zu_gt(curregs, 0,
"allocated should be greater than zero");
expect_u64_gt(
nrequests, 0, "nrequests should be greater than zero");
expect_zu_gt(
curregs, 0, "allocated should be greater than zero");
if (opt_tcache) {
expect_u64_gt(nfills, 0,
"At least one fill should have occurred");
expect_u64_gt(nflushes, 0,
"At least one flush should have occurred");
}
expect_u64_gt(nslabs, 0,
"At least one slab should have been allocated");
expect_u64_gt(
nslabs, 0, "At least one slab should have been allocated");
expect_zu_gt(curslabs, 0,
"At least one slab should be currently allocated");
expect_zu_eq(nonfull_slabs, 0,
"slabs_nonfull should be empty");
expect_zu_eq(nonfull_slabs, 0, "slabs_nonfull should be empty");
}
dallocx(p, 0);
@ -342,14 +350,15 @@ TEST_BEGIN(test_stats_arenas_bins) {
TEST_END
TEST_BEGIN(test_stats_arenas_lextents) {
void *p;
void *p;
uint64_t epoch, nmalloc, ndalloc;
size_t curlextents, sz, hsize;
int expected = config_stats ? 0 : ENOENT;
size_t curlextents, sz, hsize;
int expected = config_stats ? 0 : ENOENT;
sz = sizeof(size_t);
expect_d_eq(mallctl("arenas.lextent.0.size", (void *)&hsize, &sz, NULL,
0), 0, "Unexpected mallctl() failure");
expect_d_eq(
mallctl("arenas.lextent.0.size", (void *)&hsize, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
p = mallocx(hsize, MALLOCX_ARENA(0));
expect_ptr_not_null(p, "Unexpected mallocx() failure");
@ -359,19 +368,19 @@ TEST_BEGIN(test_stats_arenas_lextents) {
sz = sizeof(uint64_t);
expect_d_eq(mallctl("stats.arenas.0.lextents.0.nmalloc",
(void *)&nmalloc, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&nmalloc, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
expect_d_eq(mallctl("stats.arenas.0.lextents.0.ndalloc",
(void *)&ndalloc, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&ndalloc, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
expect_d_eq(mallctl("stats.arenas.0.lextents.0.curlextents",
(void *)&curlextents, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
(void *)&curlextents, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
if (config_stats) {
expect_u64_gt(nmalloc, 0,
"nmalloc should be greater than zero");
expect_u64_gt(
nmalloc, 0, "nmalloc should be greater than zero");
expect_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
expect_u64_gt(curlextents, 0,
@ -385,35 +394,37 @@ TEST_END
static void
test_tcache_bytes_for_usize(size_t usize) {
uint64_t epoch;
size_t tcache_bytes, tcache_stashed_bytes;
size_t sz = sizeof(tcache_bytes);
size_t tcache_bytes, tcache_stashed_bytes;
size_t sz = sizeof(tcache_bytes);
void *ptr = mallocx(usize, 0);
expect_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl(
"stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL) ".tcache_bytes",
&tcache_bytes, &sz, NULL, 0), 0, "Unexpected mallctl failure");
assert_d_eq(mallctl(
"stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL)
".tcache_stashed_bytes", &tcache_stashed_bytes, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
assert_d_eq(mallctl("stats.arenas." STRINGIFY(
MALLCTL_ARENAS_ALL) ".tcache_bytes",
&tcache_bytes, &sz, NULL, 0),
0, "Unexpected mallctl failure");
assert_d_eq(mallctl("stats.arenas." STRINGIFY(
MALLCTL_ARENAS_ALL) ".tcache_stashed_bytes",
&tcache_stashed_bytes, &sz, NULL, 0),
0, "Unexpected mallctl failure");
size_t tcache_bytes_before = tcache_bytes + tcache_stashed_bytes;
dallocx(ptr, 0);
expect_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl(
"stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL) ".tcache_bytes",
&tcache_bytes, &sz, NULL, 0), 0, "Unexpected mallctl failure");
assert_d_eq(mallctl(
"stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL)
".tcache_stashed_bytes", &tcache_stashed_bytes, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
assert_d_eq(mallctl("stats.arenas." STRINGIFY(
MALLCTL_ARENAS_ALL) ".tcache_bytes",
&tcache_bytes, &sz, NULL, 0),
0, "Unexpected mallctl failure");
assert_d_eq(mallctl("stats.arenas." STRINGIFY(
MALLCTL_ARENAS_ALL) ".tcache_stashed_bytes",
&tcache_stashed_bytes, &sz, NULL, 0),
0, "Unexpected mallctl failure");
size_t tcache_bytes_after = tcache_bytes + tcache_stashed_bytes;
assert_zu_eq(tcache_bytes_after - tcache_bytes_before,
usize, "Incorrectly attributed a free");
assert_zu_eq(tcache_bytes_after - tcache_bytes_before, usize,
"Incorrectly attributed a free");
}
TEST_BEGIN(test_stats_tcache_bytes_small) {
@ -436,14 +447,9 @@ TEST_END
int
main(void) {
return test_no_reentrancy(
test_stats_summary,
test_stats_large,
test_stats_arenas_summary,
test_stats_arenas_small,
test_stats_arenas_large,
test_stats_arenas_bins,
test_stats_arenas_lextents,
test_stats_tcache_bytes_small,
return test_no_reentrancy(test_stats_summary, test_stats_large,
test_stats_arenas_summary, test_stats_arenas_small,
test_stats_arenas_large, test_stats_arenas_bins,
test_stats_arenas_lextents, test_stats_tcache_bytes_small,
test_stats_tcache_bytes_large);
}

File diff suppressed because it is too large Load diff

View file

@ -10,8 +10,8 @@ TEST_BEGIN(test_sz_psz2ind) {
for (size_t i = 0; i < SC_NGROUP; i++) {
for (size_t psz = i * PAGE + 1; psz <= (i + 1) * PAGE; psz++) {
pszind_t ind = sz_psz2ind(psz);
expect_zu_eq(ind, i, "Got %u as sz_psz2ind of %zu", ind,
psz);
expect_zu_eq(
ind, i, "Got %u as sz_psz2ind of %zu", ind, psz);
}
}
@ -25,15 +25,14 @@ TEST_BEGIN(test_sz_psz2ind) {
*/
size_t base_psz = 1 << (SC_LG_NGROUP + LG_PAGE);
size_t base_ind = 0;
while (base_ind < SC_NSIZES &&
reg_size_compute(data.sc[base_ind].lg_base,
data.sc[base_ind].lg_delta,
data.sc[base_ind].ndelta) < base_psz) {
while (base_ind < SC_NSIZES
&& reg_size_compute(data.sc[base_ind].lg_base,
data.sc[base_ind].lg_delta, data.sc[base_ind].ndelta)
< base_psz) {
base_ind++;
}
expect_zu_eq(
reg_size_compute(data.sc[base_ind].lg_base,
data.sc[base_ind].lg_delta, data.sc[base_ind].ndelta),
expect_zu_eq(reg_size_compute(data.sc[base_ind].lg_base,
data.sc[base_ind].lg_delta, data.sc[base_ind].ndelta),
base_psz, "Size class equal to %zu not found", base_psz);
/*
* Test different sizes falling into groups after the 'base'. The
@ -42,21 +41,21 @@ TEST_BEGIN(test_sz_psz2ind) {
base_ind -= SC_NGROUP;
for (size_t psz = base_psz; psz <= 64 * 1024 * 1024; psz += PAGE / 3) {
pszind_t ind = sz_psz2ind(psz);
sc_t gt_sc = data.sc[ind + base_ind];
sc_t gt_sc = data.sc[ind + base_ind];
expect_zu_gt(psz,
reg_size_compute(gt_sc.lg_base, gt_sc.lg_delta,
gt_sc.ndelta),
reg_size_compute(
gt_sc.lg_base, gt_sc.lg_delta, gt_sc.ndelta),
"Got %u as sz_psz2ind of %zu", ind, psz);
sc_t le_sc = data.sc[ind + base_ind + 1];
expect_zu_le(psz,
reg_size_compute(le_sc.lg_base, le_sc.lg_delta,
le_sc.ndelta),
reg_size_compute(
le_sc.lg_base, le_sc.lg_delta, le_sc.ndelta),
"Got %u as sz_psz2ind of %zu", ind, psz);
}
pszind_t max_ind = sz_psz2ind(SC_LARGE_MAXCLASS + 1);
expect_lu_eq(max_ind, SC_NPSIZES,
"Got %u as sz_psz2ind of %llu", max_ind, SC_LARGE_MAXCLASS);
expect_lu_eq(max_ind, SC_NPSIZES, "Got %u as sz_psz2ind of %llu",
max_ind, SC_LARGE_MAXCLASS);
}
TEST_END

View file

@ -69,8 +69,8 @@ tcache_bytes_read_global(void) {
static size_t
tcache_bytes_read_local(void) {
size_t tcache_bytes = 0;
tsd_t *tsd = tsd_fetch();
size_t tcache_bytes = 0;
tsd_t *tsd = tsd_fetch();
tcache_t *tcache = tcache_get(tsd);
for (szind_t i = 0; i < tcache_nbins_get(tcache->tcache_slow); i++) {
cache_bin_t *cache_bin = &tcache->bins[i];
@ -98,7 +98,7 @@ test_tcache_bytes_alloc(size_t alloc_size, size_t tcache_max,
size_t usize = sz_s2u(alloc_size);
/* No change is expected if usize is outside of tcache_max range. */
bool cached = (usize <= tcache_max);
bool cached = (usize <= tcache_max);
ssize_t diff = cached ? usize : 0;
void *ptr1 = alloc_func(alloc_size, alloc_option);
@ -186,7 +186,7 @@ TEST_BEGIN(test_tcache_max) {
test_skip_if(san_uaf_detection_enabled());
unsigned arena_ind, alloc_option, dalloc_option;
size_t sz = sizeof(arena_ind);
size_t sz = sizeof(arena_ind);
expect_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz, NULL, 0),
0, "Unexpected mallctl() failure");
expect_d_eq(
@ -215,12 +215,12 @@ static void
validate_tcache_stack(tcache_t *tcache) {
/* Assume bins[0] is enabled. */
void *tcache_stack = tcache->bins[0].stack_head;
bool expect_found = cache_bin_stack_use_thp() ? true : false;
bool expect_found = cache_bin_stack_use_thp() ? true : false;
/* Walk through all blocks to see if the stack is within range. */
base_t *base = b0get();
base_t *base = b0get();
base_block_t *next = base->blocks;
bool found = false;
bool found = false;
do {
base_block_t *block = next;
if ((byte_t *)tcache_stack >= (byte_t *)block
@ -237,10 +237,10 @@ validate_tcache_stack(tcache_t *tcache) {
static void *
tcache_check(void *arg) {
size_t old_tcache_max, new_tcache_max, min_tcache_max, sz;
unsigned tcache_nbins;
tsd_t *tsd = tsd_fetch();
tcache_t *tcache = tsd_tcachep_get(tsd);
size_t old_tcache_max, new_tcache_max, min_tcache_max, sz;
unsigned tcache_nbins;
tsd_t *tsd = tsd_fetch();
tcache_t *tcache = tsd_tcachep_get(tsd);
tcache_slow_t *tcache_slow = tcache->tcache_slow;
sz = sizeof(size_t);
new_tcache_max = *(size_t *)arg;
@ -263,7 +263,7 @@ tcache_check(void *arg) {
* Test an input that is not a valid size class, it should be ceiled
* to a valid size class.
*/
bool e0 = false, e1;
bool e0 = false, e1;
size_t bool_sz = sizeof(bool);
expect_d_eq(mallctl("thread.tcache.enabled", (void *)&e1, &bool_sz,
(void *)&e0, bool_sz),

View file

@ -32,7 +32,5 @@ TEST_END
int
main(void) {
return test(
unhooked_call,
hooked_call);
return test(unhooked_call, hooked_call);
}

View file

@ -1,20 +1,17 @@
#include "test/jemalloc_test.h"
static uint32_t nuser_hook_calls;
static bool is_registered = false;
static bool is_registered = false;
static void
test_cb(bool is_alloc, uint64_t tallocated, uint64_t tdallocated) {
++nuser_hook_calls;
}
static user_hook_object_t tobj = {
.callback = &test_cb,
.interval = 10,
.is_alloc_only = false
};
.callback = &test_cb, .interval = 10, .is_alloc_only = false};
TEST_BEGIN(test_next_event_fast) {
tsd_t *tsd = tsd_fetch();
tsd_t *tsd = tsd_fetch();
te_ctx_t ctx;
te_ctx_get(tsd, &ctx, true);
@ -23,7 +20,8 @@ TEST_BEGIN(test_next_event_fast) {
te_ctx_next_event_set(tsd, &ctx, TE_NEXT_EVENT_FAST_MAX);
if (!is_registered) {
is_registered = 0 == te_register_user_handler(tsd_tsdn(tsd), &tobj);
is_registered = 0
== te_register_user_handler(tsd_tsdn(tsd), &tobj);
}
assert_true(is_registered || !config_stats, "Register user handler");
nuser_hook_calls = 0;
@ -35,7 +33,8 @@ TEST_BEGIN(test_next_event_fast) {
/* Test next_event_fast rolling back to 0. */
void *p = malloc(16U);
assert_true(nuser_hook_calls == 1 || !config_stats, "Expected alloc call");
assert_true(
nuser_hook_calls == 1 || !config_stats, "Expected alloc call");
assert_ptr_not_null(p, "malloc() failed");
free(p);
@ -48,6 +47,5 @@ TEST_END
int
main(void) {
return test(
test_next_event_fast);
return test(test_next_event_fast);
}

View file

@ -6,7 +6,7 @@ TEST_BEGIN(test_ticker_tick) {
#define NREPS 2
#define NTICKS 3
ticker_t ticker;
int32_t i, j;
int32_t i, j;
ticker_init(&ticker, NTICKS);
for (i = 0; i < NREPS; i++) {
@ -16,12 +16,12 @@ TEST_BEGIN(test_ticker_tick) {
expect_false(ticker_tick(&ticker, false),
"Unexpected ticker fire (i=%d, j=%d)", i, j);
}
expect_u32_eq(ticker_read(&ticker), 0,
"Expected ticker depletion");
expect_u32_eq(
ticker_read(&ticker), 0, "Expected ticker depletion");
expect_true(ticker_tick(&ticker, false),
"Expected ticker fire (i=%d)", i);
expect_u32_eq(ticker_read(&ticker), NTICKS,
"Expected ticker reset");
expect_u32_eq(
ticker_read(&ticker), NTICKS, "Expected ticker reset");
}
#undef NTICKS
}
@ -34,15 +34,15 @@ TEST_BEGIN(test_ticker_ticks) {
ticker_init(&ticker, NTICKS);
expect_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
expect_false(ticker_ticks(&ticker, NTICKS, false),
"Unexpected ticker fire");
expect_false(
ticker_ticks(&ticker, NTICKS, false), "Unexpected ticker fire");
expect_u_eq(ticker_read(&ticker), 0, "Unexpected ticker value");
expect_true(ticker_ticks(&ticker, NTICKS, false),
"Expected ticker fire");
expect_true(
ticker_ticks(&ticker, NTICKS, false), "Expected ticker fire");
expect_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
expect_true(ticker_ticks(&ticker, NTICKS + 1, false),
"Expected ticker fire");
expect_true(
ticker_ticks(&ticker, NTICKS + 1, false), "Expected ticker fire");
expect_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
#undef NTICKS
}
@ -55,8 +55,8 @@ TEST_BEGIN(test_ticker_copy) {
ticker_init(&ta, NTICKS);
ticker_copy(&tb, &ta);
expect_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
expect_true(ticker_ticks(&tb, NTICKS + 1, false),
"Expected ticker fire");
expect_true(
ticker_ticks(&tb, NTICKS + 1, false), "Expected ticker fire");
expect_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
ticker_tick(&ta, false);
@ -69,7 +69,7 @@ TEST_BEGIN(test_ticker_copy) {
TEST_END
TEST_BEGIN(test_ticker_geom) {
const int32_t ticks = 100;
const int32_t ticks = 100;
const uint64_t niters = 100 * 1000;
ticker_geom_t ticker;
@ -78,7 +78,7 @@ TEST_BEGIN(test_ticker_geom) {
/* Just some random constant. */
uint64_t prng_state = 0x343219f93496db9fULL;
for (uint64_t i = 0; i < niters; i++) {
while(!ticker_geom_tick(&ticker, &prng_state, false)) {
while (!ticker_geom_tick(&ticker, &prng_state, false)) {
total_ticks++;
}
}
@ -87,15 +87,15 @@ TEST_BEGIN(test_ticker_geom) {
* used at the time this was tested, total_ticks is 95.1% of the
* expected ticks.
*/
expect_u64_ge(total_ticks , niters * ticks * 9 / 10,
"Mean off by > 10%%");
expect_u64_le(total_ticks , niters * ticks * 11 / 10,
"Mean off by > 10%%");
expect_u64_ge(
total_ticks, niters * ticks * 9 / 10, "Mean off by > 10%%");
expect_u64_le(
total_ticks, niters * ticks * 11 / 10, "Mean off by > 10%%");
}
TEST_END
TEST_BEGIN(test_ticker_delay) {
const int32_t ticks = 1000;
const int32_t ticks = 1000;
const uint64_t niters = 10000;
ticker_t t1;
@ -120,22 +120,19 @@ TEST_BEGIN(test_ticker_delay) {
expect_false(ticker_geom_tick(&t2, &prng_state, delay),
"Unexpected ticker fire");
expect_d_eq(ticker_read(&t1), 0, "Unexpected ticker value");
expect_d_eq(ticker_geom_read(&t2), 0, "Unexpected ticker value");
expect_d_eq(
ticker_geom_read(&t2), 0, "Unexpected ticker value");
}
delay = false;
expect_true(ticker_tick(&t1, delay), "Expected ticker fire");
expect_true(ticker_geom_tick(&t2, &prng_state, delay),
"Expected ticker fire");
expect_true(
ticker_geom_tick(&t2, &prng_state, delay), "Expected ticker fire");
}
TEST_END
int
main(void) {
return test(
test_ticker_tick,
test_ticker_ticks,
test_ticker_copy,
test_ticker_geom,
test_ticker_delay);
return test(test_ticker_tick, test_ticker_ticks, test_ticker_copy,
test_ticker_geom, test_ticker_delay);
}

View file

@ -5,7 +5,7 @@
* be asserting that we're on one.
*/
static bool originally_fast;
static int data_cleanup_count;
static int data_cleanup_count;
void
data_cleanup(int *data) {
@ -45,7 +45,7 @@ data_cleanup(int *data) {
static void *
thd_start(void *arg) {
int d = (int)(uintptr_t)arg;
int d = (int)(uintptr_t)arg;
void *p;
/*
@ -105,11 +105,10 @@ thd_start_reincarnated(void *arg) {
expect_ptr_not_null(p, "Unexpected malloc() failure");
/* Manually trigger reincarnation. */
expect_ptr_not_null(tsd_arena_get(tsd),
"Should have tsd arena set.");
expect_ptr_not_null(tsd_arena_get(tsd), "Should have tsd arena set.");
tsd_cleanup((void *)tsd);
expect_ptr_null(*tsd_arenap_get_unsafe(tsd),
"TSD arena should have been cleared.");
expect_ptr_null(
*tsd_arenap_get_unsafe(tsd), "TSD arena should have been cleared.");
expect_u_eq(tsd_state_get(tsd), tsd_state_purgatory,
"TSD state should be purgatory\n");
@ -193,7 +192,7 @@ TEST_END
typedef struct {
atomic_u32_t phase;
atomic_b_t error;
atomic_b_t error;
} global_slow_data_t;
static void *
@ -207,8 +206,8 @@ thd_start_global_slow(void *arg) {
* No global slowness has happened yet; there was an error if we were
* originally fast but aren't now.
*/
atomic_store_b(&data->error, originally_fast && !tsd_fast(tsd),
ATOMIC_SEQ_CST);
atomic_store_b(
&data->error, originally_fast && !tsd_fast(tsd), ATOMIC_SEQ_CST);
atomic_store_u32(&data->phase, 1, ATOMIC_SEQ_CST);
/* PHASE 2 */
@ -241,8 +240,8 @@ thd_start_global_slow(void *arg) {
* Both decrements happened; we should be fast again (if we ever
* were)
*/
atomic_store_b(&data->error, originally_fast && !tsd_fast(tsd),
ATOMIC_SEQ_CST);
atomic_store_b(
&data->error, originally_fast && !tsd_fast(tsd), ATOMIC_SEQ_CST);
atomic_store_u32(&data->phase, 9, ATOMIC_SEQ_CST);
return NULL;
@ -321,10 +320,7 @@ main(void) {
return test_status_fail;
}
return test_no_reentrancy(
test_tsd_main_thread,
test_tsd_sub_thread,
test_tsd_sub_thread_dalloc_only,
test_tsd_reincarnation,
return test_no_reentrancy(test_tsd_main_thread, test_tsd_sub_thread,
test_tsd_sub_thread_dalloc_only, test_tsd_reincarnation,
test_tsd_global_slow);
}

View file

@ -11,7 +11,8 @@ const char *malloc_conf = TEST_SAN_UAF_ALIGN_ENABLE;
static size_t san_uaf_align;
static bool fake_abort_called;
void fake_abort(const char *message) {
void
fake_abort(const char *message) {
(void)message;
fake_abort_called = true;
}
@ -24,8 +25,8 @@ test_write_after_free_pre(void) {
static void
test_write_after_free_post(void) {
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
0, "Unexpected tcache flush failure");
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0), 0,
"Unexpected tcache flush failure");
expect_true(fake_abort_called, "Use-after-free check didn't fire.");
safety_check_set_abort(NULL);
}
@ -37,9 +38,10 @@ uaf_detection_enabled(void) {
}
ssize_t lg_san_uaf_align;
size_t sz = sizeof(lg_san_uaf_align);
assert_d_eq(mallctl("opt.lg_san_uaf_align", &lg_san_uaf_align, &sz,
NULL, 0), 0, "Unexpected mallctl failure");
size_t sz = sizeof(lg_san_uaf_align);
assert_d_eq(
mallctl("opt.lg_san_uaf_align", &lg_san_uaf_align, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
if (lg_san_uaf_align < 0) {
return false;
}
@ -48,8 +50,9 @@ uaf_detection_enabled(void) {
bool tcache_enabled;
sz = sizeof(tcache_enabled);
assert_d_eq(mallctl("thread.tcache.enabled", &tcache_enabled, &sz, NULL,
0), 0, "Unexpected mallctl failure");
assert_d_eq(
mallctl("thread.tcache.enabled", &tcache_enabled, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
if (!tcache_enabled) {
return false;
}
@ -69,10 +72,10 @@ read_tcache_stashed_bytes(unsigned arena_ind) {
size_t tcache_stashed_bytes;
size_t sz = sizeof(tcache_stashed_bytes);
assert_d_eq(mallctl(
"stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL)
".tcache_stashed_bytes", &tcache_stashed_bytes, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
assert_d_eq(mallctl("stats.arenas." STRINGIFY(
MALLCTL_ARENAS_ALL) ".tcache_stashed_bytes",
&tcache_stashed_bytes, &sz, NULL, 0),
0, "Unexpected mallctl failure");
return tcache_stashed_bytes;
}
@ -91,17 +94,17 @@ test_use_after_free(size_t alloc_size, bool write_after_free) {
* make use-after-free tolerable.
*/
unsigned arena_ind = do_arena_create(-1, -1);
int flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
int flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
size_t n_max = san_uaf_align * 2;
void **items = mallocx(n_max * sizeof(void *), flags);
assert_ptr_not_null(items, "Unexpected mallocx failure");
bool found = false;
bool found = false;
size_t iter = 0;
char magic = 's';
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
0, "Unexpected tcache flush failure");
char magic = 's';
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0), 0,
"Unexpected tcache flush failure");
while (!found) {
ptr = mallocx(alloc_size, flags);
assert_ptr_not_null(ptr, "Unexpected mallocx failure");
@ -194,7 +197,7 @@ static bool
check_allocated_intact(void **allocated, size_t n_alloc) {
for (unsigned i = 0; i < n_alloc; i++) {
void *ptr = *(void **)allocated[i];
bool found = false;
bool found = false;
for (unsigned j = 0; j < n_alloc; j++) {
if (ptr == allocated[j]) {
found = true;
@ -213,7 +216,7 @@ TEST_BEGIN(test_use_after_free_integration) {
test_skip_if(!uaf_detection_enabled());
unsigned arena_ind = do_arena_create(-1, -1);
int flags = MALLOCX_ARENA(arena_ind);
int flags = MALLOCX_ARENA(arena_ind);
size_t n_alloc = san_uaf_align * 2;
void **allocated = mallocx(n_alloc * sizeof(void *), flags);
@ -255,8 +258,6 @@ TEST_END
int
main(void) {
return test(
test_read_after_free,
test_write_after_free,
return test(test_read_after_free, test_write_after_free,
test_use_after_free_integration);
}

View file

@ -1,9 +1,9 @@
#include "test/jemalloc_test.h"
static witness_lock_error_t *witness_lock_error_orig;
static witness_owner_error_t *witness_owner_error_orig;
static witness_lock_error_t *witness_lock_error_orig;
static witness_owner_error_t *witness_owner_error_orig;
static witness_not_owner_error_t *witness_not_owner_error_orig;
static witness_depth_error_t *witness_depth_error_orig;
static witness_depth_error_t *witness_depth_error_orig;
static bool saw_lock_error;
static bool saw_owner_error;
@ -11,8 +11,8 @@ static bool saw_not_owner_error;
static bool saw_depth_error;
static void
witness_lock_error_intercept(const witness_list_t *witnesses,
const witness_t *witness) {
witness_lock_error_intercept(
const witness_list_t *witnesses, const witness_t *witness) {
saw_lock_error = true;
}
@ -43,8 +43,8 @@ witness_comp(const witness_t *a, void *oa, const witness_t *b, void *ob) {
}
static int
witness_comp_reverse(const witness_t *a, void *oa, const witness_t *b,
void *ob) {
witness_comp_reverse(
const witness_t *a, void *oa, const witness_t *b, void *ob) {
expect_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
assert(oa == (void *)a);
@ -54,8 +54,8 @@ witness_comp_reverse(const witness_t *a, void *oa, const witness_t *b,
}
TEST_BEGIN(test_witness) {
witness_t a, b;
witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
witness_t a, b;
witness_tsdn_t witness_tsdn = {WITNESS_TSD_INITIALIZER};
test_skip_if(!config_debug);
@ -94,8 +94,8 @@ TEST_BEGIN(test_witness) {
TEST_END
TEST_BEGIN(test_witness_comp) {
witness_t a, b, c, d;
witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
witness_t a, b, c, d;
witness_tsdn_t witness_tsdn = {WITNESS_TSD_INITIALIZER};
test_skip_if(!config_debug);
@ -146,8 +146,8 @@ TEST_BEGIN(test_witness_comp) {
TEST_END
TEST_BEGIN(test_witness_reversal) {
witness_t a, b;
witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
witness_t a, b;
witness_tsdn_t witness_tsdn = {WITNESS_TSD_INITIALIZER};
test_skip_if(!config_debug);
@ -177,8 +177,8 @@ TEST_BEGIN(test_witness_reversal) {
TEST_END
TEST_BEGIN(test_witness_recursive) {
witness_t a;
witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
witness_t a;
witness_tsdn_t witness_tsdn = {WITNESS_TSD_INITIALIZER};
test_skip_if(!config_debug);
@ -207,13 +207,12 @@ TEST_BEGIN(test_witness_recursive) {
witness_owner_error = witness_owner_error_orig;
witness_lock_error = witness_lock_error_orig;
}
TEST_END
TEST_BEGIN(test_witness_unlock_not_owned) {
witness_t a;
witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
witness_t a;
witness_tsdn_t witness_tsdn = {WITNESS_TSD_INITIALIZER};
test_skip_if(!config_debug);
@ -236,8 +235,8 @@ TEST_BEGIN(test_witness_unlock_not_owned) {
TEST_END
TEST_BEGIN(test_witness_depth) {
witness_t a;
witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
witness_t a;
witness_tsdn_t witness_tsdn = {WITNESS_TSD_INITIALIZER};
test_skip_if(!config_debug);
@ -270,11 +269,7 @@ TEST_END
int
main(void) {
return test(
test_witness,
test_witness_comp,
test_witness_reversal,
test_witness_recursive,
test_witness_unlock_not_owned,
return test(test_witness, test_witness_comp, test_witness_reversal,
test_witness_recursive, test_witness_unlock_not_owned,
test_witness_depth);
}

View file

@ -3,35 +3,35 @@
static void
test_zero(size_t sz_min, size_t sz_max) {
uint8_t *s;
size_t sz_prev, sz, i;
#define MAGIC ((uint8_t)0x61)
size_t sz_prev, sz, i;
#define MAGIC ((uint8_t)0x61)
sz_prev = 0;
s = (uint8_t *)mallocx(sz_min, 0);
expect_ptr_not_null((void *)s, "Unexpected mallocx() failure");
for (sz = sallocx(s, 0); sz <= sz_max;
sz_prev = sz, sz = sallocx(s, 0)) {
sz_prev = sz, sz = sallocx(s, 0)) {
if (sz_prev > 0) {
expect_u_eq(s[0], MAGIC,
"Previously allocated byte %zu/%zu is corrupted",
ZU(0), sz_prev);
expect_u_eq(s[sz_prev-1], MAGIC,
expect_u_eq(s[sz_prev - 1], MAGIC,
"Previously allocated byte %zu/%zu is corrupted",
sz_prev-1, sz_prev);
sz_prev - 1, sz_prev);
}
for (i = sz_prev; i < sz; i++) {
expect_u_eq(s[i], 0x0,
"Newly allocated byte %zu/%zu isn't zero-filled",
i, sz);
"Newly allocated byte %zu/%zu isn't zero-filled", i,
sz);
s[i] = MAGIC;
}
if (xallocx(s, sz+1, 0, 0) == sz) {
s = (uint8_t *)rallocx(s, sz+1, 0);
expect_ptr_not_null((void *)s,
"Unexpected rallocx() failure");
if (xallocx(s, sz + 1, 0, 0) == sz) {
s = (uint8_t *)rallocx(s, sz + 1, 0);
expect_ptr_not_null(
(void *)s, "Unexpected rallocx() failure");
}
}
@ -53,7 +53,5 @@ TEST_END
int
main(void) {
return test(
test_zero_small,
test_zero_large);
return test(test_zero_small, test_zero_large);
}

View file

@ -4,7 +4,8 @@
static bool abort_called = false;
void set_abort_called(const char *message) {
void
set_abort_called(const char *message) {
(void)message;
abort_called = true;
};
@ -21,7 +22,5 @@ TEST_END
int
main(void) {
return test(
test_realloc_abort);
return test(test_realloc_abort);
}

View file

@ -6,9 +6,10 @@ allocated(void) {
return 0;
}
uint64_t allocated;
size_t sz = sizeof(allocated);
expect_d_eq(mallctl("thread.allocated", (void *)&allocated, &sz, NULL,
0), 0, "Unexpected mallctl failure");
size_t sz = sizeof(allocated);
expect_d_eq(
mallctl("thread.allocated", (void *)&allocated, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
return allocated;
}
@ -18,9 +19,10 @@ deallocated(void) {
return 0;
}
uint64_t deallocated;
size_t sz = sizeof(deallocated);
expect_d_eq(mallctl("thread.deallocated", (void *)&deallocated, &sz,
NULL, 0), 0, "Unexpected mallctl failure");
size_t sz = sizeof(deallocated);
expect_d_eq(
mallctl("thread.deallocated", (void *)&deallocated, &sz, NULL, 0),
0, "Unexpected mallctl failure");
return deallocated;
}
@ -43,6 +45,5 @@ TEST_BEGIN(test_realloc_alloc) {
TEST_END
int
main(void) {
return test(
test_realloc_alloc);
return test(test_realloc_alloc);
}

View file

@ -6,9 +6,10 @@ deallocated(void) {
return 0;
}
uint64_t deallocated;
size_t sz = sizeof(deallocated);
expect_d_eq(mallctl("thread.deallocated", (void *)&deallocated, &sz,
NULL, 0), 0, "Unexpected mallctl failure");
size_t sz = sizeof(deallocated);
expect_d_eq(
mallctl("thread.deallocated", (void *)&deallocated, &sz, NULL, 0),
0, "Unexpected mallctl failure");
return deallocated;
}
@ -28,6 +29,5 @@ TEST_END
int
main(void) {
return test(
test_realloc_free);
return test(test_realloc_free);
}

Some files were not shown because too many files have changed in this diff Show more