Commit 5268379e authored by antirez's avatar antirez
Browse files

Jemalloc updated to 4.0.3.

parent 589c41e4
......@@ -3,6 +3,12 @@
#define MAX_REL_ERR 1.0e-9
#define MAX_ABS_ERR 1.0e-9
#include <float.h>
#ifndef INFINITY
#define INFINITY (DBL_MAX + DBL_MAX)
#endif
static bool
double_eq_rel(double a, double b, double max_rel_err, double max_abs_err)
{
......
......@@ -54,7 +54,7 @@ thd_sender_start(void *arg)
mq_msg_t *msg;
void *p;
p = mallocx(sizeof(mq_msg_t), 0);
assert_ptr_not_null(p, "Unexpected allocm() failure");
assert_ptr_not_null(p, "Unexpected mallocx() failure");
msg = (mq_msg_t *)p;
mq_put(mq, msg);
}
......@@ -85,6 +85,7 @@ TEST_END
int
main(void)
{
return (test(
test_mq_basic,
test_mq_threaded));
......
#include "prof_accum.h"
#include "test/jemalloc_test.h"
#define NTHREADS 4
#define NALLOCS_PER_THREAD 50
#define DUMP_INTERVAL 1
#define BT_COUNT_CHECK_INTERVAL 5
#ifdef JEMALLOC_PROF
const char *malloc_conf =
......@@ -20,7 +25,7 @@ static void *
alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration)
{
return (alloc_0(thd_ind*NALLOCS_PER_THREAD + iteration));
return (btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration));
}
static void *
......
#include "prof_accum.h"
alloc_n_gen(0)
#include "prof_accum.h"
alloc_n_gen(1)
#include "test/jemalloc_test.h"
#ifdef JEMALLOC_PROF
const char *malloc_conf =
"prof:true,prof_thread_active_init:false,lg_prof_sample:0";
#endif
static void
mallctl_bool_get(const char *name, bool expected, const char *func, int line)
{
bool old;
size_t sz;
sz = sizeof(old);
assert_d_eq(mallctl(name, &old, &sz, NULL, 0), 0,
"%s():%d: Unexpected mallctl failure reading %s", func, line, name);
assert_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line,
name);
}
static void
mallctl_bool_set(const char *name, bool old_expected, bool val_new,
const char *func, int line)
{
bool old;
size_t sz;
sz = sizeof(old);
assert_d_eq(mallctl(name, &old, &sz, &val_new, sizeof(val_new)), 0,
"%s():%d: Unexpected mallctl failure reading/writing %s", func,
line, name);
assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func,
line, name);
}
static void
mallctl_prof_active_get_impl(bool prof_active_old_expected, const char *func,
int line)
{
mallctl_bool_get("prof.active", prof_active_old_expected, func, line);
}
#define mallctl_prof_active_get(a) \
mallctl_prof_active_get_impl(a, __func__, __LINE__)
static void
mallctl_prof_active_set_impl(bool prof_active_old_expected,
bool prof_active_new, const char *func, int line)
{
mallctl_bool_set("prof.active", prof_active_old_expected,
prof_active_new, func, line);
}
#define mallctl_prof_active_set(a, b) \
mallctl_prof_active_set_impl(a, b, __func__, __LINE__)
static void
mallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected,
const char *func, int line)
{
mallctl_bool_get("thread.prof.active", thread_prof_active_old_expected,
func, line);
}
#define mallctl_thread_prof_active_get(a) \
mallctl_thread_prof_active_get_impl(a, __func__, __LINE__)
static void
mallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected,
bool thread_prof_active_new, const char *func, int line)
{
mallctl_bool_set("thread.prof.active", thread_prof_active_old_expected,
thread_prof_active_new, func, line);
}
#define mallctl_thread_prof_active_set(a, b) \
mallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__)
static void
prof_sampling_probe_impl(bool expect_sample, const char *func, int line)
{
void *p;
size_t expected_backtraces = expect_sample ? 1 : 0;
assert_zu_eq(prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func,
line);
p = mallocx(1, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_zu_eq(prof_bt_count(), expected_backtraces,
"%s():%d: Unexpected backtrace count", func, line);
dallocx(p, 0);
}
#define prof_sampling_probe(a) \
prof_sampling_probe_impl(a, __func__, __LINE__)
TEST_BEGIN(test_prof_active)
{
test_skip_if(!config_prof);
mallctl_prof_active_get(true);
mallctl_thread_prof_active_get(false);
mallctl_prof_active_set(true, true);
mallctl_thread_prof_active_set(false, false);
/* prof.active, !thread.prof.active. */
prof_sampling_probe(false);
mallctl_prof_active_set(true, false);
mallctl_thread_prof_active_set(false, false);
/* !prof.active, !thread.prof.active. */
prof_sampling_probe(false);
mallctl_prof_active_set(false, false);
mallctl_thread_prof_active_set(false, true);
/* !prof.active, thread.prof.active. */
prof_sampling_probe(false);
mallctl_prof_active_set(false, true);
mallctl_thread_prof_active_set(true, true);
/* prof.active, thread.prof.active. */
prof_sampling_probe(true);
/* Restore settings. */
mallctl_prof_active_set(true, true);
mallctl_thread_prof_active_set(true, false);
}
TEST_END
int
main(void)
{
return (test(
test_prof_active));
}
......@@ -21,8 +21,9 @@ prof_dump_open_intercept(bool propagate_err, const char *filename)
TEST_BEGIN(test_gdump)
{
bool active;
void *p, *q;
bool active, gdump, gdump_old;
void *p, *q, *r, *s;
size_t sz;
test_skip_if(!config_prof);
......@@ -42,8 +43,32 @@ TEST_BEGIN(test_gdump)
assert_ptr_not_null(q, "Unexpected mallocx() failure");
assert_true(did_prof_dump_open, "Expected a profile dump");
gdump = false;
sz = sizeof(gdump_old);
assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump,
sizeof(gdump)), 0,
"Unexpected mallctl failure while disabling prof.gdump");
assert(gdump_old);
did_prof_dump_open = false;
r = mallocx(chunksize, 0);
assert_ptr_not_null(q, "Unexpected mallocx() failure");
assert_false(did_prof_dump_open, "Unexpected profile dump");
gdump = true;
sz = sizeof(gdump_old);
assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump,
sizeof(gdump)), 0,
"Unexpected mallctl failure while enabling prof.gdump");
assert(!gdump_old);
did_prof_dump_open = false;
s = mallocx(chunksize, 0);
assert_ptr_not_null(q, "Unexpected mallocx() failure");
assert_true(did_prof_dump_open, "Expected a profile dump");
dallocx(p, 0);
dallocx(q, 0);
dallocx(r, 0);
dallocx(s, 0);
}
TEST_END
......
#include "test/jemalloc_test.h"
#ifdef JEMALLOC_PROF
const char *malloc_conf =
"prof:true,prof_active:false,lg_prof_sample:0";
#endif
static int
prof_dump_open_intercept(bool propagate_err, const char *filename)
{
int fd;
fd = open("/dev/null", O_WRONLY);
assert_d_ne(fd, -1, "Unexpected open() failure");
return (fd);
}
static void
set_prof_active(bool active)
{
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
0, "Unexpected mallctl failure");
}
static size_t
get_lg_prof_sample(void)
{
size_t lg_prof_sample;
size_t sz = sizeof(size_t);
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0,
"Unexpected mallctl failure while reading profiling sample rate");
return (lg_prof_sample);
}
static void
do_prof_reset(size_t lg_prof_sample)
{
assert_d_eq(mallctl("prof.reset", NULL, NULL,
&lg_prof_sample, sizeof(size_t)), 0,
"Unexpected mallctl failure while resetting profile data");
assert_zu_eq(lg_prof_sample, get_lg_prof_sample(),
"Expected profile sample rate change");
}
TEST_BEGIN(test_prof_reset_basic)
{
size_t lg_prof_sample_orig, lg_prof_sample, lg_prof_sample_next;
size_t sz;
unsigned i;
test_skip_if(!config_prof);
sz = sizeof(size_t);
assert_d_eq(mallctl("opt.lg_prof_sample", &lg_prof_sample_orig, &sz,
NULL, 0), 0,
"Unexpected mallctl failure while reading profiling sample rate");
assert_zu_eq(lg_prof_sample_orig, 0,
"Unexpected profiling sample rate");
lg_prof_sample = get_lg_prof_sample();
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
"\"prof.lg_sample\"");
/* Test simple resets. */
for (i = 0; i < 2; i++) {
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl failure while resetting profile data");
lg_prof_sample = get_lg_prof_sample();
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
"Unexpected profile sample rate change");
}
/* Test resets with prof.lg_sample changes. */
lg_prof_sample_next = 1;
for (i = 0; i < 2; i++) {
do_prof_reset(lg_prof_sample_next);
lg_prof_sample = get_lg_prof_sample();
assert_zu_eq(lg_prof_sample, lg_prof_sample_next,
"Expected profile sample rate change");
lg_prof_sample_next = lg_prof_sample_orig;
}
/* Make sure the test code restored prof.lg_sample. */
lg_prof_sample = get_lg_prof_sample();
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
"\"prof.lg_sample\"");
}
TEST_END
bool prof_dump_header_intercepted = false;
prof_cnt_t cnt_all_copy = {0, 0, 0, 0};
static bool
prof_dump_header_intercept(bool propagate_err, const prof_cnt_t *cnt_all)
{
prof_dump_header_intercepted = true;
memcpy(&cnt_all_copy, cnt_all, sizeof(prof_cnt_t));
return (false);
}
TEST_BEGIN(test_prof_reset_cleanup)
{
void *p;
prof_dump_header_t *prof_dump_header_orig;
test_skip_if(!config_prof);
set_prof_active(true);
assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces");
p = mallocx(1, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_zu_eq(prof_bt_count(), 1, "Expected 1 backtrace");
prof_dump_header_orig = prof_dump_header;
prof_dump_header = prof_dump_header_intercept;
assert_false(prof_dump_header_intercepted, "Unexpected intercept");
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
0, "Unexpected error while dumping heap profile");
assert_true(prof_dump_header_intercepted, "Expected intercept");
assert_u64_eq(cnt_all_copy.curobjs, 1, "Expected 1 allocation");
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
"Unexpected error while resetting heap profile data");
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
0, "Unexpected error while dumping heap profile");
assert_u64_eq(cnt_all_copy.curobjs, 0, "Expected 0 allocations");
assert_zu_eq(prof_bt_count(), 1, "Expected 1 backtrace");
prof_dump_header = prof_dump_header_orig;
dallocx(p, 0);
assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces");
set_prof_active(false);
}
TEST_END
#define NTHREADS 4
#define NALLOCS_PER_THREAD (1U << 13)
#define OBJ_RING_BUF_COUNT 1531
#define RESET_INTERVAL (1U << 10)
#define DUMP_INTERVAL 3677
static void *
thd_start(void *varg)
{
unsigned thd_ind = *(unsigned *)varg;
unsigned i;
void *objs[OBJ_RING_BUF_COUNT];
memset(objs, 0, sizeof(objs));
for (i = 0; i < NALLOCS_PER_THREAD; i++) {
if (i % RESET_INTERVAL == 0) {
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0),
0, "Unexpected error while resetting heap profile "
"data");
}
if (i % DUMP_INTERVAL == 0) {
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
0, "Unexpected error while dumping heap profile");
}
{
void **pp = &objs[i % OBJ_RING_BUF_COUNT];
if (*pp != NULL) {
dallocx(*pp, 0);
*pp = NULL;
}
*pp = btalloc(1, thd_ind*NALLOCS_PER_THREAD + i);
assert_ptr_not_null(*pp,
"Unexpected btalloc() failure");
}
}
/* Clean up any remaining objects. */
for (i = 0; i < OBJ_RING_BUF_COUNT; i++) {
void **pp = &objs[i % OBJ_RING_BUF_COUNT];
if (*pp != NULL) {
dallocx(*pp, 0);
*pp = NULL;
}
}
return (NULL);
}
TEST_BEGIN(test_prof_reset)
{
size_t lg_prof_sample_orig;
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
size_t bt_count, tdata_count;
test_skip_if(!config_prof);
bt_count = prof_bt_count();
assert_zu_eq(bt_count, 0,
"Unexpected pre-existing tdata structures");
tdata_count = prof_tdata_count();
lg_prof_sample_orig = get_lg_prof_sample();
do_prof_reset(5);
set_prof_active(true);
for (i = 0; i < NTHREADS; i++) {
thd_args[i] = i;
thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
}
for (i = 0; i < NTHREADS; i++)
thd_join(thds[i], NULL);
assert_zu_eq(prof_bt_count(), bt_count,
"Unexpected bactrace count change");
assert_zu_eq(prof_tdata_count(), tdata_count,
"Unexpected remaining tdata structures");
set_prof_active(false);
do_prof_reset(lg_prof_sample_orig);
}
TEST_END
#undef NTHREADS
#undef NALLOCS_PER_THREAD
#undef OBJ_RING_BUF_COUNT
#undef RESET_INTERVAL
#undef DUMP_INTERVAL
/* Test sampling at the same allocation site across resets. */
#define NITER 10
TEST_BEGIN(test_xallocx)
{
size_t lg_prof_sample_orig;
unsigned i;
void *ptrs[NITER];
test_skip_if(!config_prof);
lg_prof_sample_orig = get_lg_prof_sample();
set_prof_active(true);
/* Reset profiling. */
do_prof_reset(0);
for (i = 0; i < NITER; i++) {
void *p;
size_t sz, nsz;
/* Reset profiling. */
do_prof_reset(0);
/* Allocate small object (which will be promoted). */
p = ptrs[i] = mallocx(1, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
/* Reset profiling. */
do_prof_reset(0);
/* Perform successful xallocx(). */
sz = sallocx(p, 0);
assert_zu_eq(xallocx(p, sz, 0, 0), sz,
"Unexpected xallocx() failure");
/* Perform unsuccessful xallocx(). */
nsz = nallocx(sz+1, 0);
assert_zu_eq(xallocx(p, nsz, 0, 0), sz,
"Unexpected xallocx() success");
}
for (i = 0; i < NITER; i++) {
/* dallocx. */
dallocx(ptrs[i], 0);
}
set_prof_active(false);
do_prof_reset(lg_prof_sample_orig);
}
TEST_END
#undef NITER
int
main(void)
{
/* Intercept dumping prior to running any tests. */
prof_dump_open = prof_dump_open_intercept;
return (test(
test_prof_reset_basic,
test_prof_reset_cleanup,
test_prof_reset,
test_xallocx));
}
#include "test/jemalloc_test.h"
#ifdef JEMALLOC_PROF
const char *malloc_conf = "prof:true,prof_active:false";
#endif
static void
mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,
int line)
{
const char *thread_name_old;
size_t sz;
sz = sizeof(thread_name_old);
assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz, NULL, 0),
0, "%s():%d: Unexpected mallctl failure reading thread.prof.name",
func, line);
assert_str_eq(thread_name_old, thread_name_expected,
"%s():%d: Unexpected thread.prof.name value", func, line);
}
#define mallctl_thread_name_get(a) \
mallctl_thread_name_get_impl(a, __func__, __LINE__)
static void
mallctl_thread_name_set_impl(const char *thread_name, const char *func,
int line)
{
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
sizeof(thread_name)), 0,
"%s():%d: Unexpected mallctl failure reading thread.prof.name",
func, line);
mallctl_thread_name_get_impl(thread_name, func, line);
}
#define mallctl_thread_name_set(a) \
mallctl_thread_name_set_impl(a, __func__, __LINE__)
TEST_BEGIN(test_prof_thread_name_validation)
{
const char *thread_name;
test_skip_if(!config_prof);
mallctl_thread_name_get("");
mallctl_thread_name_set("hi there");
/* NULL input shouldn't be allowed. */
thread_name = NULL;
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
sizeof(thread_name)), EFAULT,
"Unexpected mallctl result writing \"%s\" to thread.prof.name",
thread_name);
/* '\n' shouldn't be allowed. */
thread_name = "hi\nthere";
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
sizeof(thread_name)), EFAULT,
"Unexpected mallctl result writing \"%s\" to thread.prof.name",
thread_name);
/* Simultaneous read/write shouldn't be allowed. */
{
const char *thread_name_old;
size_t sz;
sz = sizeof(thread_name_old);
assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz,
&thread_name, sizeof(thread_name)), EPERM,
"Unexpected mallctl result writing \"%s\" to "
"thread.prof.name", thread_name);
}
mallctl_thread_name_set("");
}
TEST_END
#define NTHREADS 4
#define NRESET 25
static void *
thd_start(void *varg)
{
unsigned thd_ind = *(unsigned *)varg;
char thread_name[16] = "";
unsigned i;
malloc_snprintf(thread_name, sizeof(thread_name), "thread %u", thd_ind);
mallctl_thread_name_get("");
mallctl_thread_name_set(thread_name);
for (i = 0; i < NRESET; i++) {
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
"Unexpected error while resetting heap profile data");
mallctl_thread_name_get(thread_name);
}
mallctl_thread_name_set(thread_name);
mallctl_thread_name_set("");
return (NULL);
}
TEST_BEGIN(test_prof_thread_name_threaded)
{
thd_t thds[NTHREADS];
unsigned thd_args[NTHREADS];
unsigned i;
test_skip_if(!config_prof);
for (i = 0; i < NTHREADS; i++) {
thd_args[i] = i;
thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
}
for (i = 0; i < NTHREADS; i++)
thd_join(thds[i], NULL);
}
TEST_END
#undef NTHREADS
#undef NRESET
int
main(void)
{
return (test(
test_prof_thread_name_validation,
test_prof_thread_name_threaded));
}
......@@ -5,7 +5,7 @@
for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0; \
rbp_bh_t != &(a_rbt)->rbt_nil; \
rbp_bh_t = rbtn_left_get(a_type, a_field, rbp_bh_t)) { \
if (rbtn_red_get(a_type, a_field, rbp_bh_t) == false) { \
if (!rbtn_red_get(a_type, a_field, rbp_bh_t)) { \
(r_height)++; \
} \
} \
......@@ -49,6 +49,7 @@ TEST_BEGIN(test_rb_empty)
tree_new(&tree);
assert_true(tree_empty(&tree), "Tree should be empty");
assert_ptr_null(tree_first(&tree), "Unexpected node");
assert_ptr_null(tree_last(&tree), "Unexpected node");
......@@ -74,7 +75,7 @@ tree_recurse(node_t *node, unsigned black_height, unsigned black_depth,
node_t *left_node = rbtn_left_get(node_t, link, node);
node_t *right_node = rbtn_right_get(node_t, link, node);
if (rbtn_red_get(node_t, link, node) == false)
if (!rbtn_red_get(node_t, link, node))
black_depth++;
/* Red nodes must be interleaved with black nodes. */
......@@ -265,6 +266,8 @@ TEST_BEGIN(test_rb_random)
assert_u_eq(tree_iterate_reverse(&tree), k+1,
"Unexpected node iteration count");
assert_false(tree_empty(&tree),
"Tree should not be empty");
assert_ptr_not_null(tree_first(&tree),
"Tree should not be empty");
assert_ptr_not_null(tree_last(&tree),
......
#include "test/jemalloc_test.h"
static rtree_node_elm_t *
node_alloc(size_t nelms)
{
return ((rtree_node_elm_t *)calloc(nelms, sizeof(rtree_node_elm_t)));
}
static void
node_dalloc(rtree_node_elm_t *node)
{
free(node);
}
TEST_BEGIN(test_rtree_get_empty)
{
unsigned i;
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
rtree_t *rtree = rtree_new(i, imalloc, idalloc);
assert_u_eq(rtree_get(rtree, 0), 0,
rtree_t rtree;
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
"Unexpected rtree_new() failure");
assert_ptr_null(rtree_get(&rtree, 0, false),
"rtree_get() should return NULL for empty tree");
rtree_delete(rtree);
rtree_delete(&rtree);
}
}
TEST_END
......@@ -16,19 +32,24 @@ TEST_END
TEST_BEGIN(test_rtree_extrema)
{
unsigned i;
extent_node_t node_a, node_b;
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
rtree_t *rtree = rtree_new(i, imalloc, idalloc);
rtree_t rtree;
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
"Unexpected rtree_new() failure");
rtree_set(rtree, 0, 1);
assert_u_eq(rtree_get(rtree, 0), 1,
assert_false(rtree_set(&rtree, 0, &node_a),
"Unexpected rtree_set() failure");
assert_ptr_eq(rtree_get(&rtree, 0, true), &node_a,
"rtree_get() should return previously set value");
rtree_set(rtree, ~((uintptr_t)0), 1);
assert_u_eq(rtree_get(rtree, ~((uintptr_t)0)), 1,
assert_false(rtree_set(&rtree, ~((uintptr_t)0), &node_b),
"Unexpected rtree_set() failure");
assert_ptr_eq(rtree_get(&rtree, ~((uintptr_t)0), true), &node_b,
"rtree_get() should return previously set value");
rtree_delete(rtree);
rtree_delete(&rtree);
}
}
TEST_END
......@@ -40,26 +61,32 @@ TEST_BEGIN(test_rtree_bits)
for (i = 1; i < (sizeof(uintptr_t) << 3); i++) {
uintptr_t keys[] = {0, 1,
(((uintptr_t)1) << (sizeof(uintptr_t)*8-i)) - 1};
rtree_t *rtree = rtree_new(i, imalloc, idalloc);
extent_node_t node;
rtree_t rtree;
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
"Unexpected rtree_new() failure");
for (j = 0; j < sizeof(keys)/sizeof(uintptr_t); j++) {
rtree_set(rtree, keys[j], 1);
assert_false(rtree_set(&rtree, keys[j], &node),
"Unexpected rtree_set() failure");
for (k = 0; k < sizeof(keys)/sizeof(uintptr_t); k++) {
assert_u_eq(rtree_get(rtree, keys[k]), 1,
"rtree_get() should return previously set "
"value and ignore insignificant key bits; "
"i=%u, j=%u, k=%u, set key=%#"PRIxPTR", "
"get key=%#"PRIxPTR, i, j, k, keys[j],
keys[k]);
assert_ptr_eq(rtree_get(&rtree, keys[k], true),
&node, "rtree_get() should return "
"previously set value and ignore "
"insignificant key bits; i=%u, j=%u, k=%u, "
"set key=%#"FMTxPTR", get key=%#"FMTxPTR, i,
j, k, keys[j], keys[k]);
}
assert_u_eq(rtree_get(rtree,
(((uintptr_t)1) << (sizeof(uintptr_t)*8-i))), 0,
assert_ptr_null(rtree_get(&rtree,
(((uintptr_t)1) << (sizeof(uintptr_t)*8-i)), false),
"Only leftmost rtree leaf should be set; "
"i=%u, j=%u", i, j);
rtree_set(rtree, keys[j], 0);
assert_false(rtree_set(&rtree, keys[j], NULL),
"Unexpected rtree_set() failure");
}
rtree_delete(rtree);
rtree_delete(&rtree);
}
}
TEST_END
......@@ -68,37 +95,43 @@ TEST_BEGIN(test_rtree_random)
{
unsigned i;
sfmt_t *sfmt;
#define NSET 100
#define NSET 16
#define SEED 42
sfmt = init_gen_rand(SEED);
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
rtree_t *rtree = rtree_new(i, imalloc, idalloc);
uintptr_t keys[NSET];
extent_node_t node;
unsigned j;
rtree_t rtree;
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
"Unexpected rtree_new() failure");
for (j = 0; j < NSET; j++) {
keys[j] = (uintptr_t)gen_rand64(sfmt);
rtree_set(rtree, keys[j], 1);
assert_u_eq(rtree_get(rtree, keys[j]), 1,
assert_false(rtree_set(&rtree, keys[j], &node),
"Unexpected rtree_set() failure");
assert_ptr_eq(rtree_get(&rtree, keys[j], true), &node,
"rtree_get() should return previously set value");
}
for (j = 0; j < NSET; j++) {
assert_u_eq(rtree_get(rtree, keys[j]), 1,
assert_ptr_eq(rtree_get(&rtree, keys[j], true), &node,
"rtree_get() should return previously set value");
}
for (j = 0; j < NSET; j++) {
rtree_set(rtree, keys[j], 0);
assert_u_eq(rtree_get(rtree, keys[j]), 0,
assert_false(rtree_set(&rtree, keys[j], NULL),
"Unexpected rtree_set() failure");
assert_ptr_null(rtree_get(&rtree, keys[j], true),
"rtree_get() should return previously set value");
}
for (j = 0; j < NSET; j++) {
assert_u_eq(rtree_get(rtree, keys[j]), 0,
assert_ptr_null(rtree_get(&rtree, keys[j], true),
"rtree_get() should return previously set value");
}
rtree_delete(rtree);
rtree_delete(&rtree);
}
fini_gen_rand(sfmt);
#undef NSET
......
#include "test/jemalloc_test.h"
static size_t
get_max_size_class(void)
{
unsigned nhchunks;
size_t mib[4];
size_t sz, miblen, max_size_class;
sz = sizeof(unsigned);
assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0,
"Unexpected mallctl() error");
miblen = sizeof(mib) / sizeof(size_t);
assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0,
"Unexpected mallctlnametomib() error");
mib[2] = nhchunks - 1;
sz = sizeof(size_t);
assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0,
"Unexpected mallctlbymib() error");
return (max_size_class);
}
TEST_BEGIN(test_size_classes)
{
size_t size_class, max_size_class;
szind_t index, max_index;
max_size_class = get_max_size_class();
max_index = size2index(max_size_class);
for (index = 0, size_class = index2size(index); index < max_index ||
size_class < max_size_class; index++, size_class =
index2size(index)) {
assert_true(index < max_index,
"Loop conditionals should be equivalent; index=%u, "
"size_class=%zu (%#zx)", index, size_class, size_class);
assert_true(size_class < max_size_class,
"Loop conditionals should be equivalent; index=%u, "
"size_class=%zu (%#zx)", index, size_class, size_class);
assert_u_eq(index, size2index(size_class),
"size2index() does not reverse index2size(): index=%u -->"
" size_class=%zu --> index=%u --> size_class=%zu", index,
size_class, size2index(size_class),
index2size(size2index(size_class)));
assert_zu_eq(size_class, index2size(size2index(size_class)),
"index2size() does not reverse size2index(): index=%u -->"
" size_class=%zu --> index=%u --> size_class=%zu", index,
size_class, size2index(size_class),
index2size(size2index(size_class)));
assert_u_eq(index+1, size2index(size_class+1),
"Next size_class does not round up properly");
assert_zu_eq(size_class, (index > 0) ?
s2u(index2size(index-1)+1) : s2u(1),
"s2u() does not round up to size class");
assert_zu_eq(size_class, s2u(size_class-1),
"s2u() does not round up to size class");
assert_zu_eq(size_class, s2u(size_class),
"s2u() does not compute same size class");
assert_zu_eq(s2u(size_class+1), index2size(index+1),
"s2u() does not round up to next size class");
}
assert_u_eq(index, size2index(index2size(index)),
"size2index() does not reverse index2size()");
assert_zu_eq(max_size_class, index2size(size2index(max_size_class)),
"index2size() does not reverse size2index()");
assert_zu_eq(size_class, s2u(index2size(index-1)+1),
"s2u() does not round up to size class");
assert_zu_eq(size_class, s2u(size_class-1),
"s2u() does not round up to size class");
assert_zu_eq(size_class, s2u(size_class),
"s2u() does not compute same size class");
}
TEST_END
int
main(void)
{
return (test(
test_size_classes));
}
......@@ -3,7 +3,7 @@
TEST_BEGIN(test_stats_summary)
{
size_t *cactive;
size_t sz, allocated, active, mapped;
size_t sz, allocated, active, resident, mapped;
int expected = config_stats ? 0 : ENOENT;
sz = sizeof(cactive);
......@@ -15,6 +15,8 @@ TEST_BEGIN(test_stats_summary)
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
assert_d_eq(mallctl("stats.resident", &resident, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
......@@ -23,34 +25,10 @@ TEST_BEGIN(test_stats_summary)
"active should be no larger than cactive");
assert_zu_le(allocated, active,
"allocated should be no larger than active");
assert_zu_le(active, mapped,
"active should be no larger than mapped");
}
}
TEST_END
TEST_BEGIN(test_stats_chunks)
{
size_t current, high;
uint64_t total;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.chunks.current", &current, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.chunks.total", &total, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.chunks.high", &high, &sz, NULL, 0), expected,
"Unexpected mallctl() result");
if (config_stats) {
assert_zu_le(current, high,
"current should be no larger than high");
assert_u64_le((uint64_t)high, total,
"high should be no larger than total");
assert_zu_lt(active, resident,
"active should be less than resident");
assert_zu_lt(active, mapped,
"active should be less than mapped");
}
}
TEST_END
......@@ -60,30 +38,34 @@ TEST_BEGIN(test_stats_huge)
void *p;
uint64_t epoch;
size_t allocated;
uint64_t nmalloc, ndalloc;
uint64_t nmalloc, ndalloc, nrequests;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
p = mallocx(arena_maxclass+1, 0);
p = mallocx(large_maxclass+1, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.huge.allocated", &allocated, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.huge.nmalloc", &nmalloc, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.huge.ndalloc", &ndalloc, &sz, NULL, 0),
expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz, NULL,
0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz, NULL,
0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
"allocated should be greater than zero");
assert_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
assert_u64_le(nmalloc, nrequests,
"nmalloc should no larger than nrequests");
}
dallocx(p, 0);
......@@ -93,7 +75,7 @@ TEST_END
TEST_BEGIN(test_stats_arenas_summary)
{
unsigned arena;
void *small, *large;
void *little, *large, *huge;
uint64_t epoch;
size_t sz;
int expected = config_stats ? 0 : ENOENT;
......@@ -104,10 +86,12 @@ TEST_BEGIN(test_stats_arenas_summary)
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
small = mallocx(SMALL_MAXCLASS, 0);
assert_ptr_not_null(small, "Unexpected mallocx() failure");
large = mallocx(arena_maxclass, 0);
little = mallocx(SMALL_MAXCLASS, 0);
assert_ptr_not_null(little, "Unexpected mallocx() failure");
large = mallocx(large_maxclass, 0);
assert_ptr_not_null(large, "Unexpected mallocx() failure");
huge = mallocx(chunksize, 0);
assert_ptr_not_null(huge, "Unexpected mallocx() failure");
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
"Unexpected mallctl() failure");
......@@ -133,8 +117,9 @@ TEST_BEGIN(test_stats_arenas_summary)
"nmadvise should be no greater than purged");
}
dallocx(small, 0);
dallocx(little, 0);
dallocx(large, 0);
dallocx(huge, 0);
}
TEST_END
......@@ -215,7 +200,7 @@ TEST_BEGIN(test_stats_arenas_large)
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(arena_maxclass, 0);
p = mallocx(large_maxclass, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
......@@ -247,11 +232,51 @@ TEST_BEGIN(test_stats_arenas_large)
}
TEST_END
TEST_BEGIN(test_stats_arenas_huge)
{
unsigned arena;
void *p;
size_t sz, allocated;
uint64_t epoch, nmalloc, ndalloc;
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(chunksize, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
"allocated should be greater than zero");
assert_zu_gt(nmalloc, 0,
"nmalloc should be greater than zero");
assert_zu_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
}
dallocx(p, 0);
}
TEST_END
TEST_BEGIN(test_stats_arenas_bins)
{
unsigned arena;
void *p;
size_t sz, allocated, curruns;
size_t sz, curruns, curregs;
uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;
uint64_t nruns, nreruns;
int expected = config_stats ? 0 : ENOENT;
......@@ -269,9 +294,6 @@ TEST_BEGIN(test_stats_arenas_bins)
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.allocated", &allocated, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
......@@ -279,7 +301,11 @@ TEST_BEGIN(test_stats_arenas_bins)
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests", &nrequests, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", &curregs, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz,
NULL, 0), config_tcache ? expected : ENOENT,
"Unexpected mallctl() result");
......@@ -296,14 +322,14 @@ TEST_BEGIN(test_stats_arenas_bins)
NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_zu_gt(allocated, 0,
"allocated should be greater than zero");
assert_u64_gt(nmalloc, 0,
"nmalloc should be greater than zero");
assert_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
assert_u64_gt(nrequests, 0,
"nrequests should be greater than zero");
assert_zu_gt(curregs, 0,
"allocated should be greater than zero");
if (config_tcache) {
assert_u64_gt(nfills, 0,
"At least one fill should have occurred");
......@@ -332,7 +358,7 @@ TEST_BEGIN(test_stats_arenas_lruns)
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(SMALL_MAXCLASS+1, 0);
p = mallocx(LARGE_MINCLASS, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
......@@ -364,17 +390,58 @@ TEST_BEGIN(test_stats_arenas_lruns)
}
TEST_END
TEST_BEGIN(test_stats_arenas_hchunks)
{
unsigned arena;
void *p;
uint64_t epoch, nmalloc, ndalloc;
size_t curhchunks, sz;
int expected = config_stats ? 0 : ENOENT;
arena = 0;
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
0, "Unexpected mallctl() failure");
p = mallocx(chunksize, 0);
assert_ptr_not_null(p, "Unexpected mallocx() failure");
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
"Unexpected mallctl() failure");
sz = sizeof(uint64_t);
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc", &nmalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc", &ndalloc, &sz,
NULL, 0), expected, "Unexpected mallctl() result");
sz = sizeof(size_t);
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks", &curhchunks,
&sz, NULL, 0), expected, "Unexpected mallctl() result");
if (config_stats) {
assert_u64_gt(nmalloc, 0,
"nmalloc should be greater than zero");
assert_u64_ge(nmalloc, ndalloc,
"nmalloc should be at least as large as ndalloc");
assert_u64_gt(curhchunks, 0,
"At least one chunk should be currently allocated");
}
dallocx(p, 0);
}
TEST_END
int
main(void)
{
return (test(
test_stats_summary,
test_stats_chunks,
test_stats_huge,
test_stats_arenas_summary,
test_stats_arenas_small,
test_stats_arenas_large,
test_stats_arenas_huge,
test_stats_arenas_bins,
test_stats_arenas_lruns));
test_stats_arenas_lruns,
test_stats_arenas_hchunks));
}
......@@ -6,29 +6,64 @@ typedef unsigned int data_t;
static bool data_cleanup_executed;
malloc_tsd_types(data_, data_t)
malloc_tsd_protos(, data_, data_t)
void
data_cleanup(void *arg)
{
data_t *data = (data_t *)arg;
if (!data_cleanup_executed) {
assert_x_eq(*data, THREAD_DATA,
"Argument passed into cleanup function should match tsd value");
"Argument passed into cleanup function should match tsd "
"value");
}
data_cleanup_executed = true;
/*
* Allocate during cleanup for two rounds, in order to assure that
* jemalloc's internal tsd reinitialization happens.
*/
switch (*data) {
case THREAD_DATA:
*data = 1;
data_tsd_set(data);
break;
case 1:
*data = 2;
data_tsd_set(data);
break;
case 2:
return;
default:
not_reached();
}
{
void *p = mallocx(1, 0);
assert_ptr_not_null(p, "Unexpeced mallocx() failure");
dallocx(p, 0);
}
}
malloc_tsd_protos(, data, data_t)
malloc_tsd_externs(data, data_t)
malloc_tsd_externs(data_, data_t)
#define DATA_INIT 0x12345678
malloc_tsd_data(, data, data_t, DATA_INIT)
malloc_tsd_funcs(, data, data_t, DATA_INIT, data_cleanup)
malloc_tsd_data(, data_, data_t, DATA_INIT)
malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup)
static void *
thd_start(void *arg)
{
data_t d = (data_t)(uintptr_t)arg;
void *p;
assert_x_eq(*data_tsd_get(), DATA_INIT,
"Initial tsd get should return initialization value");
p = malloc(1);
assert_ptr_not_null(p, "Unexpected malloc() failure");
data_tsd_set(&d);
assert_x_eq(*data_tsd_get(), d,
"After tsd set, tsd get should return value that was set");
......@@ -37,6 +72,7 @@ thd_start(void *arg)
assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg,
"Resetting local data should have no effect on tsd");
free(p);
return (NULL);
}
......
......@@ -53,7 +53,7 @@ TEST_BEGIN(test_malloc_strtoumax)
uintmax_t expected_x;
};
#define ERR(e) e, #e
#define UMAX(x) ((uintmax_t)x##ULL)
#define KUMAX(x) ((uintmax_t)x##ULL)
struct test_s tests[] = {
{"0", "0", -1, ERR(EINVAL), UINTMAX_MAX},
{"0", "0", 1, ERR(EINVAL), UINTMAX_MAX},
......@@ -64,51 +64,51 @@ TEST_BEGIN(test_malloc_strtoumax)
{"++3", "++3", 0, ERR(EINVAL), UINTMAX_MAX},
{"-", "-", 0, ERR(EINVAL), UINTMAX_MAX},
{"42", "", 0, ERR(0), UMAX(42)},
{"+42", "", 0, ERR(0), UMAX(42)},
{"-42", "", 0, ERR(0), UMAX(-42)},
{"042", "", 0, ERR(0), UMAX(042)},
{"+042", "", 0, ERR(0), UMAX(042)},
{"-042", "", 0, ERR(0), UMAX(-042)},
{"0x42", "", 0, ERR(0), UMAX(0x42)},
{"+0x42", "", 0, ERR(0), UMAX(0x42)},
{"-0x42", "", 0, ERR(0), UMAX(-0x42)},
{"0", "", 0, ERR(0), UMAX(0)},
{"1", "", 0, ERR(0), UMAX(1)},
{"42", "", 0, ERR(0), UMAX(42)},
{" 42", "", 0, ERR(0), UMAX(42)},
{"42 ", " ", 0, ERR(0), UMAX(42)},
{"0x", "x", 0, ERR(0), UMAX(0)},
{"42x", "x", 0, ERR(0), UMAX(42)},
{"07", "", 0, ERR(0), UMAX(7)},
{"010", "", 0, ERR(0), UMAX(8)},
{"08", "8", 0, ERR(0), UMAX(0)},
{"0_", "_", 0, ERR(0), UMAX(0)},
{"0x", "x", 0, ERR(0), UMAX(0)},
{"0X", "X", 0, ERR(0), UMAX(0)},
{"0xg", "xg", 0, ERR(0), UMAX(0)},
{"0XA", "", 0, ERR(0), UMAX(10)},
{"010", "", 10, ERR(0), UMAX(10)},
{"0x3", "x3", 10, ERR(0), UMAX(0)},
{"12", "2", 2, ERR(0), UMAX(1)},
{"78", "8", 8, ERR(0), UMAX(7)},
{"9a", "a", 10, ERR(0), UMAX(9)},
{"9A", "A", 10, ERR(0), UMAX(9)},
{"fg", "g", 16, ERR(0), UMAX(15)},
{"FG", "G", 16, ERR(0), UMAX(15)},
{"0xfg", "g", 16, ERR(0), UMAX(15)},
{"0XFG", "G", 16, ERR(0), UMAX(15)},
{"z_", "_", 36, ERR(0), UMAX(35)},
{"Z_", "_", 36, ERR(0), UMAX(35)}
{"42", "", 0, ERR(0), KUMAX(42)},
{"+42", "", 0, ERR(0), KUMAX(42)},
{"-42", "", 0, ERR(0), KUMAX(-42)},
{"042", "", 0, ERR(0), KUMAX(042)},
{"+042", "", 0, ERR(0), KUMAX(042)},
{"-042", "", 0, ERR(0), KUMAX(-042)},
{"0x42", "", 0, ERR(0), KUMAX(0x42)},
{"+0x42", "", 0, ERR(0), KUMAX(0x42)},
{"-0x42", "", 0, ERR(0), KUMAX(-0x42)},
{"0", "", 0, ERR(0), KUMAX(0)},
{"1", "", 0, ERR(0), KUMAX(1)},
{"42", "", 0, ERR(0), KUMAX(42)},
{" 42", "", 0, ERR(0), KUMAX(42)},
{"42 ", " ", 0, ERR(0), KUMAX(42)},
{"0x", "x", 0, ERR(0), KUMAX(0)},
{"42x", "x", 0, ERR(0), KUMAX(42)},
{"07", "", 0, ERR(0), KUMAX(7)},
{"010", "", 0, ERR(0), KUMAX(8)},
{"08", "8", 0, ERR(0), KUMAX(0)},
{"0_", "_", 0, ERR(0), KUMAX(0)},
{"0x", "x", 0, ERR(0), KUMAX(0)},
{"0X", "X", 0, ERR(0), KUMAX(0)},
{"0xg", "xg", 0, ERR(0), KUMAX(0)},
{"0XA", "", 0, ERR(0), KUMAX(10)},
{"010", "", 10, ERR(0), KUMAX(10)},
{"0x3", "x3", 10, ERR(0), KUMAX(0)},
{"12", "2", 2, ERR(0), KUMAX(1)},
{"78", "8", 8, ERR(0), KUMAX(7)},
{"9a", "a", 10, ERR(0), KUMAX(9)},
{"9A", "A", 10, ERR(0), KUMAX(9)},
{"fg", "g", 16, ERR(0), KUMAX(15)},
{"FG", "G", 16, ERR(0), KUMAX(15)},
{"0xfg", "g", 16, ERR(0), KUMAX(15)},
{"0XFG", "G", 16, ERR(0), KUMAX(15)},
{"z_", "_", 36, ERR(0), KUMAX(35)},
{"Z_", "_", 36, ERR(0), KUMAX(35)}
};
#undef ERR
#undef UMAX
#undef KUMAX
unsigned i;
for (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) {
......@@ -141,8 +141,8 @@ TEST_BEGIN(test_malloc_snprintf_truncated)
char buf[BUFLEN];
int result;
size_t len;
#define TEST(expected_str_untruncated, fmt...) do { \
result = malloc_snprintf(buf, len, fmt); \
#define TEST(expected_str_untruncated, ...) do { \
result = malloc_snprintf(buf, len, __VA_ARGS__); \
assert_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0, \
"Unexpected string inequality (\"%s\" vs \"%s\")", \
buf, expected_str_untruncated); \
......@@ -173,8 +173,8 @@ TEST_BEGIN(test_malloc_snprintf)
#define BUFLEN 128
char buf[BUFLEN];
int result;
#define TEST(expected_str, fmt...) do { \
result = malloc_snprintf(buf, sizeof(buf), fmt); \
#define TEST(expected_str, ...) do { \
result = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__); \
assert_str_eq(buf, expected_str, "Unexpected output"); \
assert_d_eq(result, strlen(expected_str), "Unexpected result"); \
} while (0)
......
......@@ -55,7 +55,7 @@ TEST_BEGIN(test_zero_large)
{
test_skip_if(!config_fill);
test_zero(SMALL_MAXCLASS+1, arena_maxclass);
test_zero(SMALL_MAXCLASS+1, large_maxclass);
}
TEST_END
......@@ -63,7 +63,7 @@ TEST_BEGIN(test_zero_huge)
{
test_skip_if(!config_fill);
test_zero(arena_maxclass+1, chunksize*2);
test_zero(large_maxclass+1, chunksize*2);
}
TEST_END
......
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