Commit 7178cac0 authored by antirez's avatar antirez
Browse files

Revert "Jemalloc updated to 4.4.0."

This reverts commit 153f2f00.

Jemalloc 4.4.0 is apparently causing deadlocks in certain
systems. See for example https://github.com/antirez/redis/issues/3799.
As a cautionary step we are reverting the commit back and
releasing a new stable Redis version.
parent 33fad43c
......@@ -3,7 +3,7 @@
#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 != &(a_rbt)->rbt_nil; \
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)++; \
......@@ -21,7 +21,7 @@ struct node_s {
};
static int
node_cmp(const node_t *a, const node_t *b) {
node_cmp(node_t *a, node_t *b) {
int ret;
assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
......@@ -68,43 +68,38 @@ TEST_BEGIN(test_rb_empty)
TEST_END
static unsigned
tree_recurse(node_t *node, unsigned black_height, unsigned black_depth)
tree_recurse(node_t *node, unsigned black_height, unsigned black_depth,
node_t *nil)
{
unsigned ret = 0;
node_t *left_node;
node_t *right_node;
if (node == NULL)
return (ret);
left_node = rbtn_left_get(node_t, link, node);
right_node = rbtn_right_get(node_t, link, node);
node_t *left_node = rbtn_left_get(node_t, link, node);
node_t *right_node = rbtn_right_get(node_t, link, node);
if (!rbtn_red_get(node_t, link, node))
black_depth++;
/* Red nodes must be interleaved with black nodes. */
if (rbtn_red_get(node_t, link, node)) {
if (left_node != NULL)
assert_false(rbtn_red_get(node_t, link, left_node),
"Node should be black");
if (right_node != NULL)
assert_false(rbtn_red_get(node_t, link, right_node),
"Node should be black");
assert_false(rbtn_red_get(node_t, link, left_node),
"Node should be black");
assert_false(rbtn_red_get(node_t, link, right_node),
"Node should be black");
}
if (node == nil)
return (ret);
/* Self. */
assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic");
/* Left subtree. */
if (left_node != NULL)
ret += tree_recurse(left_node, black_height, black_depth);
if (left_node != nil)
ret += tree_recurse(left_node, black_height, black_depth, nil);
else
ret += (black_depth != black_height);
/* Right subtree. */
if (right_node != NULL)
ret += tree_recurse(right_node, black_height, black_depth);
if (right_node != nil)
ret += tree_recurse(right_node, black_height, black_depth, nil);
else
ret += (black_depth != black_height);
......@@ -186,7 +181,8 @@ node_remove(tree_t *tree, node_t *node, unsigned nnodes)
node->magic = 0;
rbtn_black_height(node_t, link, tree, black_height);
imbalances = tree_recurse(tree->rbt_root, black_height, 0);
imbalances = tree_recurse(tree->rbt_root, black_height, 0,
&(tree->rbt_nil));
assert_u_eq(imbalances, 0, "Tree is unbalanced");
assert_u_eq(tree_iterate(tree), nnodes-1,
"Unexpected node iteration count");
......@@ -216,15 +212,6 @@ remove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data)
return (ret);
}
static void
destroy_cb(node_t *node, void *data)
{
unsigned *nnodes = (unsigned *)data;
assert_u_gt(*nnodes, 0, "Destruction removed too many nodes");
(*nnodes)--;
}
TEST_BEGIN(test_rb_random)
{
#define NNODES 25
......@@ -257,6 +244,7 @@ TEST_BEGIN(test_rb_random)
for (j = 1; j <= NNODES; j++) {
/* Initialize tree and nodes. */
tree_new(&tree);
tree.rbt_nil.magic = 0;
for (k = 0; k < j; k++) {
nodes[k].magic = NODE_MAGIC;
nodes[k].key = bag[k];
......@@ -269,7 +257,7 @@ TEST_BEGIN(test_rb_random)
rbtn_black_height(node_t, link, &tree,
black_height);
imbalances = tree_recurse(tree.rbt_root,
black_height, 0);
black_height, 0, &(tree.rbt_nil));
assert_u_eq(imbalances, 0,
"Tree is unbalanced");
......@@ -290,7 +278,7 @@ TEST_BEGIN(test_rb_random)
}
/* Remove nodes. */
switch (i % 5) {
switch (i % 4) {
case 0:
for (k = 0; k < j; k++)
node_remove(&tree, &nodes[k], j - k);
......@@ -326,12 +314,6 @@ TEST_BEGIN(test_rb_random)
assert_u_eq(nnodes, 0,
"Removal terminated early");
break;
} case 4: {
unsigned nnodes = j;
tree_destroy(&tree, destroy_cb, &nnodes);
assert_u_eq(nnodes, 0,
"Destruction terminated early");
break;
} default:
not_reached();
}
......
#include "test/jemalloc_test.h"
TEST_BEGIN(test_small_run_size)
{
unsigned nbins, i;
size_t sz, run_size;
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
/*
* Iterate over all small size classes, get their run sizes, and verify
* that the quantized size is the same as the run size.
*/
sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
assert_d_eq(mallctlnametomib("arenas.bin.0.run_size", mib, &miblen), 0,
"Unexpected mallctlnametomib failure");
for (i = 0; i < nbins; i++) {
mib[2] = i;
sz = sizeof(size_t);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&run_size, &sz,
NULL, 0), 0, "Unexpected mallctlbymib failure");
assert_zu_eq(run_size, run_quantize_floor(run_size),
"Small run quantization should be a no-op (run_size=%zu)",
run_size);
assert_zu_eq(run_size, run_quantize_ceil(run_size),
"Small run quantization should be a no-op (run_size=%zu)",
run_size);
}
}
TEST_END
TEST_BEGIN(test_large_run_size)
{
bool cache_oblivious;
unsigned nlruns, i;
size_t sz, run_size_prev, ceil_prev;
size_t mib[4];
size_t miblen = sizeof(mib) / sizeof(size_t);
/*
* Iterate over all large size classes, get their run sizes, and verify
* that the quantized size is the same as the run size.
*/
sz = sizeof(bool);
assert_d_eq(mallctl("config.cache_oblivious", (void *)&cache_oblivious,
&sz, NULL, 0), 0, "Unexpected mallctl failure");
sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.nlruns", (void *)&nlruns, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
assert_d_eq(mallctlnametomib("arenas.lrun.0.size", mib, &miblen), 0,
"Unexpected mallctlnametomib failure");
for (i = 0; i < nlruns; i++) {
size_t lrun_size, run_size, floor, ceil;
mib[2] = i;
sz = sizeof(size_t);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&lrun_size, &sz,
NULL, 0), 0, "Unexpected mallctlbymib failure");
run_size = cache_oblivious ? lrun_size + PAGE : lrun_size;
floor = run_quantize_floor(run_size);
ceil = run_quantize_ceil(run_size);
assert_zu_eq(run_size, floor,
"Large run quantization should be a no-op for precise "
"size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
assert_zu_eq(run_size, ceil,
"Large run quantization should be a no-op for precise "
"size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
if (i > 0) {
assert_zu_eq(run_size_prev, run_quantize_floor(run_size
- PAGE), "Floor should be a precise size");
if (run_size_prev < ceil_prev) {
assert_zu_eq(ceil_prev, run_size,
"Ceiling should be a precise size "
"(run_size_prev=%zu, ceil_prev=%zu, "
"run_size=%zu)", run_size_prev, ceil_prev,
run_size);
}
}
run_size_prev = floor;
ceil_prev = run_quantize_ceil(run_size + PAGE);
}
}
TEST_END
TEST_BEGIN(test_monotonic)
{
unsigned nbins, nlruns, i;
size_t sz, floor_prev, ceil_prev;
/*
* Iterate over all run sizes and verify that
* run_quantize_{floor,ceil}() are monotonic.
*/
sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.nlruns", (void *)&nlruns, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
floor_prev = 0;
ceil_prev = 0;
for (i = 1; i <= chunksize >> LG_PAGE; i++) {
size_t run_size, floor, ceil;
run_size = i << LG_PAGE;
floor = run_quantize_floor(run_size);
ceil = run_quantize_ceil(run_size);
assert_zu_le(floor, run_size,
"Floor should be <= (floor=%zu, run_size=%zu, ceil=%zu)",
floor, run_size, ceil);
assert_zu_ge(ceil, run_size,
"Ceiling should be >= (floor=%zu, run_size=%zu, ceil=%zu)",
floor, run_size, ceil);
assert_zu_le(floor_prev, floor, "Floor should be monotonic "
"(floor_prev=%zu, floor=%zu, run_size=%zu, ceil=%zu)",
floor_prev, floor, run_size, ceil);
assert_zu_le(ceil_prev, ceil, "Ceiling should be monotonic "
"(floor=%zu, run_size=%zu, ceil_prev=%zu, ceil=%zu)",
floor, run_size, ceil_prev, ceil);
floor_prev = floor;
ceil_prev = ceil;
}
}
TEST_END
int
main(void)
{
return (test(
test_small_run_size,
test_large_run_size,
test_monotonic));
}
......@@ -8,8 +8,8 @@ get_max_size_class(void)
size_t sz, miblen, max_size_class;
sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.nhchunks", (void *)&nhchunks, &sz, NULL, 0),
0, "Unexpected mallctl() error");
assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0,
"Unexpected mallctl() error");
miblen = sizeof(mib) / sizeof(size_t);
assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0,
......@@ -17,8 +17,8 @@ get_max_size_class(void)
mib[2] = nhchunks - 1;
sz = sizeof(size_t);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&max_size_class, &sz,
NULL, 0), 0, "Unexpected mallctlbymib() error");
assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0,
"Unexpected mallctlbymib() error");
return (max_size_class);
}
......@@ -80,105 +80,10 @@ TEST_BEGIN(test_size_classes)
}
TEST_END
TEST_BEGIN(test_psize_classes)
{
size_t size_class, max_size_class;
pszind_t pind, max_pind;
max_size_class = get_max_size_class();
max_pind = psz2ind(max_size_class);
for (pind = 0, size_class = pind2sz(pind); pind < max_pind ||
size_class < max_size_class; pind++, size_class =
pind2sz(pind)) {
assert_true(pind < max_pind,
"Loop conditionals should be equivalent; pind=%u, "
"size_class=%zu (%#zx)", pind, size_class, size_class);
assert_true(size_class < max_size_class,
"Loop conditionals should be equivalent; pind=%u, "
"size_class=%zu (%#zx)", pind, size_class, size_class);
assert_u_eq(pind, psz2ind(size_class),
"psz2ind() does not reverse pind2sz(): pind=%u -->"
" size_class=%zu --> pind=%u --> size_class=%zu", pind,
size_class, psz2ind(size_class),
pind2sz(psz2ind(size_class)));
assert_zu_eq(size_class, pind2sz(psz2ind(size_class)),
"pind2sz() does not reverse psz2ind(): pind=%u -->"
" size_class=%zu --> pind=%u --> size_class=%zu", pind,
size_class, psz2ind(size_class),
pind2sz(psz2ind(size_class)));
assert_u_eq(pind+1, psz2ind(size_class+1),
"Next size_class does not round up properly");
assert_zu_eq(size_class, (pind > 0) ?
psz2u(pind2sz(pind-1)+1) : psz2u(1),
"psz2u() does not round up to size class");
assert_zu_eq(size_class, psz2u(size_class-1),
"psz2u() does not round up to size class");
assert_zu_eq(size_class, psz2u(size_class),
"psz2u() does not compute same size class");
assert_zu_eq(psz2u(size_class+1), pind2sz(pind+1),
"psz2u() does not round up to next size class");
}
assert_u_eq(pind, psz2ind(pind2sz(pind)),
"psz2ind() does not reverse pind2sz()");
assert_zu_eq(max_size_class, pind2sz(psz2ind(max_size_class)),
"pind2sz() does not reverse psz2ind()");
assert_zu_eq(size_class, psz2u(pind2sz(pind-1)+1),
"psz2u() does not round up to size class");
assert_zu_eq(size_class, psz2u(size_class-1),
"psz2u() does not round up to size class");
assert_zu_eq(size_class, psz2u(size_class),
"psz2u() does not compute same size class");
}
TEST_END
TEST_BEGIN(test_overflow)
{
size_t max_size_class;
max_size_class = get_max_size_class();
assert_u_eq(size2index(max_size_class+1), NSIZES,
"size2index() should return NSIZES on overflow");
assert_u_eq(size2index(ZU(PTRDIFF_MAX)+1), NSIZES,
"size2index() should return NSIZES on overflow");
assert_u_eq(size2index(SIZE_T_MAX), NSIZES,
"size2index() should return NSIZES on overflow");
assert_zu_eq(s2u(max_size_class+1), 0,
"s2u() should return 0 for unsupported size");
assert_zu_eq(s2u(ZU(PTRDIFF_MAX)+1), 0,
"s2u() should return 0 for unsupported size");
assert_zu_eq(s2u(SIZE_T_MAX), 0,
"s2u() should return 0 on overflow");
assert_u_eq(psz2ind(max_size_class+1), NPSIZES,
"psz2ind() should return NPSIZES on overflow");
assert_u_eq(psz2ind(ZU(PTRDIFF_MAX)+1), NPSIZES,
"psz2ind() should return NPSIZES on overflow");
assert_u_eq(psz2ind(SIZE_T_MAX), NPSIZES,
"psz2ind() should return NPSIZES on overflow");
assert_zu_eq(psz2u(max_size_class+1), 0,
"psz2u() should return 0 for unsupported size");
assert_zu_eq(psz2u(ZU(PTRDIFF_MAX)+1), 0,
"psz2u() should return 0 for unsupported size");
assert_zu_eq(psz2u(SIZE_T_MAX), 0,
"psz2u() should return 0 on overflow");
}
TEST_END
int
main(void)
{
return (test(
test_size_classes,
test_psize_classes,
test_overflow));
test_size_classes));
}
#include "test/jemalloc_test.h"
static const uint64_t smoothstep_tab[] = {
#define STEP(step, h, x, y) \
h,
SMOOTHSTEP
#undef STEP
};
TEST_BEGIN(test_smoothstep_integral)
{
uint64_t sum, min, max;
unsigned i;
/*
* The integral of smoothstep in the [0..1] range equals 1/2. Verify
* that the fixed point representation's integral is no more than
* rounding error distant from 1/2. Regarding rounding, each table
* element is rounded down to the nearest fixed point value, so the
* integral may be off by as much as SMOOTHSTEP_NSTEPS ulps.
*/
sum = 0;
for (i = 0; i < SMOOTHSTEP_NSTEPS; i++)
sum += smoothstep_tab[i];
max = (KQU(1) << (SMOOTHSTEP_BFP-1)) * (SMOOTHSTEP_NSTEPS+1);
min = max - SMOOTHSTEP_NSTEPS;
assert_u64_ge(sum, min,
"Integral too small, even accounting for truncation");
assert_u64_le(sum, max, "Integral exceeds 1/2");
if (false) {
malloc_printf("%"FMTu64" ulps under 1/2 (limit %d)\n",
max - sum, SMOOTHSTEP_NSTEPS);
}
}
TEST_END
TEST_BEGIN(test_smoothstep_monotonic)
{
uint64_t prev_h;
unsigned i;
/*
* The smoothstep function is monotonic in [0..1], i.e. its slope is
* non-negative. In practice we want to parametrize table generation
* such that piecewise slope is greater than zero, but do not require
* that here.
*/
prev_h = 0;
for (i = 0; i < SMOOTHSTEP_NSTEPS; i++) {
uint64_t h = smoothstep_tab[i];
assert_u64_ge(h, prev_h, "Piecewise non-monotonic, i=%u", i);
prev_h = h;
}
assert_u64_eq(smoothstep_tab[SMOOTHSTEP_NSTEPS-1],
(KQU(1) << SMOOTHSTEP_BFP), "Last step must equal 1");
}
TEST_END
TEST_BEGIN(test_smoothstep_slope)
{
uint64_t prev_h, prev_delta;
unsigned i;
/*
* The smoothstep slope strictly increases until x=0.5, and then
* strictly decreases until x=1.0. Verify the slightly weaker
* requirement of monotonicity, so that inadequate table precision does
* not cause false test failures.
*/
prev_h = 0;
prev_delta = 0;
for (i = 0; i < SMOOTHSTEP_NSTEPS / 2 + SMOOTHSTEP_NSTEPS % 2; i++) {
uint64_t h = smoothstep_tab[i];
uint64_t delta = h - prev_h;
assert_u64_ge(delta, prev_delta,
"Slope must monotonically increase in 0.0 <= x <= 0.5, "
"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--) {
uint64_t h = smoothstep_tab[i];
uint64_t delta = prev_h - h;
assert_u64_ge(delta, prev_delta,
"Slope must monotonically decrease in 0.5 <= x <= 1.0, "
"i=%u", i);
prev_h = h;
prev_delta = delta;
}
}
TEST_END
int
main(void)
{
return (test(
test_smoothstep_integral,
test_smoothstep_monotonic,
test_smoothstep_slope));
}
......@@ -7,18 +7,18 @@ TEST_BEGIN(test_stats_summary)
int expected = config_stats ? 0 : ENOENT;
sz = sizeof(cactive);
assert_d_eq(mallctl("stats.cactive", (void *)&cactive, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.cactive", &cactive, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.allocated", (void *)&allocated, &sz, NULL,
0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.active", (void *)&active, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.resident", (void *)&resident, &sz, NULL, 0),
assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.mapped", (void *)&mapped, &sz, NULL, 0),
assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.resident", &resident, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
if (config_stats) {
assert_zu_le(active, *cactive,
......@@ -45,19 +45,19 @@ TEST_BEGIN(test_stats_huge)
p = mallocx(large_maxclass+1, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", (void *)&allocated,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", (void *)&nrequests,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz, NULL,
0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz, NULL,
0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
......@@ -83,8 +83,8 @@ TEST_BEGIN(test_stats_arenas_summary)
uint64_t npurge, nmadvise, purged;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
little = mallocx(SMALL_MAXCLASS, 0);
assert_ptr_not_null(little, "Unexpected mallocx() failure");
......@@ -93,26 +93,22 @@ TEST_BEGIN(test_stats_arenas_summary)
huge = mallocx(chunksize, 0);
assert_ptr_not_null(huge, "Unexpected mallocx() failure");
dallocx(little, 0);
dallocx(large, 0);
dallocx(huge, 0);
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.mapped", (void *)&mapped, &sz, NULL,
0), expected, "Unexepected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.mapped", &mapped, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge, &sz, NULL,
0), expected, "Unexepected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.nmadvise", (void *)&nmadvise, &sz,
NULL, 0), expected, "Unexepected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.purged", (void *)&purged, &sz, NULL,
0), expected, "Unexepected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.nmadvise", &nmadvise, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.purged", &purged, &sz, NULL, 0),
expected, "Unexepected mallctl() result");
if (config_stats) {
assert_u64_gt(npurge, 0,
......@@ -120,6 +116,10 @@ TEST_BEGIN(test_stats_arenas_summary)
assert_u64_le(nmadvise, purged,
"nmadvise should be no greater than purged");
}
dallocx(little, 0);
dallocx(large, 0);
dallocx(huge, 0);
}
TEST_END
......@@ -150,8 +150,8 @@ TEST_BEGIN(test_stats_arenas_small)
no_lazy_lock(); /* Lazy locking would dodge tcache testing. */
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(SMALL_MAXCLASS, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
......@@ -159,21 +159,19 @@ TEST_BEGIN(test_stats_arenas_small)
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.small.allocated",
(void *)&allocated, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.small.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.small.nrequests",
(void *)&nrequests, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.small.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
......@@ -199,36 +197,34 @@ TEST_BEGIN(test_stats_arenas_large)
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(large_maxclass, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.large.allocated",
(void *)&allocated, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.large.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.large.nrequests",
(void *)&nrequests, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.large.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
"allocated should be greater than zero");
assert_u64_gt(nmalloc, 0,
assert_zu_gt(nmalloc, 0,
"nmalloc should be greater than zero");
assert_u64_ge(nmalloc, ndalloc,
assert_zu_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
assert_u64_gt(nrequests, 0,
assert_zu_gt(nrequests, 0,
"nrequests should be greater than zero");
}
......@@ -245,30 +241,30 @@ TEST_BEGIN(test_stats_arenas_huge)
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(chunksize, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", (void *)&allocated,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
"allocated should be greater than zero");
assert_u64_gt(nmalloc, 0,
assert_zu_gt(nmalloc, 0,
"nmalloc should be greater than zero");
assert_u64_ge(nmalloc, ndalloc,
assert_zu_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
}
......@@ -286,8 +282,8 @@ TEST_BEGIN(test_stats_arenas_bins)
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(arena_bin_info[0].reg_size, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
......@@ -295,36 +291,35 @@ TEST_BEGIN(test_stats_arenas_bins)
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests",
(void *)&nrequests, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", (void *)&curregs,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", &curregs, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", (void *)&nfills,
&sz, NULL, 0), config_tcache ? expected : ENOENT,
assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz,
NULL, 0), config_tcache ? expected : ENOENT,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", (void *)&nflushes,
&sz, NULL, 0), config_tcache ? expected : ENOENT,
assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", &nflushes, &sz,
NULL, 0), config_tcache ? expected : ENOENT,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", (void *)&nruns, &sz,
assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", &nruns, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", &nreruns, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", (void *)&nreruns,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", (void *)&curruns,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", &curruns, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_u64_gt(nmalloc, 0,
......@@ -360,26 +355,25 @@ TEST_BEGIN(test_stats_arenas_lruns)
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(LARGE_MINCLASS, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", (void *)&nmalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", (void *)&ndalloc,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests",
(void *)&nrequests, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", (void *)&curruns,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", &curruns, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_u64_gt(nmalloc, 0,
......@@ -405,26 +399,23 @@ TEST_BEGIN(test_stats_arenas_hchunks)
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&arena,
sizeof(arena)), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(chunksize, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc",
(void *)&nmalloc, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc",
(void *)&ndalloc, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks",
(void *)&curhchunks, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks", &curhchunks,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_u64_gt(nmalloc, 0,
......
#include "test/jemalloc_test.h"
TEST_BEGIN(test_ticker_tick)
{
#define NREPS 2
#define NTICKS 3
ticker_t ticker;
int32_t i, j;
ticker_init(&ticker, NTICKS);
for (i = 0; i < NREPS; i++) {
for (j = 0; j < NTICKS; j++) {
assert_u_eq(ticker_read(&ticker), NTICKS - j,
"Unexpected ticker value (i=%d, j=%d)", i, j);
assert_false(ticker_tick(&ticker),
"Unexpected ticker fire (i=%d, j=%d)", i, j);
}
assert_u32_eq(ticker_read(&ticker), 0,
"Expected ticker depletion");
assert_true(ticker_tick(&ticker),
"Expected ticker fire (i=%d)", i);
assert_u32_eq(ticker_read(&ticker), NTICKS,
"Expected ticker reset");
}
#undef NTICKS
}
TEST_END
TEST_BEGIN(test_ticker_ticks)
{
#define NTICKS 3
ticker_t ticker;
ticker_init(&ticker, NTICKS);
assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
assert_false(ticker_ticks(&ticker, NTICKS), "Unexpected ticker fire");
assert_u_eq(ticker_read(&ticker), 0, "Unexpected ticker value");
assert_true(ticker_ticks(&ticker, NTICKS), "Expected ticker fire");
assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
assert_true(ticker_ticks(&ticker, NTICKS + 1), "Expected ticker fire");
assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
#undef NTICKS
}
TEST_END
TEST_BEGIN(test_ticker_copy)
{
#define NTICKS 3
ticker_t ta, tb;
ticker_init(&ta, NTICKS);
ticker_copy(&tb, &ta);
assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
assert_true(ticker_ticks(&tb, NTICKS + 1), "Expected ticker fire");
assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
ticker_tick(&ta);
ticker_copy(&tb, &ta);
assert_u_eq(ticker_read(&tb), NTICKS - 1, "Unexpected ticker value");
assert_true(ticker_ticks(&tb, NTICKS), "Expected ticker fire");
assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
#undef NTICKS
}
TEST_END
int
main(void)
{
return (test(
test_ticker_tick,
test_ticker_ticks,
test_ticker_copy));
}
......@@ -58,18 +58,18 @@ thd_start(void *arg)
data_t d = (data_t)(uintptr_t)arg;
void *p;
assert_x_eq(*data_tsd_get(true), DATA_INIT,
assert_x_eq(*data_tsd_get(), DATA_INIT,
"Initial tsd get should return initialization value");
p = malloc(1);
assert_ptr_not_null(p, "Unexpected malloc() failure");
data_tsd_set(&d);
assert_x_eq(*data_tsd_get(true), d,
assert_x_eq(*data_tsd_get(), d,
"After tsd set, tsd get should return value that was set");
d = 0;
assert_x_eq(*data_tsd_get(true), (data_t)(uintptr_t)arg,
assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg,
"Resetting local data should have no effect on tsd");
free(p);
......@@ -79,7 +79,7 @@ thd_start(void *arg)
TEST_BEGIN(test_tsd_main_thread)
{
thd_start((void *)(uintptr_t)0xa5f3e329);
thd_start((void *) 0xa5f3e329);
}
TEST_END
......@@ -99,11 +99,6 @@ int
main(void)
{
/* Core tsd bootstrapping must happen prior to data_tsd_boot(). */
if (nallocx(1, 0) == 0) {
malloc_printf("Initialization error");
return (test_status_fail);
}
data_tsd_boot();
return (test(
......
#include "test/jemalloc_test.h"
#define TEST_POW2_CEIL(t, suf, pri) do { \
unsigned i, pow2; \
t x; \
\
assert_##suf##_eq(pow2_ceil_##suf(0), 0, "Unexpected result"); \
\
for (i = 0; i < sizeof(t) * 8; i++) { \
assert_##suf##_eq(pow2_ceil_##suf(((t)1) << i), ((t)1) \
<< i, "Unexpected result"); \
} \
\
for (i = 2; i < sizeof(t) * 8; i++) { \
assert_##suf##_eq(pow2_ceil_##suf((((t)1) << i) - 1), \
((t)1) << i, "Unexpected result"); \
} \
\
for (i = 0; i < sizeof(t) * 8 - 1; i++) { \
assert_##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++) { \
assert_##suf##_eq(pow2_ceil_##suf(x), \
((t)1) << pow2, \
"Unexpected result, x=%"pri, x); \
} \
} \
} while (0)
TEST_BEGIN(test_pow2_ceil_u64)
TEST_BEGIN(test_pow2_ceil)
{
unsigned i, pow2;
size_t x;
TEST_POW2_CEIL(uint64_t, u64, FMTu64);
}
TEST_END
assert_zu_eq(pow2_ceil(0), 0, "Unexpected result");
TEST_BEGIN(test_pow2_ceil_u32)
{
for (i = 0; i < sizeof(size_t) * 8; i++) {
assert_zu_eq(pow2_ceil(ZU(1) << i), ZU(1) << i,
"Unexpected result");
}
TEST_POW2_CEIL(uint32_t, u32, FMTu32);
}
TEST_END
for (i = 2; i < sizeof(size_t) * 8; i++) {
assert_zu_eq(pow2_ceil((ZU(1) << i) - 1), ZU(1) << i,
"Unexpected result");
}
TEST_BEGIN(test_pow2_ceil_zu)
{
for (i = 0; i < sizeof(size_t) * 8 - 1; i++) {
assert_zu_eq(pow2_ceil((ZU(1) << i) + 1), ZU(1) << (i+1),
"Unexpected result");
}
TEST_POW2_CEIL(size_t, zu, "zu");
for (pow2 = 1; pow2 < 25; pow2++) {
for (x = (ZU(1) << (pow2-1)) + 1; x <= ZU(1) << pow2; x++) {
assert_zu_eq(pow2_ceil(x), ZU(1) << pow2,
"Unexpected result, x=%zu", x);
}
}
}
TEST_END
......@@ -75,7 +54,6 @@ TEST_BEGIN(test_malloc_strtoumax)
};
#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},
......@@ -88,13 +66,13 @@ TEST_BEGIN(test_malloc_strtoumax)
{"42", "", 0, ERR(0), KUMAX(42)},
{"+42", "", 0, ERR(0), KUMAX(42)},
{"-42", "", 0, ERR(0), KSMAX(-42)},
{"-42", "", 0, ERR(0), KUMAX(-42)},
{"042", "", 0, ERR(0), KUMAX(042)},
{"+042", "", 0, ERR(0), KUMAX(042)},
{"-042", "", 0, ERR(0), KSMAX(-042)},
{"-042", "", 0, ERR(0), KUMAX(-042)},
{"0x42", "", 0, ERR(0), KUMAX(0x42)},
{"+0x42", "", 0, ERR(0), KUMAX(0x42)},
{"-0x42", "", 0, ERR(0), KSMAX(-0x42)},
{"-0x42", "", 0, ERR(0), KUMAX(-0x42)},
{"0", "", 0, ERR(0), KUMAX(0)},
{"1", "", 0, ERR(0), KUMAX(1)},
......@@ -131,7 +109,6 @@ TEST_BEGIN(test_malloc_strtoumax)
};
#undef ERR
#undef KUMAX
#undef KSMAX
unsigned i;
for (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) {
......@@ -162,14 +139,14 @@ TEST_BEGIN(test_malloc_snprintf_truncated)
{
#define BUFLEN 15
char buf[BUFLEN];
size_t result;
int result;
size_t len;
#define TEST(expected_str_untruncated, ...) do { \
#define TEST(expected_str_untruncated, ...) do { \
result = malloc_snprintf(buf, len, __VA_ARGS__); \
assert_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0, \
"Unexpected string inequality (\"%s\" vs \"%s\")", \
buf, expected_str_untruncated); \
assert_zu_eq(result, strlen(expected_str_untruncated), \
buf, expected_str_untruncated); \
assert_d_eq(result, strlen(expected_str_untruncated), \
"Unexpected result"); \
} while (0)
......@@ -195,11 +172,11 @@ TEST_BEGIN(test_malloc_snprintf)
{
#define BUFLEN 128
char buf[BUFLEN];
size_t result;
int result;
#define TEST(expected_str, ...) do { \
result = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__); \
assert_str_eq(buf, expected_str, "Unexpected output"); \
assert_zu_eq(result, strlen(expected_str), "Unexpected result");\
assert_d_eq(result, strlen(expected_str), "Unexpected result"); \
} while (0)
TEST("hello", "hello");
......@@ -309,9 +286,7 @@ main(void)
{
return (test(
test_pow2_ceil_u64,
test_pow2_ceil_u32,
test_pow2_ceil_zu,
test_pow2_ceil,
test_malloc_strtoumax_no_endptr,
test_malloc_strtoumax,
test_malloc_snprintf_truncated,
......
#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_not_owner_error_t *witness_not_owner_error_orig;
static witness_lockless_error_t *witness_lockless_error_orig;
static bool saw_lock_error;
static bool saw_owner_error;
static bool saw_not_owner_error;
static bool saw_lockless_error;
static void
witness_lock_error_intercept(const witness_list_t *witnesses,
const witness_t *witness)
{
saw_lock_error = true;
}
static void
witness_owner_error_intercept(const witness_t *witness)
{
saw_owner_error = true;
}
static void
witness_not_owner_error_intercept(const witness_t *witness)
{
saw_not_owner_error = true;
}
static void
witness_lockless_error_intercept(const witness_list_t *witnesses)
{
saw_lockless_error = true;
}
static int
witness_comp(const witness_t *a, const witness_t *b)
{
assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
return (strcmp(a->name, b->name));
}
static int
witness_comp_reverse(const witness_t *a, const witness_t *b)
{
assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
return (-strcmp(a->name, b->name));
}
TEST_BEGIN(test_witness)
{
witness_t a, b;
tsdn_t *tsdn;
test_skip_if(!config_debug);
tsdn = tsdn_fetch();
witness_assert_lockless(tsdn);
witness_init(&a, "a", 1, NULL);
witness_assert_not_owner(tsdn, &a);
witness_lock(tsdn, &a);
witness_assert_owner(tsdn, &a);
witness_init(&b, "b", 2, NULL);
witness_assert_not_owner(tsdn, &b);
witness_lock(tsdn, &b);
witness_assert_owner(tsdn, &b);
witness_unlock(tsdn, &a);
witness_unlock(tsdn, &b);
witness_assert_lockless(tsdn);
}
TEST_END
TEST_BEGIN(test_witness_comp)
{
witness_t a, b, c, d;
tsdn_t *tsdn;
test_skip_if(!config_debug);
tsdn = tsdn_fetch();
witness_assert_lockless(tsdn);
witness_init(&a, "a", 1, witness_comp);
witness_assert_not_owner(tsdn, &a);
witness_lock(tsdn, &a);
witness_assert_owner(tsdn, &a);
witness_init(&b, "b", 1, witness_comp);
witness_assert_not_owner(tsdn, &b);
witness_lock(tsdn, &b);
witness_assert_owner(tsdn, &b);
witness_unlock(tsdn, &b);
witness_lock_error_orig = witness_lock_error;
witness_lock_error = witness_lock_error_intercept;
saw_lock_error = false;
witness_init(&c, "c", 1, witness_comp_reverse);
witness_assert_not_owner(tsdn, &c);
assert_false(saw_lock_error, "Unexpected witness lock error");
witness_lock(tsdn, &c);
assert_true(saw_lock_error, "Expected witness lock error");
witness_unlock(tsdn, &c);
saw_lock_error = false;
witness_init(&d, "d", 1, NULL);
witness_assert_not_owner(tsdn, &d);
assert_false(saw_lock_error, "Unexpected witness lock error");
witness_lock(tsdn, &d);
assert_true(saw_lock_error, "Expected witness lock error");
witness_unlock(tsdn, &d);
witness_unlock(tsdn, &a);
witness_assert_lockless(tsdn);
witness_lock_error = witness_lock_error_orig;
}
TEST_END
TEST_BEGIN(test_witness_reversal)
{
witness_t a, b;
tsdn_t *tsdn;
test_skip_if(!config_debug);
witness_lock_error_orig = witness_lock_error;
witness_lock_error = witness_lock_error_intercept;
saw_lock_error = false;
tsdn = tsdn_fetch();
witness_assert_lockless(tsdn);
witness_init(&a, "a", 1, NULL);
witness_init(&b, "b", 2, NULL);
witness_lock(tsdn, &b);
assert_false(saw_lock_error, "Unexpected witness lock error");
witness_lock(tsdn, &a);
assert_true(saw_lock_error, "Expected witness lock error");
witness_unlock(tsdn, &a);
witness_unlock(tsdn, &b);
witness_assert_lockless(tsdn);
witness_lock_error = witness_lock_error_orig;
}
TEST_END
TEST_BEGIN(test_witness_recursive)
{
witness_t a;
tsdn_t *tsdn;
test_skip_if(!config_debug);
witness_not_owner_error_orig = witness_not_owner_error;
witness_not_owner_error = witness_not_owner_error_intercept;
saw_not_owner_error = false;
witness_lock_error_orig = witness_lock_error;
witness_lock_error = witness_lock_error_intercept;
saw_lock_error = false;
tsdn = tsdn_fetch();
witness_assert_lockless(tsdn);
witness_init(&a, "a", 1, NULL);
witness_lock(tsdn, &a);
assert_false(saw_lock_error, "Unexpected witness lock error");
assert_false(saw_not_owner_error, "Unexpected witness not owner error");
witness_lock(tsdn, &a);
assert_true(saw_lock_error, "Expected witness lock error");
assert_true(saw_not_owner_error, "Expected witness not owner error");
witness_unlock(tsdn, &a);
witness_assert_lockless(tsdn);
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;
tsdn_t *tsdn;
test_skip_if(!config_debug);
witness_owner_error_orig = witness_owner_error;
witness_owner_error = witness_owner_error_intercept;
saw_owner_error = false;
tsdn = tsdn_fetch();
witness_assert_lockless(tsdn);
witness_init(&a, "a", 1, NULL);
assert_false(saw_owner_error, "Unexpected owner error");
witness_unlock(tsdn, &a);
assert_true(saw_owner_error, "Expected owner error");
witness_assert_lockless(tsdn);
witness_owner_error = witness_owner_error_orig;
}
TEST_END
TEST_BEGIN(test_witness_lockful)
{
witness_t a;
tsdn_t *tsdn;
test_skip_if(!config_debug);
witness_lockless_error_orig = witness_lockless_error;
witness_lockless_error = witness_lockless_error_intercept;
saw_lockless_error = false;
tsdn = tsdn_fetch();
witness_assert_lockless(tsdn);
witness_init(&a, "a", 1, NULL);
assert_false(saw_lockless_error, "Unexpected lockless error");
witness_assert_lockless(tsdn);
witness_lock(tsdn, &a);
witness_assert_lockless(tsdn);
assert_true(saw_lockless_error, "Expected lockless error");
witness_unlock(tsdn, &a);
witness_assert_lockless(tsdn);
witness_lockless_error = witness_lockless_error_orig;
}
TEST_END
int
main(void)
{
return (test(
test_witness,
test_witness_comp,
test_witness_reversal,
test_witness_recursive,
test_witness_unlock_not_owned,
test_witness_lockful));
}
......@@ -8,41 +8,39 @@ const char *malloc_conf =
static void
test_zero(size_t sz_min, size_t sz_max)
{
uint8_t *s;
char *s;
size_t sz_prev, sz, i;
#define MAGIC ((uint8_t)0x61)
sz_prev = 0;
s = (uint8_t *)mallocx(sz_min, 0);
s = (char *)mallocx(sz_min, 0);
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
for (sz = sallocx(s, 0); sz <= sz_max;
sz_prev = sz, sz = sallocx(s, 0)) {
if (sz_prev > 0) {
assert_u_eq(s[0], MAGIC,
assert_c_eq(s[0], 'a',
"Previously allocated byte %zu/%zu is corrupted",
ZU(0), sz_prev);
assert_u_eq(s[sz_prev-1], MAGIC,
assert_c_eq(s[sz_prev-1], 'a',
"Previously allocated byte %zu/%zu is corrupted",
sz_prev-1, sz_prev);
}
for (i = sz_prev; i < sz; i++) {
assert_u_eq(s[i], 0x0,
assert_c_eq(s[i], 0x0,
"Newly allocated byte %zu/%zu isn't zero-filled",
i, sz);
s[i] = MAGIC;
s[i] = 'a';
}
if (xallocx(s, sz+1, 0, 0) == sz) {
s = (uint8_t *)rallocx(s, sz+1, 0);
s = (char *)rallocx(s, sz+1, 0);
assert_ptr_not_null((void *)s,
"Unexpected rallocx() failure");
}
}
dallocx(s, 0);
#undef MAGIC
}
TEST_BEGIN(test_zero_small)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment