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
...@@ -7,8 +7,8 @@ TEST_BEGIN(test_new_delete) ...@@ -7,8 +7,8 @@ TEST_BEGIN(test_new_delete)
tsd = tsd_fetch(); tsd = tsd_fetch();
assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp),
ckh_string_keycomp), "Unexpected ckh_new() error"); "Unexpected ckh_new() error");
ckh_delete(tsd, &ckh); ckh_delete(tsd, &ckh);
assert_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash, assert_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash,
...@@ -32,8 +32,8 @@ TEST_BEGIN(test_count_insert_search_remove) ...@@ -32,8 +32,8 @@ TEST_BEGIN(test_count_insert_search_remove)
tsd = tsd_fetch(); tsd = tsd_fetch();
assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp),
ckh_string_keycomp), "Unexpected ckh_new() error"); "Unexpected ckh_new() error");
assert_zu_eq(ckh_count(&ckh), 0, assert_zu_eq(ckh_count(&ckh), 0,
"ckh_count() should return %zu, but it returned %zu", ZU(0), "ckh_count() should return %zu, but it returned %zu", ZU(0),
ckh_count(&ckh)); ckh_count(&ckh));
......
#include "test/jemalloc_test.h"
const char *malloc_conf = "purge:decay,decay_time:1";
static nstime_monotonic_t *nstime_monotonic_orig;
static nstime_update_t *nstime_update_orig;
static unsigned nupdates_mock;
static nstime_t time_mock;
static bool monotonic_mock;
static bool
nstime_monotonic_mock(void)
{
return (monotonic_mock);
}
static bool
nstime_update_mock(nstime_t *time)
{
nupdates_mock++;
if (monotonic_mock)
nstime_copy(time, &time_mock);
return (!monotonic_mock);
}
TEST_BEGIN(test_decay_ticks)
{
ticker_t *decay_ticker;
unsigned tick0, tick1;
size_t sz, huge0, large0;
void *p;
test_skip_if(opt_purge != purge_mode_decay);
decay_ticker = decay_ticker_get(tsd_fetch(), 0);
assert_ptr_not_null(decay_ticker,
"Unexpected failure getting decay ticker");
sz = sizeof(size_t);
assert_d_eq(mallctl("arenas.hchunk.0.size", (void *)&huge0, &sz, NULL,
0), 0, "Unexpected mallctl failure");
assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large0, &sz, NULL,
0), 0, "Unexpected mallctl failure");
/*
* Test the standard APIs using a huge size class, since we can't
* control tcache interactions (except by completely disabling tcache
* for the entire test program).
*/
/* malloc(). */
tick0 = ticker_read(decay_ticker);
p = malloc(huge0);
assert_ptr_not_null(p, "Unexpected malloc() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0, "Expected ticker to tick during malloc()");
/* free(). */
tick0 = ticker_read(decay_ticker);
free(p);
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0, "Expected ticker to tick during free()");
/* calloc(). */
tick0 = ticker_read(decay_ticker);
p = calloc(1, huge0);
assert_ptr_not_null(p, "Unexpected calloc() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0, "Expected ticker to tick during calloc()");
free(p);
/* posix_memalign(). */
tick0 = ticker_read(decay_ticker);
assert_d_eq(posix_memalign(&p, sizeof(size_t), huge0), 0,
"Unexpected posix_memalign() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during posix_memalign()");
free(p);
/* aligned_alloc(). */
tick0 = ticker_read(decay_ticker);
p = aligned_alloc(sizeof(size_t), huge0);
assert_ptr_not_null(p, "Unexpected aligned_alloc() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during aligned_alloc()");
free(p);
/* realloc(). */
/* Allocate. */
tick0 = ticker_read(decay_ticker);
p = realloc(NULL, huge0);
assert_ptr_not_null(p, "Unexpected realloc() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
/* Reallocate. */
tick0 = ticker_read(decay_ticker);
p = realloc(p, huge0);
assert_ptr_not_null(p, "Unexpected realloc() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
/* Deallocate. */
tick0 = ticker_read(decay_ticker);
realloc(p, 0);
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
/*
* Test the *allocx() APIs using huge, large, and small size classes,
* with tcache explicitly disabled.
*/
{
unsigned i;
size_t allocx_sizes[3];
allocx_sizes[0] = huge0;
allocx_sizes[1] = large0;
allocx_sizes[2] = 1;
for (i = 0; i < sizeof(allocx_sizes) / sizeof(size_t); i++) {
sz = allocx_sizes[i];
/* mallocx(). */
tick0 = ticker_read(decay_ticker);
p = mallocx(sz, MALLOCX_TCACHE_NONE);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during mallocx() (sz=%zu)",
sz);
/* rallocx(). */
tick0 = ticker_read(decay_ticker);
p = rallocx(p, sz, MALLOCX_TCACHE_NONE);
assert_ptr_not_null(p, "Unexpected rallocx() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during rallocx() (sz=%zu)",
sz);
/* xallocx(). */
tick0 = ticker_read(decay_ticker);
xallocx(p, sz, 0, MALLOCX_TCACHE_NONE);
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during xallocx() (sz=%zu)",
sz);
/* dallocx(). */
tick0 = ticker_read(decay_ticker);
dallocx(p, MALLOCX_TCACHE_NONE);
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during dallocx() (sz=%zu)",
sz);
/* sdallocx(). */
p = mallocx(sz, MALLOCX_TCACHE_NONE);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
tick0 = ticker_read(decay_ticker);
sdallocx(p, sz, MALLOCX_TCACHE_NONE);
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during sdallocx() "
"(sz=%zu)", sz);
}
}
/*
* Test tcache fill/flush interactions for large and small size classes,
* using an explicit tcache.
*/
if (config_tcache) {
unsigned tcache_ind, i;
size_t tcache_sizes[2];
tcache_sizes[0] = large0;
tcache_sizes[1] = 1;
sz = sizeof(unsigned);
assert_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];
/* tcache fill. */
tick0 = ticker_read(decay_ticker);
p = mallocx(sz, MALLOCX_TCACHE(tcache_ind));
assert_ptr_not_null(p, "Unexpected mallocx() failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during tcache fill "
"(sz=%zu)", sz);
/* tcache flush. */
dallocx(p, MALLOCX_TCACHE(tcache_ind));
tick0 = ticker_read(decay_ticker);
assert_d_eq(mallctl("tcache.flush", NULL, NULL,
(void *)&tcache_ind, sizeof(unsigned)), 0,
"Unexpected mallctl failure");
tick1 = ticker_read(decay_ticker);
assert_u32_ne(tick1, tick0,
"Expected ticker to tick during tcache flush "
"(sz=%zu)", sz);
}
}
}
TEST_END
TEST_BEGIN(test_decay_ticker)
{
#define NPS 1024
int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
void *ps[NPS];
uint64_t epoch;
uint64_t npurge0 = 0;
uint64_t npurge1 = 0;
size_t sz, large;
unsigned i, nupdates0;
nstime_t time, decay_time, deadline;
test_skip_if(opt_purge != purge_mode_decay);
/*
* Allocate a bunch of large objects, pause the clock, deallocate the
* objects, restore the clock, then [md]allocx() in a tight loop to
* verify the ticker triggers purging.
*/
if (config_tcache) {
size_t tcache_max;
sz = sizeof(size_t);
assert_d_eq(mallctl("arenas.tcache_max", (void *)&tcache_max,
&sz, NULL, 0), 0, "Unexpected mallctl failure");
large = nallocx(tcache_max + 1, flags);
} else {
sz = sizeof(size_t);
assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large, &sz,
NULL, 0), 0, "Unexpected mallctl failure");
}
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(uint64_t)), 0, "Unexpected mallctl failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge0, &sz,
NULL, 0), config_stats ? 0 : ENOENT, "Unexpected mallctl result");
for (i = 0; i < NPS; i++) {
ps[i] = mallocx(large, flags);
assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
}
nupdates_mock = 0;
nstime_init(&time_mock, 0);
nstime_update(&time_mock);
monotonic_mock = true;
nstime_monotonic_orig = nstime_monotonic;
nstime_update_orig = nstime_update;
nstime_monotonic = nstime_monotonic_mock;
nstime_update = nstime_update_mock;
for (i = 0; i < NPS; i++) {
dallocx(ps[i], flags);
nupdates0 = nupdates_mock;
assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
"Unexpected arena.0.decay failure");
assert_u_gt(nupdates_mock, nupdates0,
"Expected nstime_update() to be called");
}
nstime_monotonic = nstime_monotonic_orig;
nstime_update = nstime_update_orig;
nstime_init(&time, 0);
nstime_update(&time);
nstime_init2(&decay_time, opt_decay_time, 0);
nstime_copy(&deadline, &time);
nstime_add(&deadline, &decay_time);
do {
for (i = 0; i < DECAY_NTICKS_PER_UPDATE / 2; i++) {
void *p = mallocx(1, flags);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
dallocx(p, flags);
}
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
sizeof(uint64_t)), 0, "Unexpected mallctl failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge1,
&sz, NULL, 0), config_stats ? 0 : ENOENT,
"Unexpected mallctl result");
nstime_update(&time);
} while (nstime_compare(&time, &deadline) <= 0 && npurge1 == npurge0);
if (config_stats)
assert_u64_gt(npurge1, npurge0, "Expected purging to occur");
#undef NPS
}
TEST_END
TEST_BEGIN(test_decay_nonmonotonic)
{
#define NPS (SMOOTHSTEP_NSTEPS + 1)
int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
void *ps[NPS];
uint64_t epoch;
uint64_t npurge0 = 0;
uint64_t npurge1 = 0;
size_t sz, large0;
unsigned i, nupdates0;
test_skip_if(opt_purge != purge_mode_decay);
sz = sizeof(size_t);
assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large0, &sz, NULL,
0), 0, "Unexpected mallctl failure");
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(uint64_t)), 0, "Unexpected mallctl failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge0, &sz,
NULL, 0), config_stats ? 0 : ENOENT, "Unexpected mallctl result");
nupdates_mock = 0;
nstime_init(&time_mock, 0);
nstime_update(&time_mock);
monotonic_mock = false;
nstime_monotonic_orig = nstime_monotonic;
nstime_update_orig = nstime_update;
nstime_monotonic = nstime_monotonic_mock;
nstime_update = nstime_update_mock;
for (i = 0; i < NPS; i++) {
ps[i] = mallocx(large0, flags);
assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
}
for (i = 0; i < NPS; i++) {
dallocx(ps[i], flags);
nupdates0 = nupdates_mock;
assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
"Unexpected arena.0.decay failure");
assert_u_gt(nupdates_mock, nupdates0,
"Expected nstime_update() to be called");
}
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
sizeof(uint64_t)), 0, "Unexpected mallctl failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge1, &sz,
NULL, 0), config_stats ? 0 : ENOENT, "Unexpected mallctl result");
if (config_stats)
assert_u64_eq(npurge0, npurge1, "Unexpected purging occurred");
nstime_monotonic = nstime_monotonic_orig;
nstime_update = nstime_update_orig;
#undef NPS
}
TEST_END
int
main(void)
{
return (test(
test_decay_ticks,
test_decay_ticker,
test_decay_nonmonotonic));
}
#include "test/jemalloc_test.h"
#ifndef _WIN32
#include <sys/wait.h>
#endif
TEST_BEGIN(test_fork)
{
#ifndef _WIN32
void *p;
pid_t pid;
p = malloc(1);
assert_ptr_not_null(p, "Unexpected malloc() failure");
pid = fork();
free(p);
p = malloc(64);
assert_ptr_not_null(p, "Unexpected malloc() failure");
free(p);
if (pid == -1) {
/* Error. */
test_fail("Unexpected fork() failure");
} else if (pid == 0) {
/* Child. */
_exit(0);
} else {
int status;
/* Parent. */
while (true) {
if (waitpid(pid, &status, 0) == -1)
test_fail("Unexpected waitpid() failure");
if (WIFSIGNALED(status)) {
test_fail("Unexpected child termination due to "
"signal %d", WTERMSIG(status));
break;
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0) {
test_fail(
"Unexpected child exit value %d",
WEXITSTATUS(status));
}
break;
}
}
}
#else
test_skip("fork(2) is irrelevant to Windows");
#endif
}
TEST_END
int
main(void)
{
return (test(
test_fork));
}
...@@ -35,7 +35,7 @@ typedef enum { ...@@ -35,7 +35,7 @@ typedef enum {
hash_variant_x64_128 hash_variant_x64_128
} hash_variant_t; } hash_variant_t;
static int static size_t
hash_variant_bits(hash_variant_t variant) hash_variant_bits(hash_variant_t variant)
{ {
...@@ -59,20 +59,19 @@ hash_variant_string(hash_variant_t variant) ...@@ -59,20 +59,19 @@ hash_variant_string(hash_variant_t variant)
} }
} }
#define KEY_SIZE 256
static void static void
hash_variant_verify_key(hash_variant_t variant, uint8_t *key) hash_variant_verify(hash_variant_t variant)
{ {
const int hashbytes = hash_variant_bits(variant) / 8; const size_t hashbytes = hash_variant_bits(variant) / 8;
const int hashes_size = hashbytes * 256; uint8_t key[256];
VARIABLE_ARRAY(uint8_t, hashes, hashes_size); VARIABLE_ARRAY(uint8_t, hashes, hashbytes * 256);
VARIABLE_ARRAY(uint8_t, final, hashbytes); VARIABLE_ARRAY(uint8_t, final, hashbytes);
unsigned i; unsigned i;
uint32_t computed, expected; uint32_t computed, expected;
memset(key, 0, KEY_SIZE); memset(key, 0, sizeof(key));
memset(hashes, 0, hashes_size); memset(hashes, 0, sizeof(hashes));
memset(final, 0, hashbytes); memset(final, 0, sizeof(final));
/* /*
* Hash keys of the form {0}, {0,1}, {0,1,2}, ..., {0,1,...,255} as the * Hash keys of the form {0}, {0,1}, {0,1,2}, ..., {0,1,...,255} as the
...@@ -103,17 +102,17 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key) ...@@ -103,17 +102,17 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key)
/* Hash the result array. */ /* Hash the result array. */
switch (variant) { switch (variant) {
case hash_variant_x86_32: { case hash_variant_x86_32: {
uint32_t out = hash_x86_32(hashes, hashes_size, 0); uint32_t out = hash_x86_32(hashes, hashbytes*256, 0);
memcpy(final, &out, sizeof(out)); memcpy(final, &out, sizeof(out));
break; break;
} case hash_variant_x86_128: { } case hash_variant_x86_128: {
uint64_t out[2]; uint64_t out[2];
hash_x86_128(hashes, hashes_size, 0, out); hash_x86_128(hashes, hashbytes*256, 0, out);
memcpy(final, out, sizeof(out)); memcpy(final, out, sizeof(out));
break; break;
} case hash_variant_x64_128: { } case hash_variant_x64_128: {
uint64_t out[2]; uint64_t out[2];
hash_x64_128(hashes, hashes_size, 0, out); hash_x64_128(hashes, hashbytes*256, 0, out);
memcpy(final, out, sizeof(out)); memcpy(final, out, sizeof(out));
break; break;
} default: not_reached(); } default: not_reached();
...@@ -140,19 +139,6 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key) ...@@ -140,19 +139,6 @@ hash_variant_verify_key(hash_variant_t variant, uint8_t *key)
hash_variant_string(variant), expected, computed); hash_variant_string(variant), expected, computed);
} }
static void
hash_variant_verify(hash_variant_t variant)
{
#define MAX_ALIGN 16
uint8_t key[KEY_SIZE + (MAX_ALIGN - 1)];
unsigned i;
for (i = 0; i < MAX_ALIGN; i++)
hash_variant_verify_key(variant, &key[i]);
#undef MAX_ALIGN
}
#undef KEY_SIZE
TEST_BEGIN(test_hash_x86_32) TEST_BEGIN(test_hash_x86_32)
{ {
......
...@@ -29,7 +29,7 @@ arena_dalloc_junk_small_intercept(void *ptr, arena_bin_info_t *bin_info) ...@@ -29,7 +29,7 @@ arena_dalloc_junk_small_intercept(void *ptr, arena_bin_info_t *bin_info)
arena_dalloc_junk_small_orig(ptr, bin_info); arena_dalloc_junk_small_orig(ptr, bin_info);
for (i = 0; i < bin_info->reg_size; i++) { for (i = 0; i < bin_info->reg_size; i++) {
assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK, assert_c_eq(((char *)ptr)[i], 0x5a,
"Missing junk fill for byte %zu/%zu of deallocated region", "Missing junk fill for byte %zu/%zu of deallocated region",
i, bin_info->reg_size); i, bin_info->reg_size);
} }
...@@ -44,7 +44,7 @@ arena_dalloc_junk_large_intercept(void *ptr, size_t usize) ...@@ -44,7 +44,7 @@ arena_dalloc_junk_large_intercept(void *ptr, size_t usize)
arena_dalloc_junk_large_orig(ptr, usize); arena_dalloc_junk_large_orig(ptr, usize);
for (i = 0; i < usize; i++) { for (i = 0; i < usize; i++) {
assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK, assert_c_eq(((char *)ptr)[i], 0x5a,
"Missing junk fill for byte %zu/%zu of deallocated region", "Missing junk fill for byte %zu/%zu of deallocated region",
i, usize); i, usize);
} }
...@@ -69,7 +69,7 @@ huge_dalloc_junk_intercept(void *ptr, size_t usize) ...@@ -69,7 +69,7 @@ huge_dalloc_junk_intercept(void *ptr, size_t usize)
static void static void
test_junk(size_t sz_min, size_t sz_max) test_junk(size_t sz_min, size_t sz_max)
{ {
uint8_t *s; char *s;
size_t sz_prev, sz, i; size_t sz_prev, sz, i;
if (opt_junk_free) { if (opt_junk_free) {
...@@ -82,23 +82,23 @@ test_junk(size_t sz_min, size_t sz_max) ...@@ -82,23 +82,23 @@ test_junk(size_t sz_min, size_t sz_max)
} }
sz_prev = 0; 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"); assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
for (sz = sallocx(s, 0); sz <= sz_max; 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) { if (sz_prev > 0) {
assert_u_eq(s[0], 'a', assert_c_eq(s[0], 'a',
"Previously allocated byte %zu/%zu is corrupted", "Previously allocated byte %zu/%zu is corrupted",
ZU(0), sz_prev); ZU(0), sz_prev);
assert_u_eq(s[sz_prev-1], 'a', assert_c_eq(s[sz_prev-1], 'a',
"Previously allocated byte %zu/%zu is corrupted", "Previously allocated byte %zu/%zu is corrupted",
sz_prev-1, sz_prev); sz_prev-1, sz_prev);
} }
for (i = sz_prev; i < sz; i++) { for (i = sz_prev; i < sz; i++) {
if (opt_junk_alloc) { if (opt_junk_alloc) {
assert_u_eq(s[i], JEMALLOC_ALLOC_JUNK, assert_c_eq(s[i], 0xa5,
"Newly allocated byte %zu/%zu isn't " "Newly allocated byte %zu/%zu isn't "
"junk-filled", i, sz); "junk-filled", i, sz);
} }
...@@ -107,7 +107,7 @@ test_junk(size_t sz_min, size_t sz_max) ...@@ -107,7 +107,7 @@ test_junk(size_t sz_min, size_t sz_max)
if (xallocx(s, sz+1, 0, 0) == sz) { if (xallocx(s, sz+1, 0, 0) == sz) {
watch_junking(s); watch_junking(s);
s = (uint8_t *)rallocx(s, sz+1, 0); s = (char *)rallocx(s, sz+1, 0);
assert_ptr_not_null((void *)s, assert_ptr_not_null((void *)s,
"Unexpected rallocx() failure"); "Unexpected rallocx() failure");
assert_true(!opt_junk_free || saw_junking, assert_true(!opt_junk_free || saw_junking,
...@@ -244,6 +244,7 @@ int ...@@ -244,6 +244,7 @@ int
main(void) main(void)
{ {
assert(!config_fill || opt_junk_alloc || opt_junk_free);
return (test( return (test(
test_junk_small, test_junk_small,
test_junk_large, test_junk_large,
......
#define JEMALLOC_TEST_JUNK_OPT "junk:alloc" #define JEMALLOC_TEST_JUNK_OPT "junk:alloc"
#include "junk.c" #include "junk.c"
#undef JEMALLOC_TEST_JUNK_OPT #undef JEMALLOC_TEST_JUNK_OPT
#define JEMALLOC_TEST_JUNK_OPT "junk:free" #define JEMALLOC_TEST_JUNK_OPT "junk:free"
#include "junk.c" #include "junk.c"
#undef JEMALLOC_TEST_JUNK_OPT #undef JEMALLOC_TEST_JUNK_OPT
...@@ -12,18 +12,16 @@ TEST_BEGIN(test_mallctl_errors) ...@@ -12,18 +12,16 @@ TEST_BEGIN(test_mallctl_errors)
EPERM, "mallctl() should return EPERM on attempt to write " EPERM, "mallctl() should return EPERM on attempt to write "
"read-only value"); "read-only value");
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)-1),
sizeof(epoch)-1), EINVAL, EINVAL, "mallctl() should return EINVAL for input size mismatch");
"mallctl() should return EINVAL for input size mismatch"); assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)+1),
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, EINVAL, "mallctl() should return EINVAL for input size mismatch");
sizeof(epoch)+1), EINVAL,
"mallctl() should return EINVAL for input size mismatch");
sz = sizeof(epoch)-1; sz = sizeof(epoch)-1;
assert_d_eq(mallctl("epoch", (void *)&epoch, &sz, NULL, 0), EINVAL, assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL,
"mallctl() should return EINVAL for output size mismatch"); "mallctl() should return EINVAL for output size mismatch");
sz = sizeof(epoch)+1; sz = sizeof(epoch)+1;
assert_d_eq(mallctl("epoch", (void *)&epoch, &sz, NULL, 0), EINVAL, assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL,
"mallctl() should return EINVAL for output size mismatch"); "mallctl() should return EINVAL for output size mismatch");
} }
TEST_END TEST_END
...@@ -58,20 +56,18 @@ TEST_BEGIN(test_mallctlbymib_errors) ...@@ -58,20 +56,18 @@ TEST_BEGIN(test_mallctlbymib_errors)
assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0, assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure"); "Unexpected mallctlnametomib() failure");
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch, assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
sizeof(epoch)-1), EINVAL, sizeof(epoch)-1), EINVAL,
"mallctlbymib() should return EINVAL for input size mismatch"); "mallctlbymib() should return EINVAL for input size mismatch");
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch, assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
sizeof(epoch)+1), EINVAL, sizeof(epoch)+1), EINVAL,
"mallctlbymib() should return EINVAL for input size mismatch"); "mallctlbymib() should return EINVAL for input size mismatch");
sz = sizeof(epoch)-1; sz = sizeof(epoch)-1;
assert_d_eq(mallctlbymib(mib, miblen, (void *)&epoch, &sz, NULL, 0), assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,
EINVAL,
"mallctlbymib() should return EINVAL for output size mismatch"); "mallctlbymib() should return EINVAL for output size mismatch");
sz = sizeof(epoch)+1; sz = sizeof(epoch)+1;
assert_d_eq(mallctlbymib(mib, miblen, (void *)&epoch, &sz, NULL, 0), assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,
EINVAL,
"mallctlbymib() should return EINVAL for output size mismatch"); "mallctlbymib() should return EINVAL for output size mismatch");
} }
TEST_END TEST_END
...@@ -87,19 +83,18 @@ TEST_BEGIN(test_mallctl_read_write) ...@@ -87,19 +83,18 @@ TEST_BEGIN(test_mallctl_read_write)
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
/* Read. */ /* Read. */
assert_d_eq(mallctl("epoch", (void *)&old_epoch, &sz, NULL, 0), 0, assert_d_eq(mallctl("epoch", &old_epoch, &sz, NULL, 0), 0,
"Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
/* Write. */ /* Write. */
assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&new_epoch, assert_d_eq(mallctl("epoch", NULL, NULL, &new_epoch, sizeof(new_epoch)),
sizeof(new_epoch)), 0, "Unexpected mallctl() failure"); 0, "Unexpected mallctl() failure");
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
/* Read+write. */ /* Read+write. */
assert_d_eq(mallctl("epoch", (void *)&old_epoch, &sz, assert_d_eq(mallctl("epoch", &old_epoch, &sz, &new_epoch,
(void *)&new_epoch, sizeof(new_epoch)), 0, sizeof(new_epoch)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
} }
TEST_END TEST_END
...@@ -122,30 +117,29 @@ TEST_END ...@@ -122,30 +117,29 @@ TEST_END
TEST_BEGIN(test_mallctl_config) TEST_BEGIN(test_mallctl_config)
{ {
#define TEST_MALLCTL_CONFIG(config, t) do { \ #define TEST_MALLCTL_CONFIG(config) do { \
t oldval; \ bool oldval; \
size_t sz = sizeof(oldval); \ size_t sz = sizeof(oldval); \
assert_d_eq(mallctl("config."#config, (void *)&oldval, &sz, \ assert_d_eq(mallctl("config."#config, &oldval, &sz, NULL, 0), \
NULL, 0), 0, "Unexpected mallctl() failure"); \ 0, "Unexpected mallctl() failure"); \
assert_b_eq(oldval, config_##config, "Incorrect config value"); \ assert_b_eq(oldval, config_##config, "Incorrect config value"); \
assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \ assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
} while (0) } while (0)
TEST_MALLCTL_CONFIG(cache_oblivious, bool); TEST_MALLCTL_CONFIG(cache_oblivious);
TEST_MALLCTL_CONFIG(debug, bool); TEST_MALLCTL_CONFIG(debug);
TEST_MALLCTL_CONFIG(fill, bool); TEST_MALLCTL_CONFIG(fill);
TEST_MALLCTL_CONFIG(lazy_lock, bool); TEST_MALLCTL_CONFIG(lazy_lock);
TEST_MALLCTL_CONFIG(malloc_conf, const char *); TEST_MALLCTL_CONFIG(munmap);
TEST_MALLCTL_CONFIG(munmap, bool); TEST_MALLCTL_CONFIG(prof);
TEST_MALLCTL_CONFIG(prof, bool); TEST_MALLCTL_CONFIG(prof_libgcc);
TEST_MALLCTL_CONFIG(prof_libgcc, bool); TEST_MALLCTL_CONFIG(prof_libunwind);
TEST_MALLCTL_CONFIG(prof_libunwind, bool); TEST_MALLCTL_CONFIG(stats);
TEST_MALLCTL_CONFIG(stats, bool); TEST_MALLCTL_CONFIG(tcache);
TEST_MALLCTL_CONFIG(tcache, bool); TEST_MALLCTL_CONFIG(tls);
TEST_MALLCTL_CONFIG(tls, bool); TEST_MALLCTL_CONFIG(utrace);
TEST_MALLCTL_CONFIG(utrace, bool); TEST_MALLCTL_CONFIG(valgrind);
TEST_MALLCTL_CONFIG(valgrind, bool); TEST_MALLCTL_CONFIG(xmalloc);
TEST_MALLCTL_CONFIG(xmalloc, bool);
#undef TEST_MALLCTL_CONFIG #undef TEST_MALLCTL_CONFIG
} }
...@@ -159,8 +153,7 @@ TEST_BEGIN(test_mallctl_opt) ...@@ -159,8 +153,7 @@ TEST_BEGIN(test_mallctl_opt)
t oldval; \ t oldval; \
size_t sz = sizeof(oldval); \ size_t sz = sizeof(oldval); \
int expected = config_##config ? 0 : ENOENT; \ int expected = config_##config ? 0 : ENOENT; \
int result = mallctl("opt."#opt, (void *)&oldval, &sz, NULL, \ int result = mallctl("opt."#opt, &oldval, &sz, NULL, 0); \
0); \
assert_d_eq(result, expected, \ assert_d_eq(result, expected, \
"Unexpected mallctl() result for opt."#opt); \ "Unexpected mallctl() result for opt."#opt); \
assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \ assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
...@@ -169,10 +162,8 @@ TEST_BEGIN(test_mallctl_opt) ...@@ -169,10 +162,8 @@ TEST_BEGIN(test_mallctl_opt)
TEST_MALLCTL_OPT(bool, abort, always); TEST_MALLCTL_OPT(bool, abort, always);
TEST_MALLCTL_OPT(size_t, lg_chunk, always); TEST_MALLCTL_OPT(size_t, lg_chunk, always);
TEST_MALLCTL_OPT(const char *, dss, always); TEST_MALLCTL_OPT(const char *, dss, always);
TEST_MALLCTL_OPT(unsigned, narenas, always); TEST_MALLCTL_OPT(size_t, narenas, always);
TEST_MALLCTL_OPT(const char *, purge, always);
TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always); TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always);
TEST_MALLCTL_OPT(ssize_t, decay_time, always);
TEST_MALLCTL_OPT(bool, stats_print, always); TEST_MALLCTL_OPT(bool, stats_print, always);
TEST_MALLCTL_OPT(const char *, junk, fill); TEST_MALLCTL_OPT(const char *, junk, fill);
TEST_MALLCTL_OPT(size_t, quarantine, fill); TEST_MALLCTL_OPT(size_t, quarantine, fill);
...@@ -203,7 +194,7 @@ TEST_BEGIN(test_manpage_example) ...@@ -203,7 +194,7 @@ TEST_BEGIN(test_manpage_example)
size_t len, miblen; size_t len, miblen;
len = sizeof(nbins); len = sizeof(nbins);
assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &len, NULL, 0), 0, assert_d_eq(mallctl("arenas.nbins", &nbins, &len, NULL, 0), 0,
"Unexpected mallctl() failure"); "Unexpected mallctl() failure");
miblen = 4; miblen = 4;
...@@ -214,8 +205,8 @@ TEST_BEGIN(test_manpage_example) ...@@ -214,8 +205,8 @@ TEST_BEGIN(test_manpage_example)
mib[2] = i; mib[2] = i;
len = sizeof(bin_size); len = sizeof(bin_size);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&bin_size, &len, assert_d_eq(mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0),
NULL, 0), 0, "Unexpected mallctlbymib() failure"); 0, "Unexpected mallctlbymib() failure");
/* Do something with bin_size... */ /* Do something with bin_size... */
} }
} }
...@@ -264,25 +255,25 @@ TEST_BEGIN(test_tcache) ...@@ -264,25 +255,25 @@ TEST_BEGIN(test_tcache)
/* Create tcaches. */ /* Create tcaches. */
for (i = 0; i < NTCACHES; i++) { for (i = 0; i < NTCACHES; i++) {
sz = sizeof(unsigned); sz = sizeof(unsigned);
assert_d_eq(mallctl("tcache.create", (void *)&tis[i], &sz, NULL, assert_d_eq(mallctl("tcache.create", &tis[i], &sz, NULL, 0), 0,
0), 0, "Unexpected mallctl() failure, i=%u", i); "Unexpected mallctl() failure, i=%u", i);
} }
/* Exercise tcache ID recycling. */ /* Exercise tcache ID recycling. */
for (i = 0; i < NTCACHES; i++) { for (i = 0; i < NTCACHES; i++) {
assert_d_eq(mallctl("tcache.destroy", NULL, NULL, assert_d_eq(mallctl("tcache.destroy", NULL, NULL, &tis[i],
(void *)&tis[i], sizeof(unsigned)), 0, sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
"Unexpected mallctl() failure, i=%u", i); i);
} }
for (i = 0; i < NTCACHES; i++) { for (i = 0; i < NTCACHES; i++) {
sz = sizeof(unsigned); sz = sizeof(unsigned);
assert_d_eq(mallctl("tcache.create", (void *)&tis[i], &sz, NULL, assert_d_eq(mallctl("tcache.create", &tis[i], &sz, NULL, 0), 0,
0), 0, "Unexpected mallctl() failure, i=%u", i); "Unexpected mallctl() failure, i=%u", i);
} }
/* Flush empty tcaches. */ /* Flush empty tcaches. */
for (i = 0; i < NTCACHES; i++) { for (i = 0; i < NTCACHES; i++) {
assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&tis[i], assert_d_eq(mallctl("tcache.flush", NULL, NULL, &tis[i],
sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u", sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
i); i);
} }
...@@ -327,16 +318,16 @@ TEST_BEGIN(test_tcache) ...@@ -327,16 +318,16 @@ TEST_BEGIN(test_tcache)
/* Flush some non-empty tcaches. */ /* Flush some non-empty tcaches. */
for (i = 0; i < NTCACHES/2; i++) { for (i = 0; i < NTCACHES/2; i++) {
assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&tis[i], assert_d_eq(mallctl("tcache.flush", NULL, NULL, &tis[i],
sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u", sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
i); i);
} }
/* Destroy tcaches. */ /* Destroy tcaches. */
for (i = 0; i < NTCACHES; i++) { for (i = 0; i < NTCACHES; i++) {
assert_d_eq(mallctl("tcache.destroy", NULL, NULL, assert_d_eq(mallctl("tcache.destroy", NULL, NULL, &tis[i],
(void *)&tis[i], sizeof(unsigned)), 0, sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
"Unexpected mallctl() failure, i=%u", i); i);
} }
} }
TEST_END TEST_END
...@@ -346,17 +337,15 @@ TEST_BEGIN(test_thread_arena) ...@@ -346,17 +337,15 @@ TEST_BEGIN(test_thread_arena)
unsigned arena_old, arena_new, narenas; unsigned arena_old, arena_new, narenas;
size_t sz = sizeof(unsigned); size_t sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0), assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect"); assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect");
arena_new = narenas - 1; arena_new = narenas - 1;
assert_d_eq(mallctl("thread.arena", (void *)&arena_old, &sz, assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new,
(void *)&arena_new, sizeof(unsigned)), 0, sizeof(unsigned)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
arena_new = 0; arena_new = 0;
assert_d_eq(mallctl("thread.arena", (void *)&arena_old, &sz, assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new,
(void *)&arena_new, sizeof(unsigned)), 0, sizeof(unsigned)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
} }
TEST_END TEST_END
...@@ -365,20 +354,17 @@ TEST_BEGIN(test_arena_i_lg_dirty_mult) ...@@ -365,20 +354,17 @@ TEST_BEGIN(test_arena_i_lg_dirty_mult)
ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult; ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
size_t sz = sizeof(ssize_t); size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_ratio); assert_d_eq(mallctl("arena.0.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("arena.0.lg_dirty_mult",
(void *)&orig_lg_dirty_mult, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
lg_dirty_mult = -2; lg_dirty_mult = -2;
assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL, assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
(void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT, &lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success"); "Unexpected mallctl() success");
lg_dirty_mult = (sizeof(size_t) << 3); lg_dirty_mult = (sizeof(size_t) << 3);
assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL, assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
(void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT, &lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success"); "Unexpected mallctl() success");
for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1; for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
...@@ -386,48 +372,15 @@ TEST_BEGIN(test_arena_i_lg_dirty_mult) ...@@ -386,48 +372,15 @@ TEST_BEGIN(test_arena_i_lg_dirty_mult)
= lg_dirty_mult, lg_dirty_mult++) { = lg_dirty_mult, lg_dirty_mult++) {
ssize_t old_lg_dirty_mult; ssize_t old_lg_dirty_mult;
assert_d_eq(mallctl("arena.0.lg_dirty_mult", assert_d_eq(mallctl("arena.0.lg_dirty_mult", &old_lg_dirty_mult,
(void *)&old_lg_dirty_mult, &sz, (void *)&lg_dirty_mult, &sz, &lg_dirty_mult, sizeof(ssize_t)), 0,
sizeof(ssize_t)), 0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult, assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
"Unexpected old arena.0.lg_dirty_mult"); "Unexpected old arena.0.lg_dirty_mult");
} }
} }
TEST_END TEST_END
TEST_BEGIN(test_arena_i_decay_time)
{
ssize_t decay_time, orig_decay_time, prev_decay_time;
size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_decay);
assert_d_eq(mallctl("arena.0.decay_time", (void *)&orig_decay_time, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
decay_time = -2;
assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
(void *)&decay_time, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success");
decay_time = 0x7fffffff;
assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
(void *)&decay_time, sizeof(ssize_t)), 0,
"Unexpected mallctl() failure");
for (prev_decay_time = decay_time, decay_time = -1;
decay_time < 20; prev_decay_time = decay_time, decay_time++) {
ssize_t old_decay_time;
assert_d_eq(mallctl("arena.0.decay_time", (void *)&old_decay_time,
&sz, (void *)&decay_time, sizeof(ssize_t)), 0,
"Unexpected mallctl() failure");
assert_zd_eq(old_decay_time, prev_decay_time,
"Unexpected old arena.0.decay_time");
}
}
TEST_END
TEST_BEGIN(test_arena_i_purge) TEST_BEGIN(test_arena_i_purge)
{ {
unsigned narenas; unsigned narenas;
...@@ -438,29 +391,9 @@ TEST_BEGIN(test_arena_i_purge) ...@@ -438,29 +391,9 @@ TEST_BEGIN(test_arena_i_purge)
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0), assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
0, "Unexpected mallctl() failure");
assert_d_eq(mallctlnametomib("arena.0.purge", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure");
mib[1] = narenas;
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
"Unexpected mallctlbymib() failure");
}
TEST_END
TEST_BEGIN(test_arena_i_decay)
{
unsigned narenas;
size_t sz = sizeof(unsigned);
size_t mib[3];
size_t miblen = 3;
assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_d_eq(mallctlnametomib("arena.0.purge", mib, &miblen), 0,
assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
0, "Unexpected mallctl() failure");
assert_d_eq(mallctlnametomib("arena.0.decay", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure"); "Unexpected mallctlnametomib() failure");
mib[1] = narenas; mib[1] = narenas;
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0, assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
...@@ -480,35 +413,31 @@ TEST_BEGIN(test_arena_i_dss) ...@@ -480,35 +413,31 @@ TEST_BEGIN(test_arena_i_dss)
"Unexpected mallctlnametomib() error"); "Unexpected mallctlnametomib() error");
dss_prec_new = "disabled"; dss_prec_new = "disabled";
assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,
(void *)&dss_prec_new, sizeof(dss_prec_new)), 0, sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary", assert_str_ne(dss_prec_old, "primary",
"Unexpected default for dss precedence"); "Unexpected default for dss precedence");
assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_new, &sz, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
(void *)&dss_prec_old, sizeof(dss_prec_old)), 0, sizeof(dss_prec_old)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, NULL, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,
0), 0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary", assert_str_ne(dss_prec_old, "primary",
"Unexpected value for dss precedence"); "Unexpected value for dss precedence");
mib[1] = narenas_total_get(); mib[1] = narenas_total_get();
dss_prec_new = "disabled"; dss_prec_new = "disabled";
assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,
(void *)&dss_prec_new, sizeof(dss_prec_new)), 0, sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary", assert_str_ne(dss_prec_old, "primary",
"Unexpected default for dss precedence"); "Unexpected default for dss precedence");
assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_new, &sz, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
(void *)&dss_prec_old, sizeof(dss_prec_new)), 0, sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
"Unexpected mallctl() failure");
assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, NULL, assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,
0), 0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_str_ne(dss_prec_old, "primary", assert_str_ne(dss_prec_old, "primary",
"Unexpected value for dss precedence"); "Unexpected value for dss precedence");
} }
...@@ -519,14 +448,14 @@ TEST_BEGIN(test_arenas_initialized) ...@@ -519,14 +448,14 @@ TEST_BEGIN(test_arenas_initialized)
unsigned narenas; unsigned narenas;
size_t sz = sizeof(narenas); size_t sz = sizeof(narenas);
assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0), assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
{ {
VARIABLE_ARRAY(bool, initialized, narenas); VARIABLE_ARRAY(bool, initialized, narenas);
sz = narenas * sizeof(bool); sz = narenas * sizeof(bool);
assert_d_eq(mallctl("arenas.initialized", (void *)initialized, assert_d_eq(mallctl("arenas.initialized", initialized, &sz,
&sz, NULL, 0), 0, "Unexpected mallctl() failure"); NULL, 0), 0, "Unexpected mallctl() failure");
} }
} }
TEST_END TEST_END
...@@ -536,19 +465,17 @@ TEST_BEGIN(test_arenas_lg_dirty_mult) ...@@ -536,19 +465,17 @@ TEST_BEGIN(test_arenas_lg_dirty_mult)
ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult; ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
size_t sz = sizeof(ssize_t); size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_ratio); assert_d_eq(mallctl("arenas.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
assert_d_eq(mallctl("arenas.lg_dirty_mult", (void *)&orig_lg_dirty_mult,
&sz, NULL, 0), 0, "Unexpected mallctl() failure");
lg_dirty_mult = -2; lg_dirty_mult = -2;
assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL, assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
(void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT, &lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success"); "Unexpected mallctl() success");
lg_dirty_mult = (sizeof(size_t) << 3); lg_dirty_mult = (sizeof(size_t) << 3);
assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL, assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
(void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT, &lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success"); "Unexpected mallctl() success");
for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1; for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
...@@ -556,56 +483,23 @@ TEST_BEGIN(test_arenas_lg_dirty_mult) ...@@ -556,56 +483,23 @@ TEST_BEGIN(test_arenas_lg_dirty_mult)
lg_dirty_mult, lg_dirty_mult++) { lg_dirty_mult, lg_dirty_mult++) {
ssize_t old_lg_dirty_mult; ssize_t old_lg_dirty_mult;
assert_d_eq(mallctl("arenas.lg_dirty_mult", assert_d_eq(mallctl("arenas.lg_dirty_mult", &old_lg_dirty_mult,
(void *)&old_lg_dirty_mult, &sz, (void *)&lg_dirty_mult, &sz, &lg_dirty_mult, sizeof(ssize_t)), 0,
sizeof(ssize_t)), 0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult, assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
"Unexpected old arenas.lg_dirty_mult"); "Unexpected old arenas.lg_dirty_mult");
} }
} }
TEST_END TEST_END
TEST_BEGIN(test_arenas_decay_time)
{
ssize_t decay_time, orig_decay_time, prev_decay_time;
size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_decay);
assert_d_eq(mallctl("arenas.decay_time", (void *)&orig_decay_time, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
decay_time = -2;
assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
(void *)&decay_time, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success");
decay_time = 0x7fffffff;
assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
(void *)&decay_time, sizeof(ssize_t)), 0,
"Expected mallctl() failure");
for (prev_decay_time = decay_time, decay_time = -1;
decay_time < 20; prev_decay_time = decay_time, decay_time++) {
ssize_t old_decay_time;
assert_d_eq(mallctl("arenas.decay_time",
(void *)&old_decay_time, &sz, (void *)&decay_time,
sizeof(ssize_t)), 0, "Unexpected mallctl() failure");
assert_zd_eq(old_decay_time, prev_decay_time,
"Unexpected old arenas.decay_time");
}
}
TEST_END
TEST_BEGIN(test_arenas_constants) TEST_BEGIN(test_arenas_constants)
{ {
#define TEST_ARENAS_CONSTANT(t, name, expected) do { \ #define TEST_ARENAS_CONSTANT(t, name, expected) do { \
t name; \ t name; \
size_t sz = sizeof(t); \ size_t sz = sizeof(t); \
assert_d_eq(mallctl("arenas."#name, (void *)&name, &sz, NULL, \ assert_d_eq(mallctl("arenas."#name, &name, &sz, NULL, 0), 0, \
0), 0, "Unexpected mallctl() failure"); \ "Unexpected mallctl() failure"); \
assert_zu_eq(name, expected, "Incorrect "#name" size"); \ assert_zu_eq(name, expected, "Incorrect "#name" size"); \
} while (0) } while (0)
...@@ -625,8 +519,8 @@ TEST_BEGIN(test_arenas_bin_constants) ...@@ -625,8 +519,8 @@ TEST_BEGIN(test_arenas_bin_constants)
#define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \ #define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \
t name; \ t name; \
size_t sz = sizeof(t); \ size_t sz = sizeof(t); \
assert_d_eq(mallctl("arenas.bin.0."#name, (void *)&name, &sz, \ assert_d_eq(mallctl("arenas.bin.0."#name, &name, &sz, NULL, 0), \
NULL, 0), 0, "Unexpected mallctl() failure"); \ 0, "Unexpected mallctl() failure"); \
assert_zu_eq(name, expected, "Incorrect "#name" size"); \ assert_zu_eq(name, expected, "Incorrect "#name" size"); \
} while (0) } while (0)
...@@ -644,8 +538,8 @@ TEST_BEGIN(test_arenas_lrun_constants) ...@@ -644,8 +538,8 @@ TEST_BEGIN(test_arenas_lrun_constants)
#define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \ #define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \
t name; \ t name; \
size_t sz = sizeof(t); \ size_t sz = sizeof(t); \
assert_d_eq(mallctl("arenas.lrun.0."#name, (void *)&name, &sz, \ assert_d_eq(mallctl("arenas.lrun.0."#name, &name, &sz, NULL, \
NULL, 0), 0, "Unexpected mallctl() failure"); \ 0), 0, "Unexpected mallctl() failure"); \
assert_zu_eq(name, expected, "Incorrect "#name" size"); \ assert_zu_eq(name, expected, "Incorrect "#name" size"); \
} while (0) } while (0)
...@@ -661,8 +555,8 @@ TEST_BEGIN(test_arenas_hchunk_constants) ...@@ -661,8 +555,8 @@ TEST_BEGIN(test_arenas_hchunk_constants)
#define TEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do { \ #define TEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do { \
t name; \ t name; \
size_t sz = sizeof(t); \ size_t sz = sizeof(t); \
assert_d_eq(mallctl("arenas.hchunk.0."#name, (void *)&name, \ assert_d_eq(mallctl("arenas.hchunk.0."#name, &name, &sz, NULL, \
&sz, NULL, 0), 0, "Unexpected mallctl() failure"); \ 0), 0, "Unexpected mallctl() failure"); \
assert_zu_eq(name, expected, "Incorrect "#name" size"); \ assert_zu_eq(name, expected, "Incorrect "#name" size"); \
} while (0) } while (0)
...@@ -677,12 +571,12 @@ TEST_BEGIN(test_arenas_extend) ...@@ -677,12 +571,12 @@ TEST_BEGIN(test_arenas_extend)
unsigned narenas_before, arena, narenas_after; unsigned narenas_before, arena, narenas_after;
size_t sz = sizeof(unsigned); size_t sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_before, &sz, assert_d_eq(mallctl("arenas.narenas", &narenas_before, &sz, NULL, 0), 0,
NULL, 0), 0, "Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_d_eq(mallctl("arenas.extend", (void *)&arena, &sz, NULL, 0), 0, assert_d_eq(mallctl("arenas.extend", &arena, &sz, NULL, 0), 0,
"Unexpected mallctl() failure");
assert_d_eq(mallctl("arenas.narenas", &narenas_after, &sz, NULL, 0), 0,
"Unexpected mallctl() failure"); "Unexpected mallctl() failure");
assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_after, &sz, NULL,
0), 0, "Unexpected mallctl() failure");
assert_u_eq(narenas_before+1, narenas_after, assert_u_eq(narenas_before+1, narenas_after,
"Unexpected number of arenas before versus after extension"); "Unexpected number of arenas before versus after extension");
...@@ -696,14 +590,12 @@ TEST_BEGIN(test_stats_arenas) ...@@ -696,14 +590,12 @@ TEST_BEGIN(test_stats_arenas)
#define TEST_STATS_ARENAS(t, name) do { \ #define TEST_STATS_ARENAS(t, name) do { \
t name; \ t name; \
size_t sz = sizeof(t); \ size_t sz = sizeof(t); \
assert_d_eq(mallctl("stats.arenas.0."#name, (void *)&name, &sz, \ assert_d_eq(mallctl("stats.arenas.0."#name, &name, &sz, NULL, \
NULL, 0), 0, "Unexpected mallctl() failure"); \ 0), 0, "Unexpected mallctl() failure"); \
} while (0) } while (0)
TEST_STATS_ARENAS(unsigned, nthreads);
TEST_STATS_ARENAS(const char *, dss); TEST_STATS_ARENAS(const char *, dss);
TEST_STATS_ARENAS(ssize_t, lg_dirty_mult); TEST_STATS_ARENAS(unsigned, nthreads);
TEST_STATS_ARENAS(ssize_t, decay_time);
TEST_STATS_ARENAS(size_t, pactive); TEST_STATS_ARENAS(size_t, pactive);
TEST_STATS_ARENAS(size_t, pdirty); TEST_STATS_ARENAS(size_t, pdirty);
...@@ -728,13 +620,10 @@ main(void) ...@@ -728,13 +620,10 @@ main(void)
test_tcache, test_tcache,
test_thread_arena, test_thread_arena,
test_arena_i_lg_dirty_mult, test_arena_i_lg_dirty_mult,
test_arena_i_decay_time,
test_arena_i_purge, test_arena_i_purge,
test_arena_i_decay,
test_arena_i_dss, test_arena_i_dss,
test_arenas_initialized, test_arenas_initialized,
test_arenas_lg_dirty_mult, test_arenas_lg_dirty_mult,
test_arenas_decay_time,
test_arenas_constants, test_arenas_constants,
test_arenas_bin_constants, test_arenas_bin_constants,
test_arenas_lrun_constants, test_arenas_lrun_constants,
......
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
#include <float.h> #include <float.h>
#ifdef __PGI
#undef INFINITY
#endif
#ifndef INFINITY #ifndef INFINITY
#define INFINITY (DBL_MAX + DBL_MAX) #define INFINITY (DBL_MAX + DBL_MAX)
#endif #endif
......
#include "test/jemalloc_test.h"
#define BILLION UINT64_C(1000000000)
TEST_BEGIN(test_nstime_init)
{
nstime_t nst;
nstime_init(&nst, 42000000043);
assert_u64_eq(nstime_ns(&nst), 42000000043, "ns incorrectly read");
assert_u64_eq(nstime_sec(&nst), 42, "sec incorrectly read");
assert_u64_eq(nstime_nsec(&nst), 43, "nsec incorrectly read");
}
TEST_END
TEST_BEGIN(test_nstime_init2)
{
nstime_t nst;
nstime_init2(&nst, 42, 43);
assert_u64_eq(nstime_sec(&nst), 42, "sec incorrectly read");
assert_u64_eq(nstime_nsec(&nst), 43, "nsec incorrectly read");
}
TEST_END
TEST_BEGIN(test_nstime_copy)
{
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_init(&nstb, 0);
nstime_copy(&nstb, &nsta);
assert_u64_eq(nstime_sec(&nstb), 42, "sec incorrectly copied");
assert_u64_eq(nstime_nsec(&nstb), 43, "nsec incorrectly copied");
}
TEST_END
TEST_BEGIN(test_nstime_compare)
{
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
assert_d_eq(nstime_compare(&nsta, &nstb), 0, "Times should be equal");
assert_d_eq(nstime_compare(&nstb, &nsta), 0, "Times should be equal");
nstime_init2(&nstb, 42, 42);
assert_d_eq(nstime_compare(&nsta, &nstb), 1,
"nsta should be greater than nstb");
assert_d_eq(nstime_compare(&nstb, &nsta), -1,
"nstb should be less than nsta");
nstime_init2(&nstb, 42, 44);
assert_d_eq(nstime_compare(&nsta, &nstb), -1,
"nsta should be less than nstb");
assert_d_eq(nstime_compare(&nstb, &nsta), 1,
"nstb should be greater than nsta");
nstime_init2(&nstb, 41, BILLION - 1);
assert_d_eq(nstime_compare(&nsta, &nstb), 1,
"nsta should be greater than nstb");
assert_d_eq(nstime_compare(&nstb, &nsta), -1,
"nstb should be less than nsta");
nstime_init2(&nstb, 43, 0);
assert_d_eq(nstime_compare(&nsta, &nstb), -1,
"nsta should be less than nstb");
assert_d_eq(nstime_compare(&nstb, &nsta), 1,
"nstb should be greater than nsta");
}
TEST_END
TEST_BEGIN(test_nstime_add)
{
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_add(&nsta, &nstb);
nstime_init2(&nstb, 84, 86);
assert_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);
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect addition result");
}
TEST_END
TEST_BEGIN(test_nstime_subtract)
{
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_subtract(&nsta, &nstb);
nstime_init(&nstb, 0);
assert_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);
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect subtraction result");
}
TEST_END
TEST_BEGIN(test_nstime_imultiply)
{
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_imultiply(&nsta, 10);
nstime_init2(&nstb, 420, 430);
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect multiplication result");
nstime_init2(&nsta, 42, 666666666);
nstime_imultiply(&nsta, 3);
nstime_init2(&nstb, 127, 999999998);
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect multiplication result");
}
TEST_END
TEST_BEGIN(test_nstime_idivide)
{
nstime_t nsta, nstb;
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 10);
nstime_idivide(&nsta, 10);
assert_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);
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
"Incorrect division result");
}
TEST_END
TEST_BEGIN(test_nstime_divide)
{
nstime_t nsta, nstb, nstc;
nstime_init2(&nsta, 42, 43);
nstime_copy(&nstb, &nsta);
nstime_imultiply(&nsta, 10);
assert_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);
assert_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);
assert_u64_eq(nstime_divide(&nsta, &nstb), 9,
"Incorrect division result");
}
TEST_END
TEST_BEGIN(test_nstime_monotonic)
{
nstime_monotonic();
}
TEST_END
TEST_BEGIN(test_nstime_update)
{
nstime_t nst;
nstime_init(&nst, 0);
assert_false(nstime_update(&nst), "Basic time update failed.");
/* Only Rip Van Winkle sleeps this long. */
{
nstime_t addend;
nstime_init2(&addend, 631152000, 0);
nstime_add(&nst, &addend);
}
{
nstime_t nst0;
nstime_copy(&nst0, &nst);
assert_true(nstime_update(&nst),
"Update should detect time roll-back.");
assert_d_eq(nstime_compare(&nst, &nst0), 0,
"Time should not have been modified");
}
}
TEST_END
int
main(void)
{
return (test(
test_nstime_init,
test_nstime_init2,
test_nstime_copy,
test_nstime_compare,
test_nstime_add,
test_nstime_subtract,
test_nstime_imultiply,
test_nstime_idivide,
test_nstime_divide,
test_nstime_monotonic,
test_nstime_update));
}
#include "test/jemalloc_test.h"
const char *malloc_conf =
/* Use smallest possible chunk size. */
"lg_chunk:0"
/* Immediately purge to minimize fragmentation. */
",lg_dirty_mult:-1"
",decay_time:-1"
;
/*
* 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))
#else
#define SZ 4096
#endif
/*
* Number of chunks to consume at high water mark. Should be at least 2 so that
* if mmap()ed memory grows downward, downward growth of mmap()ed memory is
* tested.
*/
#define NCHUNKS 8
static unsigned
binind_compute(void)
{
size_t sz;
unsigned nbins, i;
sz = sizeof(nbins);
assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
for (i = 0; i < nbins; i++) {
size_t mib[4];
size_t miblen = sizeof(mib)/sizeof(size_t);
size_t size;
assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib,
&miblen), 0, "Unexpected mallctlnametomb failure");
mib[2] = (size_t)i;
sz = sizeof(size);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&size, &sz, NULL,
0), 0, "Unexpected mallctlbymib failure");
if (size == SZ)
return (i);
}
test_fail("Unable to compute nregs_per_run");
return (0);
}
static size_t
nregs_per_run_compute(void)
{
uint32_t nregs;
size_t sz;
unsigned binind = binind_compute();
size_t mib[4];
size_t miblen = sizeof(mib)/sizeof(size_t);
assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
"Unexpected mallctlnametomb failure");
mib[2] = (size_t)binind;
sz = sizeof(nregs);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&nregs, &sz, NULL,
0), 0, "Unexpected mallctlbymib failure");
return (nregs);
}
static size_t
npages_per_run_compute(void)
{
size_t sz;
unsigned binind = binind_compute();
size_t mib[4];
size_t miblen = sizeof(mib)/sizeof(size_t);
size_t run_size;
assert_d_eq(mallctlnametomib("arenas.bin.0.run_size", mib, &miblen), 0,
"Unexpected mallctlnametomb failure");
mib[2] = (size_t)binind;
sz = sizeof(run_size);
assert_d_eq(mallctlbymib(mib, miblen, (void *)&run_size, &sz, NULL,
0), 0, "Unexpected mallctlbymib failure");
return (run_size >> LG_PAGE);
}
static size_t
npages_per_chunk_compute(void)
{
return ((chunksize >> LG_PAGE) - map_bias);
}
static size_t
nruns_per_chunk_compute(void)
{
return (npages_per_chunk_compute() / npages_per_run_compute());
}
static unsigned
arenas_extend_mallctl(void)
{
unsigned arena_ind;
size_t sz;
sz = sizeof(arena_ind);
assert_d_eq(mallctl("arenas.extend", (void *)&arena_ind, &sz, NULL, 0),
0, "Error in arenas.extend");
return (arena_ind);
}
static void
arena_reset_mallctl(unsigned arena_ind)
{
size_t mib[3];
size_t miblen = sizeof(mib)/sizeof(size_t);
assert_d_eq(mallctlnametomib("arena.0.reset", mib, &miblen), 0,
"Unexpected mallctlnametomib() failure");
mib[1] = (size_t)arena_ind;
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
"Unexpected mallctlbymib() failure");
}
TEST_BEGIN(test_pack)
{
unsigned arena_ind = arenas_extend_mallctl();
size_t nregs_per_run = nregs_per_run_compute();
size_t nruns_per_chunk = nruns_per_chunk_compute();
size_t nruns = nruns_per_chunk * NCHUNKS;
size_t nregs = nregs_per_run * nruns;
VARIABLE_ARRAY(void *, ptrs, nregs);
size_t i, j, offset;
/* Fill matrix. */
for (i = offset = 0; i < nruns; i++) {
for (j = 0; j < nregs_per_run; j++) {
void *p = mallocx(SZ, MALLOCX_ARENA(arena_ind) |
MALLOCX_TCACHE_NONE);
assert_ptr_not_null(p,
"Unexpected mallocx(%zu, MALLOCX_ARENA(%u) |"
" MALLOCX_TCACHE_NONE) failure, run=%zu, reg=%zu",
SZ, arena_ind, i, j);
ptrs[(i * nregs_per_run) + j] = p;
}
}
/*
* Free all but one region of each run, but rotate which region is
* preserved, so that subsequent allocations exercise the within-run
* layout policy.
*/
offset = 0;
for (i = offset = 0;
i < nruns;
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);
}
}
/*
* Logically refill matrix, skipping preserved regions and verifying
* that the matrix is unmodified.
*/
offset = 0;
for (i = offset = 0;
i < nruns;
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);
assert_ptr_eq(p, ptrs[(i * nregs_per_run) + j],
"Unexpected refill discrepancy, run=%zu, reg=%zu\n",
i, j);
}
}
/* Clean up. */
arena_reset_mallctl(arena_ind);
}
TEST_END
int
main(void)
{
return (test(
test_pack));
}
#include "test/jemalloc_test.h"
TEST_BEGIN(test_pages_huge)
{
bool commit;
void *pages;
commit = true;
pages = pages_map(NULL, PAGE, &commit);
assert_ptr_not_null(pages, "Unexpected pages_map() error");
assert_false(pages_huge(pages, PAGE),
"Unexpected pages_huge() result");
assert_false(pages_nohuge(pages, PAGE),
"Unexpected pages_nohuge() result");
pages_unmap(pages, PAGE);
}
TEST_END
int
main(void)
{
return (test(
test_pages_huge));
}
#include "test/jemalloc_test.h"
typedef struct node_s node_t;
struct node_s {
#define NODE_MAGIC 0x9823af7e
uint32_t magic;
phn(node_t) link;
uint64_t key;
};
static int
node_cmp(const node_t *a, const node_t *b)
{
int ret;
ret = (a->key > b->key) - (a->key < b->key);
if (ret == 0) {
/*
* Duplicates are not allowed in the heap, so force an
* arbitrary ordering for non-identical items with equal keys.
*/
ret = (((uintptr_t)a) > ((uintptr_t)b))
- (((uintptr_t)a) < ((uintptr_t)b));
}
return (ret);
}
static int
node_cmp_magic(const node_t *a, const node_t *b) {
assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
assert_u32_eq(b->magic, NODE_MAGIC, "Bad magic");
return (node_cmp(a, b));
}
typedef ph(node_t) heap_t;
ph_gen(static, heap_, heap_t, node_t, link, node_cmp_magic);
static void
node_print(const node_t *node, unsigned depth)
{
unsigned i;
node_t *leftmost_child, *sibling;
for (i = 0; i < depth; i++)
malloc_printf("\t");
malloc_printf("%2"FMTu64"\n", node->key);
leftmost_child = phn_lchild_get(node_t, link, node);
if (leftmost_child == NULL)
return;
node_print(leftmost_child, depth + 1);
for (sibling = phn_next_get(node_t, link, leftmost_child); sibling !=
NULL; sibling = phn_next_get(node_t, link, sibling)) {
node_print(sibling, depth + 1);
}
}
static void
heap_print(const heap_t *heap)
{
node_t *auxelm;
malloc_printf("vvv heap %p vvv\n", heap);
if (heap->ph_root == NULL)
goto label_return;
node_print(heap->ph_root, 0);
for (auxelm = phn_next_get(node_t, link, heap->ph_root); auxelm != NULL;
auxelm = phn_next_get(node_t, link, auxelm)) {
assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
link, auxelm)), auxelm,
"auxelm's prev doesn't link to auxelm");
node_print(auxelm, 0);
}
label_return:
malloc_printf("^^^ heap %p ^^^\n", heap);
}
static unsigned
node_validate(const node_t *node, const node_t *parent)
{
unsigned nnodes = 1;
node_t *leftmost_child, *sibling;
if (parent != NULL) {
assert_d_ge(node_cmp_magic(node, parent), 0,
"Child is less than parent");
}
leftmost_child = phn_lchild_get(node_t, link, node);
if (leftmost_child == NULL)
return (nnodes);
assert_ptr_eq((void *)phn_prev_get(node_t, link, leftmost_child),
(void *)node, "Leftmost child does not link to node");
nnodes += node_validate(leftmost_child, node);
for (sibling = phn_next_get(node_t, link, leftmost_child); sibling !=
NULL; sibling = phn_next_get(node_t, link, sibling)) {
assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
link, sibling)), sibling,
"sibling's prev doesn't link to sibling");
nnodes += node_validate(sibling, node);
}
return (nnodes);
}
static unsigned
heap_validate(const heap_t *heap)
{
unsigned nnodes = 0;
node_t *auxelm;
if (heap->ph_root == NULL)
goto label_return;
nnodes += node_validate(heap->ph_root, NULL);
for (auxelm = phn_next_get(node_t, link, heap->ph_root); auxelm != NULL;
auxelm = phn_next_get(node_t, link, auxelm)) {
assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
link, auxelm)), auxelm,
"auxelm's prev doesn't link to auxelm");
nnodes += node_validate(auxelm, NULL);
}
label_return:
if (false)
heap_print(heap);
return (nnodes);
}
TEST_BEGIN(test_ph_empty)
{
heap_t heap;
heap_new(&heap);
assert_true(heap_empty(&heap), "Heap should be empty");
assert_ptr_null(heap_first(&heap), "Unexpected node");
}
TEST_END
static void
node_remove(heap_t *heap, node_t *node)
{
heap_remove(heap, node);
node->magic = 0;
}
static node_t *
node_remove_first(heap_t *heap)
{
node_t *node = heap_remove_first(heap);
node->magic = 0;
return (node);
}
TEST_BEGIN(test_ph_random)
{
#define NNODES 25
#define NBAGS 250
#define SEED 42
sfmt_t *sfmt;
uint64_t bag[NNODES];
heap_t heap;
node_t nodes[NNODES];
unsigned i, j, k;
sfmt = init_gen_rand(SEED);
for (i = 0; i < NBAGS; i++) {
switch (i) {
case 0:
/* Insert in order. */
for (j = 0; j < NNODES; j++)
bag[j] = j;
break;
case 1:
/* Insert in reverse order. */
for (j = 0; j < NNODES; j++)
bag[j] = NNODES - j - 1;
break;
default:
for (j = 0; j < NNODES; j++)
bag[j] = gen_rand64_range(sfmt, NNODES);
}
for (j = 1; j <= NNODES; j++) {
/* Initialize heap and nodes. */
heap_new(&heap);
assert_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];
}
/* Insert nodes. */
for (k = 0; k < j; k++) {
heap_insert(&heap, &nodes[k]);
if (i % 13 == 12) {
/* Trigger merging. */
assert_ptr_not_null(heap_first(&heap),
"Heap should not be empty");
}
assert_u_eq(heap_validate(&heap), k + 1,
"Incorrect node count");
}
assert_false(heap_empty(&heap),
"Heap should not be empty");
/* Remove nodes. */
switch (i % 4) {
case 0:
for (k = 0; k < j; k++) {
assert_u_eq(heap_validate(&heap), j - k,
"Incorrect node count");
node_remove(&heap, &nodes[k]);
assert_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]);
assert_u_eq(heap_validate(&heap), k - 1,
"Incorrect node count");
}
break;
case 2: {
node_t *prev = NULL;
for (k = 0; k < j; k++) {
node_t *node = node_remove_first(&heap);
assert_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
if (prev != NULL) {
assert_d_ge(node_cmp(node,
prev), 0,
"Bad removal order");
}
prev = node;
}
break;
} case 3: {
node_t *prev = NULL;
for (k = 0; k < j; k++) {
node_t *node = heap_first(&heap);
assert_u_eq(heap_validate(&heap), j - k,
"Incorrect node count");
if (prev != NULL) {
assert_d_ge(node_cmp(node,
prev), 0,
"Bad removal order");
}
node_remove(&heap, node);
assert_u_eq(heap_validate(&heap), j - k
- 1, "Incorrect node count");
prev = node;
}
break;
} default:
not_reached();
}
assert_ptr_null(heap_first(&heap),
"Heap should be empty");
assert_true(heap_empty(&heap), "Heap should be empty");
}
}
fini_gen_rand(sfmt);
#undef NNODES
#undef SEED
}
TEST_END
int
main(void)
{
return (test(
test_ph_empty,
test_ph_random));
}
#include "test/jemalloc_test.h"
static void
test_prng_lg_range_u32(bool atomic)
{
uint32_t sa, sb, ra, rb;
unsigned lg_range;
sa = 42;
ra = prng_lg_range_u32(&sa, 32, atomic);
sa = 42;
rb = prng_lg_range_u32(&sa, 32, atomic);
assert_u32_eq(ra, rb,
"Repeated generation should produce repeated results");
sb = 42;
rb = prng_lg_range_u32(&sb, 32, atomic);
assert_u32_eq(ra, rb,
"Equivalent generation should produce equivalent results");
sa = 42;
ra = prng_lg_range_u32(&sa, 32, atomic);
rb = prng_lg_range_u32(&sa, 32, atomic);
assert_u32_ne(ra, rb,
"Full-width results must not immediately repeat");
sa = 42;
ra = prng_lg_range_u32(&sa, 32, atomic);
for (lg_range = 31; lg_range > 0; lg_range--) {
sb = 42;
rb = prng_lg_range_u32(&sb, lg_range, atomic);
assert_u32_eq((rb & (UINT32_C(0xffffffff) << lg_range)),
0, "High order bits should be 0, lg_range=%u", lg_range);
assert_u32_eq(rb, (ra >> (32 - lg_range)),
"Expected high order bits of full-width result, "
"lg_range=%u", lg_range);
}
}
static void
test_prng_lg_range_u64(void)
{
uint64_t sa, sb, ra, rb;
unsigned lg_range;
sa = 42;
ra = prng_lg_range_u64(&sa, 64);
sa = 42;
rb = prng_lg_range_u64(&sa, 64);
assert_u64_eq(ra, rb,
"Repeated generation should produce repeated results");
sb = 42;
rb = prng_lg_range_u64(&sb, 64);
assert_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);
assert_u64_ne(ra, rb,
"Full-width results must not immediately repeat");
sa = 42;
ra = prng_lg_range_u64(&sa, 64);
for (lg_range = 63; lg_range > 0; lg_range--) {
sb = 42;
rb = prng_lg_range_u64(&sb, lg_range);
assert_u64_eq((rb & (UINT64_C(0xffffffffffffffff) << lg_range)),
0, "High order bits should be 0, lg_range=%u", lg_range);
assert_u64_eq(rb, (ra >> (64 - lg_range)),
"Expected high order bits of full-width result, "
"lg_range=%u", lg_range);
}
}
static void
test_prng_lg_range_zu(bool atomic)
{
size_t sa, sb, ra, rb;
unsigned lg_range;
sa = 42;
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
sa = 42;
rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
assert_zu_eq(ra, rb,
"Repeated generation should produce repeated results");
sb = 42;
rb = prng_lg_range_zu(&sb, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
assert_zu_eq(ra, rb,
"Equivalent generation should produce equivalent results");
sa = 42;
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
assert_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), atomic);
for (lg_range = (ZU(1) << (3 + LG_SIZEOF_PTR)) - 1; lg_range > 0;
lg_range--) {
sb = 42;
rb = prng_lg_range_zu(&sb, lg_range, atomic);
assert_zu_eq((rb & (SIZE_T_MAX << lg_range)),
0, "High order bits should be 0, lg_range=%u", lg_range);
assert_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_BEGIN(test_prng_lg_range_u32_nonatomic)
{
test_prng_lg_range_u32(false);
}
TEST_END
TEST_BEGIN(test_prng_lg_range_u32_atomic)
{
test_prng_lg_range_u32(true);
}
TEST_END
TEST_BEGIN(test_prng_lg_range_u64_nonatomic)
{
test_prng_lg_range_u64();
}
TEST_END
TEST_BEGIN(test_prng_lg_range_zu_nonatomic)
{
test_prng_lg_range_zu(false);
}
TEST_END
TEST_BEGIN(test_prng_lg_range_zu_atomic)
{
test_prng_lg_range_zu(true);
}
TEST_END
static void
test_prng_range_u32(bool atomic)
{
uint32_t range;
#define MAX_RANGE 10000000
#define RANGE_STEP 97
#define NREPS 10
for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
uint32_t s;
unsigned rep;
s = range;
for (rep = 0; rep < NREPS; rep++) {
uint32_t r = prng_range_u32(&s, range, atomic);
assert_u32_lt(r, range, "Out of range");
}
}
}
static void
test_prng_range_u64(void)
{
uint64_t range;
#define MAX_RANGE 10000000
#define RANGE_STEP 97
#define NREPS 10
for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
uint64_t s;
unsigned rep;
s = range;
for (rep = 0; rep < NREPS; rep++) {
uint64_t r = prng_range_u64(&s, range);
assert_u64_lt(r, range, "Out of range");
}
}
}
static void
test_prng_range_zu(bool atomic)
{
size_t range;
#define MAX_RANGE 10000000
#define RANGE_STEP 97
#define NREPS 10
for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
size_t s;
unsigned rep;
s = range;
for (rep = 0; rep < NREPS; rep++) {
size_t r = prng_range_zu(&s, range, atomic);
assert_zu_lt(r, range, "Out of range");
}
}
}
TEST_BEGIN(test_prng_range_u32_nonatomic)
{
test_prng_range_u32(false);
}
TEST_END
TEST_BEGIN(test_prng_range_u32_atomic)
{
test_prng_range_u32(true);
}
TEST_END
TEST_BEGIN(test_prng_range_u64_nonatomic)
{
test_prng_range_u64();
}
TEST_END
TEST_BEGIN(test_prng_range_zu_nonatomic)
{
test_prng_range_zu(false);
}
TEST_END
TEST_BEGIN(test_prng_range_zu_atomic)
{
test_prng_range_zu(true);
}
TEST_END
int
main(void)
{
return (test(
test_prng_lg_range_u32_nonatomic,
test_prng_lg_range_u32_atomic,
test_prng_lg_range_u64_nonatomic,
test_prng_lg_range_zu_nonatomic,
test_prng_lg_range_zu_atomic,
test_prng_range_u32_nonatomic,
test_prng_range_u32_atomic,
test_prng_range_u64_nonatomic,
test_prng_range_zu_nonatomic,
test_prng_range_zu_atomic));
}
...@@ -68,9 +68,8 @@ TEST_BEGIN(test_idump) ...@@ -68,9 +68,8 @@ TEST_BEGIN(test_idump)
test_skip_if(!config_prof); test_skip_if(!config_prof);
active = true; active = true;
assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
sizeof(active)), 0, 0, "Unexpected mallctl failure while activating profiling");
"Unexpected mallctl failure while activating profiling");
prof_dump_open = prof_dump_open_intercept; prof_dump_open = prof_dump_open_intercept;
......
...@@ -12,7 +12,7 @@ mallctl_bool_get(const char *name, bool expected, const char *func, int line) ...@@ -12,7 +12,7 @@ mallctl_bool_get(const char *name, bool expected, const char *func, int line)
size_t sz; size_t sz;
sz = sizeof(old); sz = sizeof(old);
assert_d_eq(mallctl(name, (void *)&old, &sz, NULL, 0), 0, assert_d_eq(mallctl(name, &old, &sz, NULL, 0), 0,
"%s():%d: Unexpected mallctl failure reading %s", func, line, name); "%s():%d: Unexpected mallctl failure reading %s", func, line, name);
assert_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line, assert_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line,
name); name);
...@@ -26,8 +26,7 @@ mallctl_bool_set(const char *name, bool old_expected, bool val_new, ...@@ -26,8 +26,7 @@ mallctl_bool_set(const char *name, bool old_expected, bool val_new,
size_t sz; size_t sz;
sz = sizeof(old); sz = sizeof(old);
assert_d_eq(mallctl(name, (void *)&old, &sz, (void *)&val_new, assert_d_eq(mallctl(name, &old, &sz, &val_new, sizeof(val_new)), 0,
sizeof(val_new)), 0,
"%s():%d: Unexpected mallctl failure reading/writing %s", func, "%s():%d: Unexpected mallctl failure reading/writing %s", func,
line, name); line, name);
assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func, assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func,
......
...@@ -28,9 +28,8 @@ TEST_BEGIN(test_gdump) ...@@ -28,9 +28,8 @@ TEST_BEGIN(test_gdump)
test_skip_if(!config_prof); test_skip_if(!config_prof);
active = true; active = true;
assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
sizeof(active)), 0, 0, "Unexpected mallctl failure while activating profiling");
"Unexpected mallctl failure while activating profiling");
prof_dump_open = prof_dump_open_intercept; prof_dump_open = prof_dump_open_intercept;
...@@ -46,8 +45,8 @@ TEST_BEGIN(test_gdump) ...@@ -46,8 +45,8 @@ TEST_BEGIN(test_gdump)
gdump = false; gdump = false;
sz = sizeof(gdump_old); sz = sizeof(gdump_old);
assert_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz, assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump,
(void *)&gdump, sizeof(gdump)), 0, sizeof(gdump)), 0,
"Unexpected mallctl failure while disabling prof.gdump"); "Unexpected mallctl failure while disabling prof.gdump");
assert(gdump_old); assert(gdump_old);
did_prof_dump_open = false; did_prof_dump_open = false;
...@@ -57,8 +56,8 @@ TEST_BEGIN(test_gdump) ...@@ -57,8 +56,8 @@ TEST_BEGIN(test_gdump)
gdump = true; gdump = true;
sz = sizeof(gdump_old); sz = sizeof(gdump_old);
assert_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz, assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump,
(void *)&gdump, sizeof(gdump)), 0, sizeof(gdump)), 0,
"Unexpected mallctl failure while enabling prof.gdump"); "Unexpected mallctl failure while enabling prof.gdump");
assert(!gdump_old); assert(!gdump_old);
did_prof_dump_open = false; did_prof_dump_open = false;
......
...@@ -29,9 +29,8 @@ TEST_BEGIN(test_idump) ...@@ -29,9 +29,8 @@ TEST_BEGIN(test_idump)
test_skip_if(!config_prof); test_skip_if(!config_prof);
active = true; active = true;
assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
sizeof(active)), 0, 0, "Unexpected mallctl failure while activating profiling");
"Unexpected mallctl failure while activating profiling");
prof_dump_open = prof_dump_open_intercept; prof_dump_open = prof_dump_open_intercept;
......
...@@ -20,8 +20,8 @@ static void ...@@ -20,8 +20,8 @@ static void
set_prof_active(bool active) set_prof_active(bool active)
{ {
assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
sizeof(active)), 0, "Unexpected mallctl failure"); 0, "Unexpected mallctl failure");
} }
static size_t static size_t
...@@ -30,8 +30,7 @@ get_lg_prof_sample(void) ...@@ -30,8 +30,7 @@ get_lg_prof_sample(void)
size_t lg_prof_sample; size_t lg_prof_sample;
size_t sz = sizeof(size_t); size_t sz = sizeof(size_t);
assert_d_eq(mallctl("prof.lg_sample", (void *)&lg_prof_sample, &sz, assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0,
NULL, 0), 0,
"Unexpected mallctl failure while reading profiling sample rate"); "Unexpected mallctl failure while reading profiling sample rate");
return (lg_prof_sample); return (lg_prof_sample);
} }
...@@ -40,7 +39,7 @@ static void ...@@ -40,7 +39,7 @@ static void
do_prof_reset(size_t lg_prof_sample) do_prof_reset(size_t lg_prof_sample)
{ {
assert_d_eq(mallctl("prof.reset", NULL, NULL, assert_d_eq(mallctl("prof.reset", NULL, NULL,
(void *)&lg_prof_sample, sizeof(size_t)), 0, &lg_prof_sample, sizeof(size_t)), 0,
"Unexpected mallctl failure while resetting profile data"); "Unexpected mallctl failure while resetting profile data");
assert_zu_eq(lg_prof_sample, get_lg_prof_sample(), assert_zu_eq(lg_prof_sample, get_lg_prof_sample(),
"Expected profile sample rate change"); "Expected profile sample rate change");
...@@ -55,8 +54,8 @@ TEST_BEGIN(test_prof_reset_basic) ...@@ -55,8 +54,8 @@ TEST_BEGIN(test_prof_reset_basic)
test_skip_if(!config_prof); test_skip_if(!config_prof);
sz = sizeof(size_t); sz = sizeof(size_t);
assert_d_eq(mallctl("opt.lg_prof_sample", (void *)&lg_prof_sample_orig, assert_d_eq(mallctl("opt.lg_prof_sample", &lg_prof_sample_orig, &sz,
&sz, NULL, 0), 0, NULL, 0), 0,
"Unexpected mallctl failure while reading profiling sample rate"); "Unexpected mallctl failure while reading profiling sample rate");
assert_zu_eq(lg_prof_sample_orig, 0, assert_zu_eq(lg_prof_sample_orig, 0,
"Unexpected profiling sample rate"); "Unexpected profiling sample rate");
...@@ -95,8 +94,7 @@ TEST_END ...@@ -95,8 +94,7 @@ TEST_END
bool prof_dump_header_intercepted = false; bool prof_dump_header_intercepted = false;
prof_cnt_t cnt_all_copy = {0, 0, 0, 0}; prof_cnt_t cnt_all_copy = {0, 0, 0, 0};
static bool static bool
prof_dump_header_intercept(tsdn_t *tsdn, bool propagate_err, prof_dump_header_intercept(bool propagate_err, const prof_cnt_t *cnt_all)
const prof_cnt_t *cnt_all)
{ {
prof_dump_header_intercepted = true; prof_dump_header_intercepted = true;
......
...@@ -12,9 +12,8 @@ mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func, ...@@ -12,9 +12,8 @@ mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,
size_t sz; size_t sz;
sz = sizeof(thread_name_old); sz = sizeof(thread_name_old);
assert_d_eq(mallctl("thread.prof.name", (void *)&thread_name_old, &sz, assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz, NULL, 0),
NULL, 0), 0, 0, "%s():%d: Unexpected mallctl failure reading thread.prof.name",
"%s():%d: Unexpected mallctl failure reading thread.prof.name",
func, line); func, line);
assert_str_eq(thread_name_old, thread_name_expected, assert_str_eq(thread_name_old, thread_name_expected,
"%s():%d: Unexpected thread.prof.name value", func, line); "%s():%d: Unexpected thread.prof.name value", func, line);
...@@ -27,8 +26,8 @@ mallctl_thread_name_set_impl(const char *thread_name, const char *func, ...@@ -27,8 +26,8 @@ mallctl_thread_name_set_impl(const char *thread_name, const char *func,
int line) int line)
{ {
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
(void *)&thread_name, sizeof(thread_name)), 0, sizeof(thread_name)), 0,
"%s():%d: Unexpected mallctl failure reading thread.prof.name", "%s():%d: Unexpected mallctl failure reading thread.prof.name",
func, line); func, line);
mallctl_thread_name_get_impl(thread_name, func, line); mallctl_thread_name_get_impl(thread_name, func, line);
...@@ -47,15 +46,15 @@ TEST_BEGIN(test_prof_thread_name_validation) ...@@ -47,15 +46,15 @@ TEST_BEGIN(test_prof_thread_name_validation)
/* NULL input shouldn't be allowed. */ /* NULL input shouldn't be allowed. */
thread_name = NULL; thread_name = NULL;
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
(void *)&thread_name, sizeof(thread_name)), EFAULT, sizeof(thread_name)), EFAULT,
"Unexpected mallctl result writing \"%s\" to thread.prof.name", "Unexpected mallctl result writing \"%s\" to thread.prof.name",
thread_name); thread_name);
/* '\n' shouldn't be allowed. */ /* '\n' shouldn't be allowed. */
thread_name = "hi\nthere"; thread_name = "hi\nthere";
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
(void *)&thread_name, sizeof(thread_name)), EFAULT, sizeof(thread_name)), EFAULT,
"Unexpected mallctl result writing \"%s\" to thread.prof.name", "Unexpected mallctl result writing \"%s\" to thread.prof.name",
thread_name); thread_name);
...@@ -65,9 +64,8 @@ TEST_BEGIN(test_prof_thread_name_validation) ...@@ -65,9 +64,8 @@ TEST_BEGIN(test_prof_thread_name_validation)
size_t sz; size_t sz;
sz = sizeof(thread_name_old); sz = sizeof(thread_name_old);
assert_d_eq(mallctl("thread.prof.name", assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz,
(void *)&thread_name_old, &sz, (void *)&thread_name, &thread_name, sizeof(thread_name)), EPERM,
sizeof(thread_name)), EPERM,
"Unexpected mallctl result writing \"%s\" to " "Unexpected mallctl result writing \"%s\" to "
"thread.prof.name", thread_name); "thread.prof.name", thread_name);
} }
......
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