Commit 89a9e5a9 authored by Guy Benoish's avatar Guy Benoish
Browse files

Merge branch 'unstable' of https://github.com/antirez/redis into unstable

parents 71a8df6a a4c7f34d
...@@ -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,
......
...@@ -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