mirror of
https://github.com/fluencelabs/redis
synced 2025-07-31 08:22:01 +00:00
Jemalloc updated to 3.6.0.
Not a single bug in about 3 months, and our previous version was too old (3.2.0).
This commit is contained in:
1605
deps/jemalloc/test/unit/SFMT.c
vendored
Normal file
1605
deps/jemalloc/test/unit/SFMT.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
165
deps/jemalloc/test/unit/bitmap.c
vendored
Normal file
165
deps/jemalloc/test/unit/bitmap.c
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#if (LG_BITMAP_MAXBITS > 12)
|
||||
# define MAXBITS 4500
|
||||
#else
|
||||
# define MAXBITS (1U << LG_BITMAP_MAXBITS)
|
||||
#endif
|
||||
|
||||
TEST_BEGIN(test_bitmap_size)
|
||||
{
|
||||
size_t i, prev_size;
|
||||
|
||||
prev_size = 0;
|
||||
for (i = 1; i <= MAXBITS; i++) {
|
||||
size_t size = bitmap_size(i);
|
||||
assert_true(size >= prev_size,
|
||||
"Bitmap size is smaller than expected");
|
||||
prev_size = size;
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_init)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||
bitmap_info_ngroups(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
assert_false(bitmap_get(bitmap, &binfo, j),
|
||||
"Bit should be unset");
|
||||
}
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_set)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||
bitmap_info_ngroups(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_set(bitmap, &binfo, j);
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_unset)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||
bitmap_info_ngroups(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_set(bitmap, &binfo, j);
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_set(bitmap, &binfo, j);
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_sfu)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
ssize_t j;
|
||||
bitmap_t *bitmap = malloc(sizeof(bitmap_t) *
|
||||
bitmap_info_ngroups(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
/* Iteratively set bits starting at the beginning. */
|
||||
for (j = 0; j < i; j++) {
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), j,
|
||||
"First unset bit should be just after "
|
||||
"previous first unset bit");
|
||||
}
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
|
||||
/*
|
||||
* Iteratively unset bits starting at the end, and
|
||||
* verify that bitmap_sfu() reaches the unset bits.
|
||||
*/
|
||||
for (j = i - 1; j >= 0; j--) {
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), j,
|
||||
"First unset bit should the bit previously "
|
||||
"unset");
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
}
|
||||
assert_false(bitmap_get(bitmap, &binfo, 0),
|
||||
"Bit should be unset");
|
||||
|
||||
/*
|
||||
* Iteratively set bits starting at the beginning, and
|
||||
* verify that bitmap_sfu() looks past them.
|
||||
*/
|
||||
for (j = 1; j < i; j++) {
|
||||
bitmap_set(bitmap, &binfo, j - 1);
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), j,
|
||||
"First unset bit should be just after the "
|
||||
"bit previously set");
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
}
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), i - 1,
|
||||
"First unset bit should be the last bit");
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_bitmap_size,
|
||||
test_bitmap_init,
|
||||
test_bitmap_set,
|
||||
test_bitmap_unset,
|
||||
test_bitmap_sfu));
|
||||
}
|
206
deps/jemalloc/test/unit/ckh.c
vendored
Normal file
206
deps/jemalloc/test/unit/ckh.c
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_new_delete)
|
||||
{
|
||||
ckh_t ckh;
|
||||
|
||||
assert_false(ckh_new(&ckh, 2, ckh_string_hash, ckh_string_keycomp),
|
||||
"Unexpected ckh_new() error");
|
||||
ckh_delete(&ckh);
|
||||
|
||||
assert_false(ckh_new(&ckh, 3, ckh_pointer_hash, ckh_pointer_keycomp),
|
||||
"Unexpected ckh_new() error");
|
||||
ckh_delete(&ckh);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_count_insert_search_remove)
|
||||
{
|
||||
ckh_t ckh;
|
||||
const char *strs[] = {
|
||||
"a string",
|
||||
"A string",
|
||||
"a string.",
|
||||
"A string."
|
||||
};
|
||||
const char *missing = "A string not in the hash table.";
|
||||
size_t i;
|
||||
|
||||
assert_false(ckh_new(&ckh, 2, ckh_string_hash, ckh_string_keycomp),
|
||||
"Unexpected ckh_new() error");
|
||||
assert_zu_eq(ckh_count(&ckh), 0,
|
||||
"ckh_count() should return %zu, but it returned %zu", ZU(0),
|
||||
ckh_count(&ckh));
|
||||
|
||||
/* Insert. */
|
||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||
ckh_insert(&ckh, strs[i], strs[i]);
|
||||
assert_zu_eq(ckh_count(&ckh), i+1,
|
||||
"ckh_count() should return %zu, but it returned %zu", i+1,
|
||||
ckh_count(&ckh));
|
||||
}
|
||||
|
||||
/* Search. */
|
||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||
union {
|
||||
void *p;
|
||||
const char *s;
|
||||
} k, v;
|
||||
void **kp, **vp;
|
||||
const char *ks, *vs;
|
||||
|
||||
kp = (i & 1) ? &k.p : NULL;
|
||||
vp = (i & 2) ? &v.p : NULL;
|
||||
k.p = NULL;
|
||||
v.p = NULL;
|
||||
assert_false(ckh_search(&ckh, strs[i], kp, vp),
|
||||
"Unexpected ckh_search() error");
|
||||
|
||||
ks = (i & 1) ? strs[i] : (const char *)NULL;
|
||||
vs = (i & 2) ? strs[i] : (const char *)NULL;
|
||||
assert_ptr_eq((void *)ks, (void *)k.s,
|
||||
"Key mismatch, i=%zu", i);
|
||||
assert_ptr_eq((void *)vs, (void *)v.s,
|
||||
"Value mismatch, i=%zu", i);
|
||||
}
|
||||
assert_true(ckh_search(&ckh, missing, NULL, NULL),
|
||||
"Unexpected ckh_search() success");
|
||||
|
||||
/* Remove. */
|
||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||
union {
|
||||
void *p;
|
||||
const char *s;
|
||||
} k, v;
|
||||
void **kp, **vp;
|
||||
const char *ks, *vs;
|
||||
|
||||
kp = (i & 1) ? &k.p : NULL;
|
||||
vp = (i & 2) ? &v.p : NULL;
|
||||
k.p = NULL;
|
||||
v.p = NULL;
|
||||
assert_false(ckh_remove(&ckh, strs[i], kp, vp),
|
||||
"Unexpected ckh_remove() error");
|
||||
|
||||
ks = (i & 1) ? strs[i] : (const char *)NULL;
|
||||
vs = (i & 2) ? strs[i] : (const char *)NULL;
|
||||
assert_ptr_eq((void *)ks, (void *)k.s,
|
||||
"Key mismatch, i=%zu", i);
|
||||
assert_ptr_eq((void *)vs, (void *)v.s,
|
||||
"Value mismatch, i=%zu", i);
|
||||
assert_zu_eq(ckh_count(&ckh),
|
||||
sizeof(strs)/sizeof(const char *) - i - 1,
|
||||
"ckh_count() should return %zu, but it returned %zu",
|
||||
sizeof(strs)/sizeof(const char *) - i - 1,
|
||||
ckh_count(&ckh));
|
||||
}
|
||||
|
||||
ckh_delete(&ckh);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_insert_iter_remove)
|
||||
{
|
||||
#define NITEMS ZU(1000)
|
||||
ckh_t ckh;
|
||||
void **p[NITEMS];
|
||||
void *q, *r;
|
||||
size_t i;
|
||||
|
||||
assert_false(ckh_new(&ckh, 2, ckh_pointer_hash, ckh_pointer_keycomp),
|
||||
"Unexpected ckh_new() error");
|
||||
|
||||
for (i = 0; i < NITEMS; i++) {
|
||||
p[i] = mallocx(i+1, 0);
|
||||
assert_ptr_not_null(p[i], "Unexpected mallocx() failure");
|
||||
}
|
||||
|
||||
for (i = 0; i < NITEMS; i++) {
|
||||
size_t j;
|
||||
|
||||
for (j = i; j < NITEMS; j++) {
|
||||
assert_false(ckh_insert(&ckh, p[j], p[j]),
|
||||
"Unexpected ckh_insert() failure");
|
||||
assert_false(ckh_search(&ckh, p[j], &q, &r),
|
||||
"Unexpected ckh_search() failure");
|
||||
assert_ptr_eq(p[j], q, "Key pointer mismatch");
|
||||
assert_ptr_eq(p[j], r, "Value pointer mismatch");
|
||||
}
|
||||
|
||||
assert_zu_eq(ckh_count(&ckh), NITEMS,
|
||||
"ckh_count() should return %zu, but it returned %zu",
|
||||
NITEMS, ckh_count(&ckh));
|
||||
|
||||
for (j = i + 1; j < NITEMS; j++) {
|
||||
assert_false(ckh_search(&ckh, p[j], NULL, NULL),
|
||||
"Unexpected ckh_search() failure");
|
||||
assert_false(ckh_remove(&ckh, p[j], &q, &r),
|
||||
"Unexpected ckh_remove() failure");
|
||||
assert_ptr_eq(p[j], q, "Key pointer mismatch");
|
||||
assert_ptr_eq(p[j], r, "Value pointer mismatch");
|
||||
assert_true(ckh_search(&ckh, p[j], NULL, NULL),
|
||||
"Unexpected ckh_search() success");
|
||||
assert_true(ckh_remove(&ckh, p[j], &q, &r),
|
||||
"Unexpected ckh_remove() success");
|
||||
}
|
||||
|
||||
{
|
||||
bool seen[NITEMS];
|
||||
size_t tabind;
|
||||
|
||||
memset(seen, 0, sizeof(seen));
|
||||
|
||||
for (tabind = 0; ckh_iter(&ckh, &tabind, &q, &r) ==
|
||||
false;) {
|
||||
size_t k;
|
||||
|
||||
assert_ptr_eq(q, r, "Key and val not equal");
|
||||
|
||||
for (k = 0; k < NITEMS; k++) {
|
||||
if (p[k] == q) {
|
||||
assert_false(seen[k],
|
||||
"Item %zu already seen", k);
|
||||
seen[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < i + 1; j++)
|
||||
assert_true(seen[j], "Item %zu not seen", j);
|
||||
for (; j < NITEMS; j++)
|
||||
assert_false(seen[j], "Item %zu seen", j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NITEMS; i++) {
|
||||
assert_false(ckh_search(&ckh, p[i], NULL, NULL),
|
||||
"Unexpected ckh_search() failure");
|
||||
assert_false(ckh_remove(&ckh, p[i], &q, &r),
|
||||
"Unexpected ckh_remove() failure");
|
||||
assert_ptr_eq(p[i], q, "Key pointer mismatch");
|
||||
assert_ptr_eq(p[i], r, "Value pointer mismatch");
|
||||
assert_true(ckh_search(&ckh, p[i], NULL, NULL),
|
||||
"Unexpected ckh_search() success");
|
||||
assert_true(ckh_remove(&ckh, p[i], &q, &r),
|
||||
"Unexpected ckh_remove() success");
|
||||
dallocx(p[i], 0);
|
||||
}
|
||||
|
||||
assert_zu_eq(ckh_count(&ckh), 0,
|
||||
"ckh_count() should return %zu, but it returned %zu", ZU(0),
|
||||
ckh_count(&ckh));
|
||||
ckh_delete(&ckh);
|
||||
#undef NITEMS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_new_delete,
|
||||
test_count_insert_search_remove,
|
||||
test_insert_iter_remove));
|
||||
}
|
171
deps/jemalloc/test/unit/hash.c
vendored
Normal file
171
deps/jemalloc/test/unit/hash.c
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file is based on code that is part of SMHasher
|
||||
* (https://code.google.com/p/smhasher/), and is subject to the MIT license
|
||||
* (http://www.opensource.org/licenses/mit-license.php). Both email addresses
|
||||
* associated with the source code's revision history belong to Austin Appleby,
|
||||
* and the revision history ranges from 2010 to 2012. Therefore the copyright
|
||||
* and license are here taken to be:
|
||||
*
|
||||
* Copyright (c) 2010-2012 Austin Appleby
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
typedef enum {
|
||||
hash_variant_x86_32,
|
||||
hash_variant_x86_128,
|
||||
hash_variant_x64_128
|
||||
} hash_variant_t;
|
||||
|
||||
static size_t
|
||||
hash_variant_bits(hash_variant_t variant)
|
||||
{
|
||||
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: return (32);
|
||||
case hash_variant_x86_128: return (128);
|
||||
case hash_variant_x64_128: return (128);
|
||||
default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
hash_variant_string(hash_variant_t variant)
|
||||
{
|
||||
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: return ("hash_x86_32");
|
||||
case hash_variant_x86_128: return ("hash_x86_128");
|
||||
case hash_variant_x64_128: return ("hash_x64_128");
|
||||
default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hash_variant_verify(hash_variant_t variant)
|
||||
{
|
||||
const size_t hashbytes = hash_variant_bits(variant) / 8;
|
||||
uint8_t key[256];
|
||||
uint8_t hashes[hashbytes * 256];
|
||||
uint8_t final[hashbytes];
|
||||
unsigned i;
|
||||
uint32_t computed, expected;
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
memset(hashes, 0, sizeof(hashes));
|
||||
memset(final, 0, sizeof(final));
|
||||
|
||||
/*
|
||||
* Hash keys of the form {0}, {0,1}, {0,1,2}, ..., {0,1,...,255} as the
|
||||
* seed.
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
key[i] = (uint8_t)i;
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: {
|
||||
uint32_t out;
|
||||
out = hash_x86_32(key, i, 256-i);
|
||||
memcpy(&hashes[i*hashbytes], &out, hashbytes);
|
||||
break;
|
||||
} case hash_variant_x86_128: {
|
||||
uint64_t out[2];
|
||||
hash_x86_128(key, i, 256-i, out);
|
||||
memcpy(&hashes[i*hashbytes], out, hashbytes);
|
||||
break;
|
||||
} case hash_variant_x64_128: {
|
||||
uint64_t out[2];
|
||||
hash_x64_128(key, i, 256-i, out);
|
||||
memcpy(&hashes[i*hashbytes], out, hashbytes);
|
||||
break;
|
||||
} default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash the result array. */
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: {
|
||||
uint32_t out = hash_x86_32(hashes, hashbytes*256, 0);
|
||||
memcpy(final, &out, sizeof(out));
|
||||
break;
|
||||
} case hash_variant_x86_128: {
|
||||
uint64_t out[2];
|
||||
hash_x86_128(hashes, hashbytes*256, 0, out);
|
||||
memcpy(final, out, sizeof(out));
|
||||
break;
|
||||
} case hash_variant_x64_128: {
|
||||
uint64_t out[2];
|
||||
hash_x64_128(hashes, hashbytes*256, 0, out);
|
||||
memcpy(final, out, sizeof(out));
|
||||
break;
|
||||
} default: not_reached();
|
||||
}
|
||||
|
||||
computed = (final[0] << 0) | (final[1] << 8) | (final[2] << 16) |
|
||||
(final[3] << 24);
|
||||
|
||||
switch (variant) {
|
||||
#ifdef JEMALLOC_BIG_ENDIAN
|
||||
case hash_variant_x86_32: expected = 0x6213303eU; break;
|
||||
case hash_variant_x86_128: expected = 0x266820caU; break;
|
||||
case hash_variant_x64_128: expected = 0xcc622b6fU; break;
|
||||
#else
|
||||
case hash_variant_x86_32: expected = 0xb0f57ee3U; break;
|
||||
case hash_variant_x86_128: expected = 0xb3ece62aU; break;
|
||||
case hash_variant_x64_128: expected = 0x6384ba69U; break;
|
||||
#endif
|
||||
default: not_reached();
|
||||
}
|
||||
|
||||
assert_u32_eq(computed, expected,
|
||||
"Hash mismatch for %s(): expected %#x but got %#x",
|
||||
hash_variant_string(variant), expected, computed);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_hash_x86_32)
|
||||
{
|
||||
|
||||
hash_variant_verify(hash_variant_x86_32);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_hash_x86_128)
|
||||
{
|
||||
|
||||
hash_variant_verify(hash_variant_x86_128);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_hash_x64_128)
|
||||
{
|
||||
|
||||
hash_variant_verify(hash_variant_x64_128);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_hash_x86_32,
|
||||
test_hash_x86_128,
|
||||
test_hash_x64_128));
|
||||
}
|
222
deps/jemalloc/test/unit/junk.c
vendored
Normal file
222
deps/jemalloc/test/unit/junk.c
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf =
|
||||
"abort:false,junk:true,zero:false,redzone:true,quarantine:0";
|
||||
#endif
|
||||
|
||||
static arena_dalloc_junk_small_t *arena_dalloc_junk_small_orig;
|
||||
static arena_dalloc_junk_large_t *arena_dalloc_junk_large_orig;
|
||||
static huge_dalloc_junk_t *huge_dalloc_junk_orig;
|
||||
static void *most_recently_junked;
|
||||
|
||||
static void
|
||||
arena_dalloc_junk_small_intercept(void *ptr, arena_bin_info_t *bin_info)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
arena_dalloc_junk_small_orig(ptr, bin_info);
|
||||
for (i = 0; i < bin_info->reg_size; i++) {
|
||||
assert_c_eq(((char *)ptr)[i], 0x5a,
|
||||
"Missing junk fill for byte %zu/%zu of deallocated region",
|
||||
i, bin_info->reg_size);
|
||||
}
|
||||
most_recently_junked = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
arena_dalloc_junk_large_intercept(void *ptr, size_t usize)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
arena_dalloc_junk_large_orig(ptr, usize);
|
||||
for (i = 0; i < usize; i++) {
|
||||
assert_c_eq(((char *)ptr)[i], 0x5a,
|
||||
"Missing junk fill for byte %zu/%zu of deallocated region",
|
||||
i, usize);
|
||||
}
|
||||
most_recently_junked = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
huge_dalloc_junk_intercept(void *ptr, size_t usize)
|
||||
{
|
||||
|
||||
huge_dalloc_junk_orig(ptr, usize);
|
||||
/*
|
||||
* The conditions under which junk filling actually occurs are nuanced
|
||||
* enough that it doesn't make sense to duplicate the decision logic in
|
||||
* test code, so don't actually check that the region is junk-filled.
|
||||
*/
|
||||
most_recently_junked = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
test_junk(size_t sz_min, size_t sz_max)
|
||||
{
|
||||
char *s;
|
||||
size_t sz_prev, sz, i;
|
||||
|
||||
arena_dalloc_junk_small_orig = arena_dalloc_junk_small;
|
||||
arena_dalloc_junk_small = arena_dalloc_junk_small_intercept;
|
||||
arena_dalloc_junk_large_orig = arena_dalloc_junk_large;
|
||||
arena_dalloc_junk_large = arena_dalloc_junk_large_intercept;
|
||||
huge_dalloc_junk_orig = huge_dalloc_junk;
|
||||
huge_dalloc_junk = huge_dalloc_junk_intercept;
|
||||
|
||||
sz_prev = 0;
|
||||
s = (char *)mallocx(sz_min, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
|
||||
for (sz = sallocx(s, 0); sz <= sz_max;
|
||||
sz_prev = sz, sz = sallocx(s, 0)) {
|
||||
if (sz_prev > 0) {
|
||||
assert_c_eq(s[0], 'a',
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
ZU(0), sz_prev);
|
||||
assert_c_eq(s[sz_prev-1], 'a',
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
sz_prev-1, sz_prev);
|
||||
}
|
||||
|
||||
for (i = sz_prev; i < sz; i++) {
|
||||
assert_c_eq(s[i], 0xa5,
|
||||
"Newly allocated byte %zu/%zu isn't junk-filled",
|
||||
i, sz);
|
||||
s[i] = 'a';
|
||||
}
|
||||
|
||||
if (xallocx(s, sz+1, 0, 0) == sz) {
|
||||
void *junked = (void *)s;
|
||||
|
||||
s = (char *)rallocx(s, sz+1, 0);
|
||||
assert_ptr_not_null((void *)s,
|
||||
"Unexpected rallocx() failure");
|
||||
if (!config_mremap || sz+1 <= arena_maxclass) {
|
||||
assert_ptr_eq(most_recently_junked, junked,
|
||||
"Expected region of size %zu to be "
|
||||
"junk-filled",
|
||||
sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dallocx(s, 0);
|
||||
assert_ptr_eq(most_recently_junked, (void *)s,
|
||||
"Expected region of size %zu to be junk-filled", sz);
|
||||
|
||||
arena_dalloc_junk_small = arena_dalloc_junk_small_orig;
|
||||
arena_dalloc_junk_large = arena_dalloc_junk_large_orig;
|
||||
huge_dalloc_junk = huge_dalloc_junk_orig;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_junk_small)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_junk(1, SMALL_MAXCLASS-1);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_junk_large)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_junk(SMALL_MAXCLASS+1, arena_maxclass);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_junk_huge)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_junk(arena_maxclass+1, chunksize*2);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
arena_ralloc_junk_large_t *arena_ralloc_junk_large_orig;
|
||||
static void *most_recently_trimmed;
|
||||
|
||||
static void
|
||||
arena_ralloc_junk_large_intercept(void *ptr, size_t old_usize, size_t usize)
|
||||
{
|
||||
|
||||
arena_ralloc_junk_large_orig(ptr, old_usize, usize);
|
||||
assert_zu_eq(old_usize, arena_maxclass, "Unexpected old_usize");
|
||||
assert_zu_eq(usize, arena_maxclass-PAGE, "Unexpected usize");
|
||||
most_recently_trimmed = ptr;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_junk_large_ralloc_shrink)
|
||||
{
|
||||
void *p1, *p2;
|
||||
|
||||
p1 = mallocx(arena_maxclass, 0);
|
||||
assert_ptr_not_null(p1, "Unexpected mallocx() failure");
|
||||
|
||||
arena_ralloc_junk_large_orig = arena_ralloc_junk_large;
|
||||
arena_ralloc_junk_large = arena_ralloc_junk_large_intercept;
|
||||
|
||||
p2 = rallocx(p1, arena_maxclass-PAGE, 0);
|
||||
assert_ptr_eq(p1, p2, "Unexpected move during shrink");
|
||||
|
||||
arena_ralloc_junk_large = arena_ralloc_junk_large_orig;
|
||||
|
||||
assert_ptr_eq(most_recently_trimmed, p1,
|
||||
"Expected trimmed portion of region to be junk-filled");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static bool detected_redzone_corruption;
|
||||
|
||||
static void
|
||||
arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,
|
||||
size_t offset, uint8_t byte)
|
||||
{
|
||||
|
||||
detected_redzone_corruption = true;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_junk_redzone)
|
||||
{
|
||||
char *s;
|
||||
arena_redzone_corruption_t *arena_redzone_corruption_orig;
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
|
||||
arena_redzone_corruption_orig = arena_redzone_corruption;
|
||||
arena_redzone_corruption = arena_redzone_corruption_replacement;
|
||||
|
||||
/* Test underflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[-1] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
/* Test overflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[sallocx(s, 0)] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
arena_redzone_corruption = arena_redzone_corruption_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_junk_small,
|
||||
test_junk_large,
|
||||
test_junk_huge,
|
||||
test_junk_large_ralloc_shrink,
|
||||
test_junk_redzone));
|
||||
}
|
415
deps/jemalloc/test/unit/mallctl.c
vendored
Normal file
415
deps/jemalloc/test/unit/mallctl.c
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_mallctl_errors)
|
||||
{
|
||||
uint64_t epoch;
|
||||
size_t sz;
|
||||
|
||||
assert_d_eq(mallctl("no_such_name", NULL, NULL, NULL, 0), ENOENT,
|
||||
"mallctl() should return ENOENT for non-existent names");
|
||||
|
||||
assert_d_eq(mallctl("version", NULL, NULL, "0.0.0", strlen("0.0.0")),
|
||||
EPERM, "mallctl() should return EPERM on attempt to write "
|
||||
"read-only value");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)-1),
|
||||
EINVAL, "mallctl() should return EINVAL for input size mismatch");
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)+1),
|
||||
EINVAL, "mallctl() should return EINVAL for input size mismatch");
|
||||
|
||||
sz = sizeof(epoch)-1;
|
||||
assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctl() should return EINVAL for output size mismatch");
|
||||
sz = sizeof(epoch)+1;
|
||||
assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctl() should return EINVAL for output size mismatch");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctlnametomib_errors)
|
||||
{
|
||||
size_t mib[1];
|
||||
size_t miblen;
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("no_such_name", mib, &miblen), ENOENT,
|
||||
"mallctlnametomib() should return ENOENT for non-existent names");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctlbymib_errors)
|
||||
{
|
||||
uint64_t epoch;
|
||||
size_t sz;
|
||||
size_t mib[1];
|
||||
size_t miblen;
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("version", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, "0.0.0",
|
||||
strlen("0.0.0")), EPERM, "mallctl() should return EPERM on "
|
||||
"attempt to write read-only value");
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
|
||||
sizeof(epoch)-1), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for input size mismatch");
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
|
||||
sizeof(epoch)+1), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for input size mismatch");
|
||||
|
||||
sz = sizeof(epoch)-1;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for output size mismatch");
|
||||
sz = sizeof(epoch)+1;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for output size mismatch");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_read_write)
|
||||
{
|
||||
uint64_t old_epoch, new_epoch;
|
||||
size_t sz = sizeof(old_epoch);
|
||||
|
||||
/* Blind. */
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
|
||||
/* Read. */
|
||||
assert_d_eq(mallctl("epoch", &old_epoch, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
|
||||
/* Write. */
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &new_epoch, sizeof(new_epoch)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
|
||||
/* Read+write. */
|
||||
assert_d_eq(mallctl("epoch", &old_epoch, &sz, &new_epoch,
|
||||
sizeof(new_epoch)), 0, "Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctlnametomib_short_mib)
|
||||
{
|
||||
size_t mib[4];
|
||||
size_t miblen;
|
||||
|
||||
miblen = 3;
|
||||
mib[3] = 42;
|
||||
assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
assert_zu_eq(miblen, 3, "Unexpected mib output length");
|
||||
assert_zu_eq(mib[3], 42,
|
||||
"mallctlnametomib() wrote past the end of the input mib");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_config)
|
||||
{
|
||||
|
||||
#define TEST_MALLCTL_CONFIG(config) do { \
|
||||
bool oldval; \
|
||||
size_t sz = sizeof(oldval); \
|
||||
assert_d_eq(mallctl("config."#config, &oldval, &sz, NULL, 0), \
|
||||
0, "Unexpected mallctl() failure"); \
|
||||
assert_b_eq(oldval, config_##config, "Incorrect config value"); \
|
||||
assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_MALLCTL_CONFIG(debug);
|
||||
TEST_MALLCTL_CONFIG(dss);
|
||||
TEST_MALLCTL_CONFIG(fill);
|
||||
TEST_MALLCTL_CONFIG(lazy_lock);
|
||||
TEST_MALLCTL_CONFIG(mremap);
|
||||
TEST_MALLCTL_CONFIG(munmap);
|
||||
TEST_MALLCTL_CONFIG(prof);
|
||||
TEST_MALLCTL_CONFIG(prof_libgcc);
|
||||
TEST_MALLCTL_CONFIG(prof_libunwind);
|
||||
TEST_MALLCTL_CONFIG(stats);
|
||||
TEST_MALLCTL_CONFIG(tcache);
|
||||
TEST_MALLCTL_CONFIG(tls);
|
||||
TEST_MALLCTL_CONFIG(utrace);
|
||||
TEST_MALLCTL_CONFIG(valgrind);
|
||||
TEST_MALLCTL_CONFIG(xmalloc);
|
||||
|
||||
#undef TEST_MALLCTL_CONFIG
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_opt)
|
||||
{
|
||||
bool config_always = true;
|
||||
|
||||
#define TEST_MALLCTL_OPT(t, opt, config) do { \
|
||||
t oldval; \
|
||||
size_t sz = sizeof(oldval); \
|
||||
int expected = config_##config ? 0 : ENOENT; \
|
||||
int result = mallctl("opt."#opt, &oldval, &sz, NULL, 0); \
|
||||
assert_d_eq(result, expected, \
|
||||
"Unexpected mallctl() result for opt."#opt); \
|
||||
assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_MALLCTL_OPT(bool, abort, always);
|
||||
TEST_MALLCTL_OPT(size_t, lg_chunk, always);
|
||||
TEST_MALLCTL_OPT(const char *, dss, always);
|
||||
TEST_MALLCTL_OPT(size_t, narenas, always);
|
||||
TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always);
|
||||
TEST_MALLCTL_OPT(bool, stats_print, always);
|
||||
TEST_MALLCTL_OPT(bool, junk, fill);
|
||||
TEST_MALLCTL_OPT(size_t, quarantine, fill);
|
||||
TEST_MALLCTL_OPT(bool, redzone, fill);
|
||||
TEST_MALLCTL_OPT(bool, zero, fill);
|
||||
TEST_MALLCTL_OPT(bool, utrace, utrace);
|
||||
TEST_MALLCTL_OPT(bool, valgrind, valgrind);
|
||||
TEST_MALLCTL_OPT(bool, xmalloc, xmalloc);
|
||||
TEST_MALLCTL_OPT(bool, tcache, tcache);
|
||||
TEST_MALLCTL_OPT(size_t, lg_tcache_max, tcache);
|
||||
TEST_MALLCTL_OPT(bool, prof, prof);
|
||||
TEST_MALLCTL_OPT(const char *, prof_prefix, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_active, prof);
|
||||
TEST_MALLCTL_OPT(ssize_t, lg_prof_sample, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_accum, prof);
|
||||
TEST_MALLCTL_OPT(ssize_t, lg_prof_interval, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_gdump, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_final, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_leak, prof);
|
||||
|
||||
#undef TEST_MALLCTL_OPT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_manpage_example)
|
||||
{
|
||||
unsigned nbins, i;
|
||||
size_t mib[4];
|
||||
size_t len, miblen;
|
||||
|
||||
len = sizeof(nbins);
|
||||
assert_d_eq(mallctl("arenas.nbins", &nbins, &len, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
miblen = 4;
|
||||
assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
for (i = 0; i < nbins; i++) {
|
||||
size_t bin_size;
|
||||
|
||||
mib[2] = i;
|
||||
len = sizeof(bin_size);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0),
|
||||
0, "Unexpected mallctlbymib() failure");
|
||||
/* Do something with bin_size... */
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_thread_arena)
|
||||
{
|
||||
unsigned arena_old, arena_new, narenas;
|
||||
size_t sz = sizeof(unsigned);
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect");
|
||||
arena_new = narenas - 1;
|
||||
assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new,
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure");
|
||||
arena_new = 0;
|
||||
assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new,
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arena_i_purge)
|
||||
{
|
||||
unsigned narenas;
|
||||
size_t sz = sizeof(unsigned);
|
||||
size_t mib[3];
|
||||
size_t miblen = 3;
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 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_dss)
|
||||
{
|
||||
const char *dss_prec_old, *dss_prec_new;
|
||||
size_t sz = sizeof(dss_prec_old);
|
||||
|
||||
dss_prec_new = "primary";
|
||||
assert_d_eq(mallctl("arena.0.dss", &dss_prec_old, &sz, &dss_prec_new,
|
||||
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
|
||||
assert_str_ne(dss_prec_old, "primary",
|
||||
"Unexpected default for dss precedence");
|
||||
|
||||
assert_d_eq(mallctl("arena.0.dss", &dss_prec_new, &sz, &dss_prec_old,
|
||||
sizeof(dss_prec_old)), 0, "Unexpected mallctl() failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_purge)
|
||||
{
|
||||
unsigned arena = 0;
|
||||
|
||||
assert_d_eq(mallctl("arenas.purge", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctl("arenas.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_initialized)
|
||||
{
|
||||
unsigned narenas;
|
||||
size_t sz = sizeof(narenas);
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
{
|
||||
bool initialized[narenas];
|
||||
|
||||
sz = narenas * sizeof(bool);
|
||||
assert_d_eq(mallctl("arenas.initialized", initialized, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas."#name, &name, &sz, NULL, 0), 0, \
|
||||
"Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_CONSTANT(size_t, quantum, QUANTUM);
|
||||
TEST_ARENAS_CONSTANT(size_t, page, PAGE);
|
||||
TEST_ARENAS_CONSTANT(unsigned, nbins, NBINS);
|
||||
TEST_ARENAS_CONSTANT(size_t, nlruns, nlclasses);
|
||||
|
||||
#undef TEST_ARENAS_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_bin_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas.bin.0."#name, &name, &sz, NULL, 0), \
|
||||
0, "Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_BIN_CONSTANT(size_t, size, arena_bin_info[0].reg_size);
|
||||
TEST_ARENAS_BIN_CONSTANT(uint32_t, nregs, arena_bin_info[0].nregs);
|
||||
TEST_ARENAS_BIN_CONSTANT(size_t, run_size, arena_bin_info[0].run_size);
|
||||
|
||||
#undef TEST_ARENAS_BIN_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_lrun_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas.lrun.0."#name, &name, &sz, NULL, \
|
||||
0), 0, "Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_LRUN_CONSTANT(size_t, size, (1 << LG_PAGE));
|
||||
|
||||
#undef TEST_ARENAS_LRUN_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_extend)
|
||||
{
|
||||
unsigned narenas_before, arena, narenas_after;
|
||||
size_t sz = sizeof(unsigned);
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas_before, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
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");
|
||||
|
||||
assert_u_eq(narenas_before+1, narenas_after,
|
||||
"Unexpected number of arenas before versus after extension");
|
||||
assert_u_eq(arena, narenas_after-1, "Unexpected arena index");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas)
|
||||
{
|
||||
|
||||
#define TEST_STATS_ARENAS(t, name) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("stats.arenas.0."#name, &name, &sz, NULL, \
|
||||
0), 0, "Unexpected mallctl() failure"); \
|
||||
} while (0)
|
||||
|
||||
TEST_STATS_ARENAS(const char *, dss);
|
||||
TEST_STATS_ARENAS(unsigned, nthreads);
|
||||
TEST_STATS_ARENAS(size_t, pactive);
|
||||
TEST_STATS_ARENAS(size_t, pdirty);
|
||||
|
||||
#undef TEST_STATS_ARENAS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_mallctl_errors,
|
||||
test_mallctlnametomib_errors,
|
||||
test_mallctlbymib_errors,
|
||||
test_mallctl_read_write,
|
||||
test_mallctlnametomib_short_mib,
|
||||
test_mallctl_config,
|
||||
test_mallctl_opt,
|
||||
test_manpage_example,
|
||||
test_thread_arena,
|
||||
test_arena_i_purge,
|
||||
test_arena_i_dss,
|
||||
test_arenas_purge,
|
||||
test_arenas_initialized,
|
||||
test_arenas_constants,
|
||||
test_arenas_bin_constants,
|
||||
test_arenas_lrun_constants,
|
||||
test_arenas_extend,
|
||||
test_stats_arenas));
|
||||
}
|
388
deps/jemalloc/test/unit/math.c
vendored
Normal file
388
deps/jemalloc/test/unit/math.c
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define MAX_REL_ERR 1.0e-9
|
||||
#define MAX_ABS_ERR 1.0e-9
|
||||
|
||||
static bool
|
||||
double_eq_rel(double a, double b, double max_rel_err, double max_abs_err)
|
||||
{
|
||||
double rel_err;
|
||||
|
||||
if (fabs(a - b) < max_abs_err)
|
||||
return (true);
|
||||
rel_err = (fabs(b) > fabs(a)) ? fabs((a-b)/b) : fabs((a-b)/a);
|
||||
return (rel_err < max_rel_err);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
factorial(unsigned x)
|
||||
{
|
||||
uint64_t ret = 1;
|
||||
unsigned i;
|
||||
|
||||
for (i = 2; i <= x; i++)
|
||||
ret *= (uint64_t)i;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ln_gamma_factorial)
|
||||
{
|
||||
unsigned x;
|
||||
|
||||
/* exp(ln_gamma(x)) == (x-1)! for integer x. */
|
||||
for (x = 1; x <= 21; x++) {
|
||||
assert_true(double_eq_rel(exp(ln_gamma(x)),
|
||||
(double)factorial(x-1), MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect factorial result for x=%u", x);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/* Expected ln_gamma([0.0..100.0] increment=0.25). */
|
||||
static const double ln_gamma_misc_expected[] = {
|
||||
INFINITY,
|
||||
1.28802252469807743, 0.57236494292470008, 0.20328095143129538,
|
||||
0.00000000000000000, -0.09827183642181320, -0.12078223763524518,
|
||||
-0.08440112102048555, 0.00000000000000000, 0.12487171489239651,
|
||||
0.28468287047291918, 0.47521466691493719, 0.69314718055994529,
|
||||
0.93580193110872523, 1.20097360234707429, 1.48681557859341718,
|
||||
1.79175946922805496, 2.11445692745037128, 2.45373657084244234,
|
||||
2.80857141857573644, 3.17805383034794575, 3.56137591038669710,
|
||||
3.95781396761871651, 4.36671603662228680, 4.78749174278204581,
|
||||
5.21960398699022932, 5.66256205985714178, 6.11591589143154568,
|
||||
6.57925121201010121, 7.05218545073853953, 7.53436423675873268,
|
||||
8.02545839631598312, 8.52516136106541467, 9.03318691960512332,
|
||||
9.54926725730099690, 10.07315123968123949, 10.60460290274525086,
|
||||
11.14340011995171231, 11.68933342079726856, 12.24220494005076176,
|
||||
12.80182748008146909, 13.36802367147604720, 13.94062521940376342,
|
||||
14.51947222506051816, 15.10441257307551943, 15.69530137706046524,
|
||||
16.29200047656724237, 16.89437797963419285, 17.50230784587389010,
|
||||
18.11566950571089407, 18.73434751193644843, 19.35823122022435427,
|
||||
19.98721449566188468, 20.62119544270163018, 21.26007615624470048,
|
||||
21.90376249182879320, 22.55216385312342098, 23.20519299513386002,
|
||||
23.86276584168908954, 24.52480131594137802, 25.19122118273868338,
|
||||
25.86194990184851861, 26.53691449111561340, 27.21604439872720604,
|
||||
27.89927138384089389, 28.58652940490193828, 29.27775451504081516,
|
||||
29.97288476399884871, 30.67186010608067548, 31.37462231367769050,
|
||||
32.08111489594735843, 32.79128302226991565, 33.50507345013689076,
|
||||
34.22243445715505317, 34.94331577687681545, 35.66766853819134298,
|
||||
36.39544520803305261, 37.12659953718355865, 37.86108650896109395,
|
||||
38.59886229060776230, 39.33988418719949465, 40.08411059791735198,
|
||||
40.83150097453079752, 41.58201578195490100, 42.33561646075348506,
|
||||
43.09226539146988699, 43.85192586067515208, 44.61456202863158893,
|
||||
45.38013889847690052, 46.14862228684032885, 46.91997879580877395,
|
||||
47.69417578616628361, 48.47118135183522014, 49.25096429545256882,
|
||||
50.03349410501914463, 50.81874093156324790, 51.60667556776436982,
|
||||
52.39726942748592364, 53.19049452616926743, 53.98632346204390586,
|
||||
54.78472939811231157, 55.58568604486942633, 56.38916764371992940,
|
||||
57.19514895105859864, 58.00360522298051080, 58.81451220059079787,
|
||||
59.62784609588432261, 60.44358357816834371, 61.26170176100199427,
|
||||
62.08217818962842927, 62.90499082887649962, 63.73011805151035958,
|
||||
64.55753862700632340, 65.38723171073768015, 66.21917683354901385,
|
||||
67.05335389170279825, 67.88974313718154008, 68.72832516833013017,
|
||||
69.56908092082363737, 70.41199165894616385, 71.25703896716800045,
|
||||
72.10420474200799390, 72.95347118416940191, 73.80482079093779646,
|
||||
74.65823634883015814, 75.51370092648485866, 76.37119786778275454,
|
||||
77.23071078519033961, 78.09222355331530707, 78.95572030266725960,
|
||||
79.82118541361435859, 80.68860351052903468, 81.55795945611502873,
|
||||
82.42923834590904164, 83.30242550295004378, 84.17750647261028973,
|
||||
85.05446701758152983, 85.93329311301090456, 86.81397094178107920,
|
||||
87.69648688992882057, 88.58082754219766741, 89.46697967771913795,
|
||||
90.35493026581838194, 91.24466646193963015, 92.13617560368709292,
|
||||
93.02944520697742803, 93.92446296229978486, 94.82121673107967297,
|
||||
95.71969454214321615, 96.61988458827809723, 97.52177522288820910,
|
||||
98.42535495673848800, 99.33061245478741341, 100.23753653310367895,
|
||||
101.14611615586458981, 102.05634043243354370, 102.96819861451382394,
|
||||
103.88168009337621811, 104.79677439715833032, 105.71347118823287303,
|
||||
106.63176026064346047, 107.55163153760463501, 108.47307506906540198,
|
||||
109.39608102933323153, 110.32063971475740516, 111.24674154146920557,
|
||||
112.17437704317786995, 113.10353686902013237, 114.03421178146170689,
|
||||
114.96639265424990128, 115.90007047041454769, 116.83523632031698014,
|
||||
117.77188139974506953, 118.70999700805310795, 119.64957454634490830,
|
||||
120.59060551569974962, 121.53308151543865279, 122.47699424143097247,
|
||||
123.42233548443955726, 124.36909712850338394, 125.31727114935689826,
|
||||
126.26684961288492559, 127.21782467361175861, 128.17018857322420899,
|
||||
129.12393363912724453, 130.07905228303084755, 131.03553699956862033,
|
||||
131.99338036494577864, 132.95257503561629164, 133.91311374698926784,
|
||||
134.87498931216194364, 135.83819462068046846, 136.80272263732638294,
|
||||
137.76856640092901785, 138.73571902320256299, 139.70417368760718091,
|
||||
140.67392364823425055, 141.64496222871400732, 142.61728282114600574,
|
||||
143.59087888505104047, 144.56574394634486680, 145.54187159633210058,
|
||||
146.51925549072063859, 147.49788934865566148, 148.47776695177302031,
|
||||
149.45888214327129617, 150.44122882700193600, 151.42480096657754984,
|
||||
152.40959258449737490, 153.39559776128982094, 154.38281063467164245,
|
||||
155.37122539872302696, 156.36083630307879844, 157.35163765213474107,
|
||||
158.34362380426921391, 159.33678917107920370, 160.33112821663092973,
|
||||
161.32663545672428995, 162.32330545817117695, 163.32113283808695314,
|
||||
164.32011226319519892, 165.32023844914485267, 166.32150615984036790,
|
||||
167.32391020678358018, 168.32744544842768164, 169.33210678954270634,
|
||||
170.33788918059275375, 171.34478761712384198, 172.35279713916281707,
|
||||
173.36191283062726143, 174.37212981874515094, 175.38344327348534080,
|
||||
176.39584840699734514, 177.40934047306160437, 178.42391476654847793,
|
||||
179.43956662288721304, 180.45629141754378111, 181.47408456550741107,
|
||||
182.49294152078630304, 183.51285777591152737, 184.53382886144947861,
|
||||
185.55585034552262869, 186.57891783333786861, 187.60302696672312095,
|
||||
188.62817342367162610, 189.65435291789341932, 190.68156119837468054,
|
||||
191.70979404894376330, 192.73904728784492590, 193.76931676731820176,
|
||||
194.80059837318714244, 195.83288802445184729, 196.86618167288995096,
|
||||
197.90047530266301123, 198.93576492992946214, 199.97204660246373464,
|
||||
201.00931639928148797, 202.04757043027063901, 203.08680483582807597,
|
||||
204.12701578650228385, 205.16819948264117102, 206.21035215404597807,
|
||||
207.25347005962987623, 208.29754948708190909, 209.34258675253678916,
|
||||
210.38857820024875878, 211.43552020227099320, 212.48340915813977858,
|
||||
213.53224149456323744, 214.58201366511514152, 215.63272214993284592,
|
||||
216.68436345542014010, 217.73693411395422004, 218.79043068359703739,
|
||||
219.84484974781133815, 220.90018791517996988, 221.95644181913033322,
|
||||
223.01360811766215875, 224.07168349307951871, 225.13066465172661879,
|
||||
226.19054832372759734, 227.25133126272962159, 228.31301024565024704,
|
||||
229.37558207242807384, 230.43904356577689896, 231.50339157094342113,
|
||||
232.56862295546847008, 233.63473460895144740, 234.70172344281823484,
|
||||
235.76958639009222907, 236.83832040516844586, 237.90792246359117712,
|
||||
238.97838956183431947, 240.04971871708477238, 241.12190696702904802,
|
||||
242.19495136964280846, 243.26884900298270509, 244.34359696498191283,
|
||||
245.41919237324782443, 246.49563236486270057, 247.57291409618682110,
|
||||
248.65103474266476269, 249.72999149863338175, 250.80978157713354904,
|
||||
251.89040220972316320, 252.97185064629374551, 254.05412415488834199,
|
||||
255.13722002152300661, 256.22113555000953511, 257.30586806178126835,
|
||||
258.39141489572085675, 259.47777340799029844, 260.56494097186322279,
|
||||
261.65291497755913497, 262.74169283208021852, 263.83127195904967266,
|
||||
264.92164979855277807, 266.01282380697938379, 267.10479145686849733,
|
||||
268.19755023675537586, 269.29109765101975427, 270.38543121973674488,
|
||||
271.48054847852881721, 272.57644697842033565, 273.67312428569374561,
|
||||
274.77057798174683967, 275.86880566295326389, 276.96780494052313770,
|
||||
278.06757344036617496, 279.16810880295668085, 280.26940868320008349,
|
||||
281.37147075030043197, 282.47429268763045229, 283.57787219260217171,
|
||||
284.68220697654078322, 285.78729476455760050, 286.89313329542699194,
|
||||
287.99972032146268930, 289.10705360839756395, 290.21513093526289140,
|
||||
291.32395009427028754, 292.43350889069523646, 293.54380514276073200,
|
||||
294.65483668152336350, 295.76660135076059532, 296.87909700685889902,
|
||||
297.99232151870342022, 299.10627276756946458, 300.22094864701409733,
|
||||
301.33634706277030091, 302.45246593264130297, 303.56930318639643929,
|
||||
304.68685676566872189, 305.80512462385280514, 306.92410472600477078,
|
||||
308.04379504874236773, 309.16419358014690033, 310.28529831966631036,
|
||||
311.40710727801865687, 312.52961847709792664, 313.65282994987899201,
|
||||
314.77673974032603610, 315.90134590329950015, 317.02664650446632777,
|
||||
318.15263962020929966, 319.27932333753892635, 320.40669575400545455,
|
||||
321.53475497761127144, 322.66349912672620803, 323.79292633000159185,
|
||||
324.92303472628691452, 326.05382246454587403, 327.18528770377525916,
|
||||
328.31742861292224234, 329.45024337080525356, 330.58373016603343331,
|
||||
331.71788719692847280, 332.85271267144611329, 333.98820480709991898,
|
||||
335.12436183088397001, 336.26118197919845443, 337.39866349777429377,
|
||||
338.53680464159958774, 339.67560367484657036, 340.81505887079896411,
|
||||
341.95516851178109619, 343.09593088908627578, 344.23734430290727460,
|
||||
345.37940706226686416, 346.52211748494903532, 347.66547389743118401,
|
||||
348.80947463481720661, 349.95411804077025408, 351.09940246744753267,
|
||||
352.24532627543504759, 353.39188783368263103, 354.53908551944078908,
|
||||
355.68691771819692349, 356.83538282361303118, 357.98447923746385868,
|
||||
359.13420536957539753
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_ln_gamma_misc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < sizeof(ln_gamma_misc_expected)/sizeof(double); i++) {
|
||||
double x = (double)i * 0.25;
|
||||
assert_true(double_eq_rel(ln_gamma(x),
|
||||
ln_gamma_misc_expected[i], MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect ln_gamma result for i=%u", i);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/* Expected pt_norm([0.01..0.99] increment=0.01). */
|
||||
static const double pt_norm_expected[] = {
|
||||
-INFINITY,
|
||||
-2.32634787404084076, -2.05374891063182252, -1.88079360815125085,
|
||||
-1.75068607125216946, -1.64485362695147264, -1.55477359459685305,
|
||||
-1.47579102817917063, -1.40507156030963221, -1.34075503369021654,
|
||||
-1.28155156554460081, -1.22652812003661049, -1.17498679206608991,
|
||||
-1.12639112903880045, -1.08031934081495606, -1.03643338949378938,
|
||||
-0.99445788320975281, -0.95416525314619416, -0.91536508784281390,
|
||||
-0.87789629505122846, -0.84162123357291418, -0.80642124701824025,
|
||||
-0.77219321418868492, -0.73884684918521371, -0.70630256284008752,
|
||||
-0.67448975019608171, -0.64334540539291685, -0.61281299101662701,
|
||||
-0.58284150727121620, -0.55338471955567281, -0.52440051270804067,
|
||||
-0.49585034734745320, -0.46769879911450812, -0.43991316567323380,
|
||||
-0.41246312944140462, -0.38532046640756751, -0.35845879325119373,
|
||||
-0.33185334643681652, -0.30548078809939738, -0.27931903444745404,
|
||||
-0.25334710313579978, -0.22754497664114931, -0.20189347914185077,
|
||||
-0.17637416478086135, -0.15096921549677725, -0.12566134685507399,
|
||||
-0.10043372051146975, -0.07526986209982976, -0.05015358346473352,
|
||||
-0.02506890825871106, 0.00000000000000000, 0.02506890825871106,
|
||||
0.05015358346473366, 0.07526986209982990, 0.10043372051146990,
|
||||
0.12566134685507413, 0.15096921549677739, 0.17637416478086146,
|
||||
0.20189347914185105, 0.22754497664114931, 0.25334710313579978,
|
||||
0.27931903444745404, 0.30548078809939738, 0.33185334643681652,
|
||||
0.35845879325119373, 0.38532046640756762, 0.41246312944140484,
|
||||
0.43991316567323391, 0.46769879911450835, 0.49585034734745348,
|
||||
0.52440051270804111, 0.55338471955567303, 0.58284150727121620,
|
||||
0.61281299101662701, 0.64334540539291685, 0.67448975019608171,
|
||||
0.70630256284008752, 0.73884684918521371, 0.77219321418868492,
|
||||
0.80642124701824036, 0.84162123357291441, 0.87789629505122879,
|
||||
0.91536508784281423, 0.95416525314619460, 0.99445788320975348,
|
||||
1.03643338949378938, 1.08031934081495606, 1.12639112903880045,
|
||||
1.17498679206608991, 1.22652812003661049, 1.28155156554460081,
|
||||
1.34075503369021654, 1.40507156030963265, 1.47579102817917085,
|
||||
1.55477359459685394, 1.64485362695147308, 1.75068607125217102,
|
||||
1.88079360815125041, 2.05374891063182208, 2.32634787404084076
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_pt_norm)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < sizeof(pt_norm_expected)/sizeof(double); i++) {
|
||||
double p = (double)i * 0.01;
|
||||
assert_true(double_eq_rel(pt_norm(p), pt_norm_expected[i],
|
||||
MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect pt_norm result for i=%u", i);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/*
|
||||
* Expected pt_chi2(p=[0.01..0.99] increment=0.07,
|
||||
* df={0.1, 1.1, 10.1, 100.1, 1000.1}).
|
||||
*/
|
||||
static const double pt_chi2_df[] = {0.1, 1.1, 10.1, 100.1, 1000.1};
|
||||
static const double pt_chi2_expected[] = {
|
||||
1.168926411457320e-40, 1.347680397072034e-22, 3.886980416666260e-17,
|
||||
8.245951724356564e-14, 2.068936347497604e-11, 1.562561743309233e-09,
|
||||
5.459543043426564e-08, 1.114775688149252e-06, 1.532101202364371e-05,
|
||||
1.553884683726585e-04, 1.239396954915939e-03, 8.153872320255721e-03,
|
||||
4.631183739647523e-02, 2.473187311701327e-01, 2.175254800183617e+00,
|
||||
|
||||
0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113,
|
||||
0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931,
|
||||
0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259,
|
||||
0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304,
|
||||
2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839,
|
||||
|
||||
2.606673548632508, 4.602913725294877, 5.646152813924212,
|
||||
6.488971315540869, 7.249823275816285, 7.977314231410841,
|
||||
8.700354939944047, 9.441728024225892, 10.224338321374127,
|
||||
11.076435368801061, 12.039320937038386, 13.183878752697167,
|
||||
14.657791935084575, 16.885728216339373, 23.361991680031817,
|
||||
|
||||
70.14844087392152, 80.92379498849355, 85.53325420085891,
|
||||
88.94433120715347, 91.83732712857017, 94.46719943606301,
|
||||
96.96896479994635, 99.43412843510363, 101.94074719829733,
|
||||
104.57228644307247, 107.43900093448734, 110.71844673417287,
|
||||
114.76616819871325, 120.57422505959563, 135.92318818757556,
|
||||
|
||||
899.0072447849649, 937.9271278858220, 953.8117189560207,
|
||||
965.3079371501154, 974.8974061207954, 983.4936235182347,
|
||||
991.5691170518946, 999.4334123954690, 1007.3391826856553,
|
||||
1015.5445154999951, 1024.3777075619569, 1034.3538789836223,
|
||||
1046.4872561869577, 1063.5717461999654, 1107.0741966053859
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_pt_chi2)
|
||||
{
|
||||
unsigned i, j;
|
||||
unsigned e = 0;
|
||||
|
||||
for (i = 0; i < sizeof(pt_chi2_df)/sizeof(double); i++) {
|
||||
double df = pt_chi2_df[i];
|
||||
double ln_gamma_df = ln_gamma(df * 0.5);
|
||||
for (j = 1; j < 100; j += 7) {
|
||||
double p = (double)j * 0.01;
|
||||
assert_true(double_eq_rel(pt_chi2(p, df, ln_gamma_df),
|
||||
pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect pt_chi2 result for i=%u, j=%u", i, j);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/*
|
||||
* Expected pt_gamma(p=[0.1..0.99] increment=0.07,
|
||||
* shape=[0.5..3.0] increment=0.5).
|
||||
*/
|
||||
static const double pt_gamma_shape[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0};
|
||||
static const double pt_gamma_expected[] = {
|
||||
7.854392895485103e-05, 5.043466107888016e-03, 1.788288957794883e-02,
|
||||
3.900956150232906e-02, 6.913847560638034e-02, 1.093710833465766e-01,
|
||||
1.613412523825817e-01, 2.274682115597864e-01, 3.114117323127083e-01,
|
||||
4.189466220207417e-01, 5.598106789059246e-01, 7.521856146202706e-01,
|
||||
1.036125427911119e+00, 1.532450860038180e+00, 3.317448300510606e+00,
|
||||
|
||||
0.01005033585350144, 0.08338160893905107, 0.16251892949777497,
|
||||
0.24846135929849966, 0.34249030894677596, 0.44628710262841947,
|
||||
0.56211891815354142, 0.69314718055994529, 0.84397007029452920,
|
||||
1.02165124753198167, 1.23787435600161766, 1.51412773262977574,
|
||||
1.89711998488588196, 2.52572864430825783, 4.60517018598809091,
|
||||
|
||||
0.05741590094955853, 0.24747378084860744, 0.39888572212236084,
|
||||
0.54394139997444901, 0.69048812513915159, 0.84311389861296104,
|
||||
1.00580622221479898, 1.18298694218766931, 1.38038096305861213,
|
||||
1.60627736383027453, 1.87396970522337947, 2.20749220408081070,
|
||||
2.65852391865854942, 3.37934630984842244, 5.67243336507218476,
|
||||
|
||||
0.1485547402532659, 0.4657458011640391, 0.6832386130709406,
|
||||
0.8794297834672100, 1.0700752852474524, 1.2629614217350744,
|
||||
1.4638400448580779, 1.6783469900166610, 1.9132338090606940,
|
||||
2.1778589228618777, 2.4868823970010991, 2.8664695666264195,
|
||||
3.3724415436062114, 4.1682658512758071, 6.6383520679938108,
|
||||
|
||||
0.2771490383641385, 0.7195001279643727, 0.9969081732265243,
|
||||
1.2383497880608061, 1.4675206597269927, 1.6953064251816552,
|
||||
1.9291243435606809, 2.1757300955477641, 2.4428032131216391,
|
||||
2.7406534569230616, 3.0851445039665513, 3.5043101122033367,
|
||||
4.0575997065264637, 4.9182956424675286, 7.5431362346944937,
|
||||
|
||||
0.4360451650782932, 0.9983600902486267, 1.3306365880734528,
|
||||
1.6129750834753802, 1.8767241606994294, 2.1357032436097660,
|
||||
2.3988853336865565, 2.6740603137235603, 2.9697561737517959,
|
||||
3.2971457713883265, 3.6731795898504660, 4.1275751617770631,
|
||||
4.7230515633946677, 5.6417477865306020, 8.4059469148854635
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_pt_gamma_shape)
|
||||
{
|
||||
unsigned i, j;
|
||||
unsigned e = 0;
|
||||
|
||||
for (i = 0; i < sizeof(pt_gamma_shape)/sizeof(double); i++) {
|
||||
double shape = pt_gamma_shape[i];
|
||||
double ln_gamma_shape = ln_gamma(shape);
|
||||
for (j = 1; j < 100; j += 7) {
|
||||
double p = (double)j * 0.01;
|
||||
assert_true(double_eq_rel(pt_gamma(p, shape, 1.0,
|
||||
ln_gamma_shape), pt_gamma_expected[e], MAX_REL_ERR,
|
||||
MAX_ABS_ERR),
|
||||
"Incorrect pt_gamma result for i=%u, j=%u", i, j);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_pt_gamma_scale)
|
||||
{
|
||||
double shape = 1.0;
|
||||
double ln_gamma_shape = ln_gamma(shape);
|
||||
|
||||
assert_true(double_eq_rel(
|
||||
pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0,
|
||||
pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR,
|
||||
MAX_ABS_ERR),
|
||||
"Scale should be trivially equivalent to external multiplication");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_ln_gamma_factorial,
|
||||
test_ln_gamma_misc,
|
||||
test_pt_norm,
|
||||
test_pt_chi2,
|
||||
test_pt_gamma_shape,
|
||||
test_pt_gamma_scale));
|
||||
}
|
92
deps/jemalloc/test/unit/mq.c
vendored
Normal file
92
deps/jemalloc/test/unit/mq.c
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NSENDERS 3
|
||||
#define NMSGS 100000
|
||||
|
||||
typedef struct mq_msg_s mq_msg_t;
|
||||
struct mq_msg_s {
|
||||
mq_msg(mq_msg_t) link;
|
||||
};
|
||||
mq_gen(static, mq_, mq_t, mq_msg_t, link)
|
||||
|
||||
TEST_BEGIN(test_mq_basic)
|
||||
{
|
||||
mq_t mq;
|
||||
mq_msg_t msg;
|
||||
|
||||
assert_false(mq_init(&mq), "Unexpected mq_init() failure");
|
||||
assert_u_eq(mq_count(&mq), 0, "mq should be empty");
|
||||
assert_ptr_null(mq_tryget(&mq),
|
||||
"mq_tryget() should fail when the queue is empty");
|
||||
|
||||
mq_put(&mq, &msg);
|
||||
assert_u_eq(mq_count(&mq), 1, "mq should contain one message");
|
||||
assert_ptr_eq(mq_tryget(&mq), &msg, "mq_tryget() should return msg");
|
||||
|
||||
mq_put(&mq, &msg);
|
||||
assert_ptr_eq(mq_get(&mq), &msg, "mq_get() should return msg");
|
||||
|
||||
mq_fini(&mq);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void *
|
||||
thd_receiver_start(void *arg)
|
||||
{
|
||||
mq_t *mq = (mq_t *)arg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < (NSENDERS * NMSGS); i++) {
|
||||
mq_msg_t *msg = mq_get(mq);
|
||||
assert_ptr_not_null(msg, "mq_get() should never return NULL");
|
||||
dallocx(msg, 0);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void *
|
||||
thd_sender_start(void *arg)
|
||||
{
|
||||
mq_t *mq = (mq_t *)arg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NMSGS; i++) {
|
||||
mq_msg_t *msg;
|
||||
void *p;
|
||||
p = mallocx(sizeof(mq_msg_t), 0);
|
||||
assert_ptr_not_null(p, "Unexpected allocm() failure");
|
||||
msg = (mq_msg_t *)p;
|
||||
mq_put(mq, msg);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_mq_threaded)
|
||||
{
|
||||
mq_t mq;
|
||||
thd_t receiver;
|
||||
thd_t senders[NSENDERS];
|
||||
unsigned i;
|
||||
|
||||
assert_false(mq_init(&mq), "Unexpected mq_init() failure");
|
||||
|
||||
thd_create(&receiver, thd_receiver_start, (void *)&mq);
|
||||
for (i = 0; i < NSENDERS; i++)
|
||||
thd_create(&senders[i], thd_sender_start, (void *)&mq);
|
||||
|
||||
thd_join(receiver, NULL);
|
||||
for (i = 0; i < NSENDERS; i++)
|
||||
thd_join(senders[i], NULL);
|
||||
|
||||
mq_fini(&mq);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return (test(
|
||||
test_mq_basic,
|
||||
test_mq_threaded));
|
||||
}
|
||||
|
60
deps/jemalloc/test/unit/mtx.c
vendored
Normal file
60
deps/jemalloc/test/unit/mtx.c
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NTHREADS 2
|
||||
#define NINCRS 2000000
|
||||
|
||||
TEST_BEGIN(test_mtx_basic)
|
||||
{
|
||||
mtx_t mtx;
|
||||
|
||||
assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure");
|
||||
mtx_lock(&mtx);
|
||||
mtx_unlock(&mtx);
|
||||
mtx_fini(&mtx);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
typedef struct {
|
||||
mtx_t mtx;
|
||||
unsigned x;
|
||||
} thd_start_arg_t;
|
||||
|
||||
static void *
|
||||
thd_start(void *varg)
|
||||
{
|
||||
thd_start_arg_t *arg = (thd_start_arg_t *)varg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NINCRS; i++) {
|
||||
mtx_lock(&arg->mtx);
|
||||
arg->x++;
|
||||
mtx_unlock(&arg->mtx);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_mtx_race)
|
||||
{
|
||||
thd_start_arg_t arg;
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure");
|
||||
arg.x = 0;
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_create(&thds[i], thd_start, (void *)&arg);
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_join(thds[i], NULL);
|
||||
assert_u_eq(arg.x, NTHREADS * NINCRS,
|
||||
"Race-related counter corruption");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_mtx_basic,
|
||||
test_mtx_race));
|
||||
}
|
86
deps/jemalloc/test/unit/prof_accum.c
vendored
Normal file
86
deps/jemalloc/test/unit/prof_accum.c
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
#include "prof_accum.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf =
|
||||
"prof:true,prof_accum: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 *
|
||||
alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration)
|
||||
{
|
||||
|
||||
return (alloc_0(thd_ind*NALLOCS_PER_THREAD + iteration));
|
||||
}
|
||||
|
||||
static void *
|
||||
thd_start(void *varg)
|
||||
{
|
||||
unsigned thd_ind = *(unsigned *)varg;
|
||||
size_t bt_count_prev, bt_count;
|
||||
unsigned i_prev, i;
|
||||
|
||||
i_prev = 0;
|
||||
bt_count_prev = 0;
|
||||
for (i = 0; i < NALLOCS_PER_THREAD; i++) {
|
||||
void *p = alloc_from_permuted_backtrace(thd_ind, i);
|
||||
dallocx(p, 0);
|
||||
if (i % DUMP_INTERVAL == 0) {
|
||||
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
|
||||
0, "Unexpected error while dumping heap profile");
|
||||
}
|
||||
|
||||
if (i % BT_COUNT_CHECK_INTERVAL == 0 ||
|
||||
i+1 == NALLOCS_PER_THREAD) {
|
||||
bt_count = prof_bt_count();
|
||||
assert_zu_le(bt_count_prev+(i-i_prev), bt_count,
|
||||
"Expected larger backtrace count increase");
|
||||
i_prev = i;
|
||||
bt_count_prev = bt_count;
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_idump)
|
||||
{
|
||||
bool active;
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned thd_args[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
active = true;
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure while activating profiling");
|
||||
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
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
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_idump));
|
||||
}
|
35
deps/jemalloc/test/unit/prof_accum.h
vendored
Normal file
35
deps/jemalloc/test/unit/prof_accum.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NTHREADS 4
|
||||
#define NALLOCS_PER_THREAD 50
|
||||
#define DUMP_INTERVAL 1
|
||||
#define BT_COUNT_CHECK_INTERVAL 5
|
||||
|
||||
#define alloc_n_proto(n) \
|
||||
void *alloc_##n(unsigned bits);
|
||||
alloc_n_proto(0)
|
||||
alloc_n_proto(1)
|
||||
|
||||
#define alloc_n_gen(n) \
|
||||
void * \
|
||||
alloc_##n(unsigned bits) \
|
||||
{ \
|
||||
void *p; \
|
||||
\
|
||||
if (bits == 0) \
|
||||
p = mallocx(1, 0); \
|
||||
else { \
|
||||
switch (bits & 0x1U) { \
|
||||
case 0: \
|
||||
p = (alloc_0(bits >> 1)); \
|
||||
break; \
|
||||
case 1: \
|
||||
p = (alloc_1(bits >> 1)); \
|
||||
break; \
|
||||
default: not_reached(); \
|
||||
} \
|
||||
} \
|
||||
/* Intentionally sabotage tail call optimization. */ \
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure"); \
|
||||
return (p); \
|
||||
}
|
3
deps/jemalloc/test/unit/prof_accum_a.c
vendored
Normal file
3
deps/jemalloc/test/unit/prof_accum_a.c
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "prof_accum.h"
|
||||
|
||||
alloc_n_gen(0)
|
3
deps/jemalloc/test/unit/prof_accum_b.c
vendored
Normal file
3
deps/jemalloc/test/unit/prof_accum_b.c
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "prof_accum.h"
|
||||
|
||||
alloc_n_gen(1)
|
56
deps/jemalloc/test/unit/prof_gdump.c
vendored
Normal file
56
deps/jemalloc/test/unit/prof_gdump.c
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf = "prof:true,prof_active:false,prof_gdump:true";
|
||||
#endif
|
||||
|
||||
static bool did_prof_dump_open;
|
||||
|
||||
static int
|
||||
prof_dump_open_intercept(bool propagate_err, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
did_prof_dump_open = true;
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_gdump)
|
||||
{
|
||||
bool active;
|
||||
void *p, *q;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
active = true;
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure while activating profiling");
|
||||
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
did_prof_dump_open = false;
|
||||
p = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
assert_true(did_prof_dump_open, "Expected a profile dump");
|
||||
|
||||
did_prof_dump_open = false;
|
||||
q = 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);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_gdump));
|
||||
}
|
51
deps/jemalloc/test/unit/prof_idump.c
vendored
Normal file
51
deps/jemalloc/test/unit/prof_idump.c
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf =
|
||||
"prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0,"
|
||||
"lg_prof_interval:0";
|
||||
#endif
|
||||
|
||||
static bool did_prof_dump_open;
|
||||
|
||||
static int
|
||||
prof_dump_open_intercept(bool propagate_err, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
did_prof_dump_open = true;
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_idump)
|
||||
{
|
||||
bool active;
|
||||
void *p;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
active = true;
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure while activating profiling");
|
||||
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
did_prof_dump_open = false;
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
dallocx(p, 0);
|
||||
assert_true(did_prof_dump_open, "Expected a profile dump");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_idump));
|
||||
}
|
209
deps/jemalloc/test/unit/ql.c
vendored
Normal file
209
deps/jemalloc/test/unit/ql.c
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
/* Number of ring entries, in [2..26]. */
|
||||
#define NENTRIES 9
|
||||
|
||||
typedef struct list_s list_t;
|
||||
typedef ql_head(list_t) list_head_t;
|
||||
|
||||
struct list_s {
|
||||
ql_elm(list_t) link;
|
||||
char id;
|
||||
};
|
||||
|
||||
static void
|
||||
test_empty_list(list_head_t *head)
|
||||
{
|
||||
list_t *t;
|
||||
unsigned i;
|
||||
|
||||
assert_ptr_null(ql_first(head), "Unexpected element for empty list");
|
||||
assert_ptr_null(ql_last(head, link),
|
||||
"Unexpected element for empty list");
|
||||
|
||||
i = 0;
|
||||
ql_foreach(t, head, link) {
|
||||
i++;
|
||||
}
|
||||
assert_u_eq(i, 0, "Unexpected element for empty list");
|
||||
|
||||
i = 0;
|
||||
ql_reverse_foreach(t, head, link) {
|
||||
i++;
|
||||
}
|
||||
assert_u_eq(i, 0, "Unexpected element for empty list");
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ql_empty)
|
||||
{
|
||||
list_head_t head;
|
||||
|
||||
ql_new(&head);
|
||||
test_empty_list(&head);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
init_entries(list_t *entries, unsigned nentries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nentries; i++) {
|
||||
entries[i].id = 'a' + i;
|
||||
ql_elm_new(&entries[i], link);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_entries_list(list_head_t *head, list_t *entries, unsigned nentries)
|
||||
{
|
||||
list_t *t;
|
||||
unsigned i;
|
||||
|
||||
assert_c_eq(ql_first(head)->id, entries[0].id, "Element id mismatch");
|
||||
assert_c_eq(ql_last(head, link)->id, entries[nentries-1].id,
|
||||
"Element id mismatch");
|
||||
|
||||
i = 0;
|
||||
ql_foreach(t, head, link) {
|
||||
assert_c_eq(t->id, entries[i].id, "Element id mismatch");
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
ql_reverse_foreach(t, head, link) {
|
||||
assert_c_eq(t->id, entries[nentries-i-1].id,
|
||||
"Element id mismatch");
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < nentries-1; i++) {
|
||||
t = ql_next(head, &entries[i], link);
|
||||
assert_c_eq(t->id, entries[i+1].id, "Element id mismatch");
|
||||
}
|
||||
assert_ptr_null(ql_next(head, &entries[nentries-1], link),
|
||||
"Unexpected element");
|
||||
|
||||
assert_ptr_null(ql_prev(head, &entries[0], link), "Unexpected element");
|
||||
for (i = 1; i < nentries; i++) {
|
||||
t = ql_prev(head, &entries[i], link);
|
||||
assert_c_eq(t->id, entries[i-1].id, "Element id mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ql_tail_insert)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_tail_insert(&head, &entries[i], link);
|
||||
|
||||
test_entries_list(&head, entries, NENTRIES);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_tail_remove)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_tail_insert(&head, &entries[i], link);
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
test_entries_list(&head, entries, NENTRIES-i);
|
||||
ql_tail_remove(&head, list_t, link);
|
||||
}
|
||||
test_empty_list(&head);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_head_insert)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_head_insert(&head, &entries[NENTRIES-i-1], link);
|
||||
|
||||
test_entries_list(&head, entries, NENTRIES);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_head_remove)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_head_insert(&head, &entries[NENTRIES-i-1], link);
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
test_entries_list(&head, &entries[i], NENTRIES-i);
|
||||
ql_head_remove(&head, list_t, link);
|
||||
}
|
||||
test_empty_list(&head);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_insert)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[8];
|
||||
list_t *a, *b, *c, *d, *e, *f, *g, *h;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
a = &entries[0];
|
||||
b = &entries[1];
|
||||
c = &entries[2];
|
||||
d = &entries[3];
|
||||
e = &entries[4];
|
||||
f = &entries[5];
|
||||
g = &entries[6];
|
||||
h = &entries[7];
|
||||
|
||||
/*
|
||||
* ql_remove(), ql_before_insert(), and ql_after_insert() are used
|
||||
* internally by other macros that are already tested, so there's no
|
||||
* need to test them completely. However, insertion/deletion from the
|
||||
* middle of lists is not otherwise tested; do so here.
|
||||
*/
|
||||
ql_tail_insert(&head, f, link);
|
||||
ql_before_insert(&head, f, b, link);
|
||||
ql_before_insert(&head, f, c, link);
|
||||
ql_after_insert(f, h, link);
|
||||
ql_after_insert(f, g, link);
|
||||
ql_before_insert(&head, b, a, link);
|
||||
ql_after_insert(c, d, link);
|
||||
ql_before_insert(&head, f, e, link);
|
||||
|
||||
test_entries_list(&head, entries, sizeof(entries)/sizeof(list_t));
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_ql_empty,
|
||||
test_ql_tail_insert,
|
||||
test_ql_tail_remove,
|
||||
test_ql_head_insert,
|
||||
test_ql_head_remove,
|
||||
test_ql_insert));
|
||||
}
|
248
deps/jemalloc/test/unit/qr.c
vendored
Normal file
248
deps/jemalloc/test/unit/qr.c
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
/* Number of ring entries, in [2..26]. */
|
||||
#define NENTRIES 9
|
||||
/* Split index, in [1..NENTRIES). */
|
||||
#define SPLIT_INDEX 5
|
||||
|
||||
typedef struct ring_s ring_t;
|
||||
|
||||
struct ring_s {
|
||||
qr(ring_t) link;
|
||||
char id;
|
||||
};
|
||||
|
||||
static void
|
||||
init_entries(ring_t *entries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
qr_new(&entries[i], link);
|
||||
entries[i].id = 'a' + i;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_independent_entries(ring_t *entries)
|
||||
{
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
j++;
|
||||
}
|
||||
assert_u_eq(j, 1,
|
||||
"Iteration over single-element ring should visit precisely "
|
||||
"one element");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
j++;
|
||||
}
|
||||
assert_u_eq(j, 1,
|
||||
"Iteration over single-element ring should visit precisely "
|
||||
"one element");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_next(&entries[i], link);
|
||||
assert_ptr_eq(t, &entries[i],
|
||||
"Next element in single-element ring should be same as "
|
||||
"current element");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_prev(&entries[i], link);
|
||||
assert_ptr_eq(t, &entries[i],
|
||||
"Previous element in single-element ring should be same as "
|
||||
"current element");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_qr_one)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
|
||||
init_entries(entries);
|
||||
test_independent_entries(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
test_entries_ring(ring_t *entries)
|
||||
{
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(i+j) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-j-1) %
|
||||
NENTRIES].id, "Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_next(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(i+1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_prev(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_qr_after_insert)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
test_entries_ring(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_qr_remove)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[i+j].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[NENTRIES - 1 - j].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
qr_remove(&entries[i], link);
|
||||
}
|
||||
test_independent_entries(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_qr_before_insert)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_before_insert(&entries[i - 1], &entries[i], link);
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-j) %
|
||||
NENTRIES].id, "Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(i+j+1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_next(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_prev(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(i+1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
test_split_entries(ring_t *entries)
|
||||
{
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
if (i < SPLIT_INDEX) {
|
||||
assert_c_eq(t->id,
|
||||
entries[(i+j) % SPLIT_INDEX].id,
|
||||
"Element id mismatch");
|
||||
} else {
|
||||
assert_c_eq(t->id, entries[(i+j-SPLIT_INDEX) %
|
||||
(NENTRIES-SPLIT_INDEX) + SPLIT_INDEX].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_qr_meld_split)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_split_entries(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_split_entries(entries);
|
||||
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_split(&entries[0], &entries[0], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[0], link);
|
||||
test_entries_ring(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_qr_one,
|
||||
test_qr_after_insert,
|
||||
test_qr_remove,
|
||||
test_qr_before_insert,
|
||||
test_qr_meld_split));
|
||||
}
|
108
deps/jemalloc/test/unit/quarantine.c
vendored
Normal file
108
deps/jemalloc/test/unit/quarantine.c
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define QUARANTINE_SIZE 8192
|
||||
#define STRINGIFY_HELPER(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_HELPER(x)
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:"
|
||||
STRINGIFY(QUARANTINE_SIZE);
|
||||
#endif
|
||||
|
||||
void
|
||||
quarantine_clear(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = mallocx(QUARANTINE_SIZE*2, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
dallocx(p, 0);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_quarantine)
|
||||
{
|
||||
#define SZ ZU(256)
|
||||
#define NQUARANTINED (QUARANTINE_SIZE/SZ)
|
||||
void *quarantined[NQUARANTINED+1];
|
||||
size_t i, j;
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
|
||||
assert_zu_eq(nallocx(SZ, 0), SZ,
|
||||
"SZ=%zu does not precisely equal a size class", SZ);
|
||||
|
||||
quarantine_clear();
|
||||
|
||||
/*
|
||||
* Allocate enough regions to completely fill the quarantine, plus one
|
||||
* more. The last iteration occurs with a completely full quarantine,
|
||||
* but no regions should be drained from the quarantine until the last
|
||||
* deallocation occurs. Therefore no region recycling should occur
|
||||
* until after this loop completes.
|
||||
*/
|
||||
for (i = 0; i < NQUARANTINED+1; i++) {
|
||||
void *p = mallocx(SZ, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
quarantined[i] = p;
|
||||
dallocx(p, 0);
|
||||
for (j = 0; j < i; j++) {
|
||||
assert_ptr_ne(p, quarantined[j],
|
||||
"Quarantined region recycled too early; "
|
||||
"i=%zu, j=%zu", i, j);
|
||||
}
|
||||
}
|
||||
#undef NQUARANTINED
|
||||
#undef SZ
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static bool detected_redzone_corruption;
|
||||
|
||||
static void
|
||||
arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,
|
||||
size_t offset, uint8_t byte)
|
||||
{
|
||||
|
||||
detected_redzone_corruption = true;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_quarantine_redzone)
|
||||
{
|
||||
char *s;
|
||||
arena_redzone_corruption_t *arena_redzone_corruption_orig;
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
|
||||
arena_redzone_corruption_orig = arena_redzone_corruption;
|
||||
arena_redzone_corruption = arena_redzone_corruption_replacement;
|
||||
|
||||
/* Test underflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[-1] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
/* Test overflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[sallocx(s, 0)] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
arena_redzone_corruption = arena_redzone_corruption_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_quarantine,
|
||||
test_quarantine_redzone));
|
||||
}
|
333
deps/jemalloc/test/unit/rb.c
vendored
Normal file
333
deps/jemalloc/test/unit/rb.c
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define rbtn_black_height(a_type, a_field, a_rbt, r_height) do { \
|
||||
a_type *rbp_bh_t; \
|
||||
for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0; \
|
||||
rbp_bh_t != &(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) { \
|
||||
(r_height)++; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef struct node_s node_t;
|
||||
|
||||
struct node_s {
|
||||
#define NODE_MAGIC 0x9823af7e
|
||||
uint32_t magic;
|
||||
rb_node(node_t) link;
|
||||
uint64_t key;
|
||||
};
|
||||
|
||||
static int
|
||||
node_cmp(node_t *a, node_t *b) {
|
||||
int ret;
|
||||
|
||||
assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
|
||||
assert_u32_eq(b->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
ret = (a->key > b->key) - (a->key < b->key);
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Duplicates are not allowed in the tree, 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);
|
||||
}
|
||||
|
||||
typedef rb_tree(node_t) tree_t;
|
||||
rb_gen(static, tree_, tree_t, node_t, link, node_cmp);
|
||||
|
||||
TEST_BEGIN(test_rb_empty)
|
||||
{
|
||||
tree_t tree;
|
||||
node_t key;
|
||||
|
||||
tree_new(&tree);
|
||||
|
||||
assert_ptr_null(tree_first(&tree), "Unexpected node");
|
||||
assert_ptr_null(tree_last(&tree), "Unexpected node");
|
||||
|
||||
key.key = 0;
|
||||
key.magic = NODE_MAGIC;
|
||||
assert_ptr_null(tree_search(&tree, &key), "Unexpected node");
|
||||
|
||||
key.key = 0;
|
||||
key.magic = NODE_MAGIC;
|
||||
assert_ptr_null(tree_nsearch(&tree, &key), "Unexpected node");
|
||||
|
||||
key.key = 0;
|
||||
key.magic = NODE_MAGIC;
|
||||
assert_ptr_null(tree_psearch(&tree, &key), "Unexpected node");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static unsigned
|
||||
tree_recurse(node_t *node, unsigned black_height, unsigned black_depth,
|
||||
node_t *nil)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
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)
|
||||
black_depth++;
|
||||
|
||||
/* Red nodes must be interleaved with black nodes. */
|
||||
if (rbtn_red_get(node_t, link, node)) {
|
||||
assert_false(rbtn_red_get(node_t, link, left_node),
|
||||
"Node should be black");
|
||||
assert_false(rbtn_red_get(node_t, link, right_node),
|
||||
"Node should be black");
|
||||
}
|
||||
|
||||
if (node == nil)
|
||||
return (ret);
|
||||
/* Self. */
|
||||
assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
/* Left subtree. */
|
||||
if (left_node != nil)
|
||||
ret += tree_recurse(left_node, black_height, black_depth, nil);
|
||||
else
|
||||
ret += (black_depth != black_height);
|
||||
|
||||
/* Right subtree. */
|
||||
if (right_node != nil)
|
||||
ret += tree_recurse(right_node, black_height, black_depth, nil);
|
||||
else
|
||||
ret += (black_depth != black_height);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static node_t *
|
||||
tree_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned *i = (unsigned *)data;
|
||||
node_t *search_node;
|
||||
|
||||
assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
/* Test rb_search(). */
|
||||
search_node = tree_search(tree, node);
|
||||
assert_ptr_eq(search_node, node,
|
||||
"tree_search() returned unexpected node");
|
||||
|
||||
/* Test rb_nsearch(). */
|
||||
search_node = tree_nsearch(tree, node);
|
||||
assert_ptr_eq(search_node, node,
|
||||
"tree_nsearch() returned unexpected node");
|
||||
|
||||
/* Test rb_psearch(). */
|
||||
search_node = tree_psearch(tree, node);
|
||||
assert_ptr_eq(search_node, node,
|
||||
"tree_psearch() returned unexpected node");
|
||||
|
||||
(*i)++;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
tree_iterate(tree_t *tree)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
tree_iter(tree, NULL, tree_iterate_cb, (void *)&i);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
tree_iterate_reverse(tree_t *tree)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
tree_reverse_iter(tree, NULL, tree_iterate_cb, (void *)&i);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
static void
|
||||
node_remove(tree_t *tree, node_t *node, unsigned nnodes)
|
||||
{
|
||||
node_t *search_node;
|
||||
unsigned black_height, imbalances;
|
||||
|
||||
tree_remove(tree, node);
|
||||
|
||||
/* Test rb_nsearch(). */
|
||||
search_node = tree_nsearch(tree, node);
|
||||
if (search_node != NULL) {
|
||||
assert_u64_ge(search_node->key, node->key,
|
||||
"Key ordering error");
|
||||
}
|
||||
|
||||
/* Test rb_psearch(). */
|
||||
search_node = tree_psearch(tree, node);
|
||||
if (search_node != NULL) {
|
||||
assert_u64_le(search_node->key, node->key,
|
||||
"Key ordering error");
|
||||
}
|
||||
|
||||
node->magic = 0;
|
||||
|
||||
rbtn_black_height(node_t, link, tree, black_height);
|
||||
imbalances = tree_recurse(tree->rbt_root, black_height, 0,
|
||||
&(tree->rbt_nil));
|
||||
assert_u_eq(imbalances, 0, "Tree is unbalanced");
|
||||
assert_u_eq(tree_iterate(tree), nnodes-1,
|
||||
"Unexpected node iteration count");
|
||||
assert_u_eq(tree_iterate_reverse(tree), nnodes-1,
|
||||
"Unexpected node iteration count");
|
||||
}
|
||||
|
||||
static node_t *
|
||||
remove_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
node_t *ret = tree_next(tree, node);
|
||||
|
||||
node_remove(tree, node, *nnodes);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static node_t *
|
||||
remove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
node_t *ret = tree_prev(tree, node);
|
||||
|
||||
node_remove(tree, node, *nnodes);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_rb_random)
|
||||
{
|
||||
#define NNODES 25
|
||||
#define NBAGS 250
|
||||
#define SEED 42
|
||||
sfmt_t *sfmt;
|
||||
uint64_t bag[NNODES];
|
||||
tree_t tree;
|
||||
node_t nodes[NNODES];
|
||||
unsigned i, j, k, black_height, imbalances;
|
||||
|
||||
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 tree and nodes. */
|
||||
tree_new(&tree);
|
||||
tree.rbt_nil.magic = 0;
|
||||
for (k = 0; k < j; k++) {
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
}
|
||||
|
||||
/* Insert nodes. */
|
||||
for (k = 0; k < j; k++) {
|
||||
tree_insert(&tree, &nodes[k]);
|
||||
|
||||
rbtn_black_height(node_t, link, &tree,
|
||||
black_height);
|
||||
imbalances = tree_recurse(tree.rbt_root,
|
||||
black_height, 0, &(tree.rbt_nil));
|
||||
assert_u_eq(imbalances, 0,
|
||||
"Tree is unbalanced");
|
||||
|
||||
assert_u_eq(tree_iterate(&tree), k+1,
|
||||
"Unexpected node iteration count");
|
||||
assert_u_eq(tree_iterate_reverse(&tree), k+1,
|
||||
"Unexpected node iteration count");
|
||||
|
||||
assert_ptr_not_null(tree_first(&tree),
|
||||
"Tree should not be empty");
|
||||
assert_ptr_not_null(tree_last(&tree),
|
||||
"Tree should not be empty");
|
||||
|
||||
tree_next(&tree, &nodes[k]);
|
||||
tree_prev(&tree, &nodes[k]);
|
||||
}
|
||||
|
||||
/* Remove nodes. */
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
for (k = 0; k < j; k++)
|
||||
node_remove(&tree, &nodes[k], j - k);
|
||||
break;
|
||||
case 1:
|
||||
for (k = j; k > 0; k--)
|
||||
node_remove(&tree, &nodes[k-1], k);
|
||||
break;
|
||||
case 2: {
|
||||
node_t *start;
|
||||
unsigned nnodes = j;
|
||||
|
||||
start = NULL;
|
||||
do {
|
||||
start = tree_iter(&tree, start,
|
||||
remove_iterate_cb, (void *)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert_u_eq(nnodes, 0,
|
||||
"Removal terminated early");
|
||||
break;
|
||||
} case 3: {
|
||||
node_t *start;
|
||||
unsigned nnodes = j;
|
||||
|
||||
start = NULL;
|
||||
do {
|
||||
start = tree_reverse_iter(&tree, start,
|
||||
remove_reverse_iterate_cb,
|
||||
(void *)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert_u_eq(nnodes, 0,
|
||||
"Removal terminated early");
|
||||
break;
|
||||
} default:
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
fini_gen_rand(sfmt);
|
||||
#undef NNODES
|
||||
#undef NBAGS
|
||||
#undef SEED
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_rb_empty,
|
||||
test_rb_random));
|
||||
}
|
118
deps/jemalloc/test/unit/rtree.c
vendored
Normal file
118
deps/jemalloc/test/unit/rtree.c
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
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_get() should return NULL for empty tree");
|
||||
rtree_delete(rtree);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_rtree_extrema)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
|
||||
rtree_t *rtree = rtree_new(i, imalloc, idalloc);
|
||||
|
||||
rtree_set(rtree, 0, 1);
|
||||
assert_u_eq(rtree_get(rtree, 0), 1,
|
||||
"rtree_get() should return previously set value");
|
||||
|
||||
rtree_set(rtree, ~((uintptr_t)0), 1);
|
||||
assert_u_eq(rtree_get(rtree, ~((uintptr_t)0)), 1,
|
||||
"rtree_get() should return previously set value");
|
||||
|
||||
rtree_delete(rtree);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_rtree_bits)
|
||||
{
|
||||
unsigned i, j, k;
|
||||
|
||||
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);
|
||||
|
||||
for (j = 0; j < sizeof(keys)/sizeof(uintptr_t); j++) {
|
||||
rtree_set(rtree, keys[j], 1);
|
||||
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_u_eq(rtree_get(rtree,
|
||||
(((uintptr_t)1) << (sizeof(uintptr_t)*8-i))), 0,
|
||||
"Only leftmost rtree leaf should be set; "
|
||||
"i=%u, j=%u", i, j);
|
||||
rtree_set(rtree, keys[j], 0);
|
||||
}
|
||||
|
||||
rtree_delete(rtree);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_rtree_random)
|
||||
{
|
||||
unsigned i;
|
||||
sfmt_t *sfmt;
|
||||
#define NSET 100
|
||||
#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];
|
||||
unsigned j;
|
||||
|
||||
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,
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
for (j = 0; j < NSET; j++) {
|
||||
assert_u_eq(rtree_get(rtree, keys[j]), 1,
|
||||
"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,
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
for (j = 0; j < NSET; j++) {
|
||||
assert_u_eq(rtree_get(rtree, keys[j]), 0,
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
|
||||
rtree_delete(rtree);
|
||||
}
|
||||
fini_gen_rand(sfmt);
|
||||
#undef NSET
|
||||
#undef SEED
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_rtree_get_empty,
|
||||
test_rtree_extrema,
|
||||
test_rtree_bits,
|
||||
test_rtree_random));
|
||||
}
|
380
deps/jemalloc/test/unit/stats.c
vendored
Normal file
380
deps/jemalloc/test/unit/stats.c
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_stats_summary)
|
||||
{
|
||||
size_t *cactive;
|
||||
size_t sz, allocated, active, mapped;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
sz = sizeof(cactive);
|
||||
assert_d_eq(mallctl("stats.cactive", &cactive, &sz, NULL, 0), expected,
|
||||
"Unexpected mallctl() result");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0),
|
||||
expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected,
|
||||
"Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
|
||||
"Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_le(active, *cactive,
|
||||
"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", ¤t, &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");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_huge)
|
||||
{
|
||||
void *p;
|
||||
uint64_t epoch;
|
||||
size_t allocated;
|
||||
uint64_t nmalloc, ndalloc;
|
||||
size_t sz;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
p = mallocx(arena_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");
|
||||
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");
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_summary)
|
||||
{
|
||||
unsigned arena;
|
||||
void *small, *large;
|
||||
uint64_t epoch;
|
||||
size_t sz;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
size_t mapped;
|
||||
uint64_t npurge, nmadvise, purged;
|
||||
|
||||
arena = 0;
|
||||
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);
|
||||
assert_ptr_not_null(large, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.mapped", &mapped, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.nmadvise", &nmadvise, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.purged", &purged, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_u64_gt(npurge, 0,
|
||||
"At least one purge should have occurred");
|
||||
assert_u64_le(nmadvise, purged,
|
||||
"nmadvise should be no greater than purged");
|
||||
}
|
||||
|
||||
dallocx(small, 0);
|
||||
dallocx(large, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
no_lazy_lock(void)
|
||||
{
|
||||
thd_t thd;
|
||||
|
||||
thd_create(&thd, thd_start, NULL);
|
||||
thd_join(thd, NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_small)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, allocated;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
no_lazy_lock(); /* Lazy locking would dodge tcache testing. */
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(SMALL_MAXCLASS, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
|
||||
config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.allocated", &allocated, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be no 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");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_large)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, allocated;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests;
|
||||
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(arena_maxclass, 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.large.allocated", &allocated, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_zu_gt(nmalloc, 0,
|
||||
"nmalloc should be greater than zero");
|
||||
assert_zu_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_zu_gt(nrequests, 0,
|
||||
"nrequests should be greater than zero");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_bins)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, allocated, curruns;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;
|
||||
uint64_t nruns, nreruns;
|
||||
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(arena_bin_info[0].reg_size, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
|
||||
config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &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");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz,
|
||||
NULL, 0), config_tcache ? expected : ENOENT,
|
||||
"Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", &nflushes, &sz,
|
||||
NULL, 0), config_tcache ? expected : ENOENT,
|
||||
"Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", &nruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", &nreruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", &curruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"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");
|
||||
if (config_tcache) {
|
||||
assert_u64_gt(nfills, 0,
|
||||
"At least one fill should have occurred");
|
||||
assert_u64_gt(nflushes, 0,
|
||||
"At least one flush should have occurred");
|
||||
}
|
||||
assert_u64_gt(nruns, 0,
|
||||
"At least one run should have been allocated");
|
||||
assert_zu_gt(curruns, 0,
|
||||
"At least one run should be currently allocated");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_lruns)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests;
|
||||
size_t curruns, 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(SMALL_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(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", &curruns, &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(nrequests, 0,
|
||||
"nrequests should be greater than zero");
|
||||
assert_u64_gt(curruns, 0,
|
||||
"At least one run 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_bins,
|
||||
test_stats_arenas_lruns));
|
||||
}
|
71
deps/jemalloc/test/unit/tsd.c
vendored
Normal file
71
deps/jemalloc/test/unit/tsd.c
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define THREAD_DATA 0x72b65c10
|
||||
|
||||
typedef unsigned int data_t;
|
||||
|
||||
static bool data_cleanup_executed;
|
||||
|
||||
void
|
||||
data_cleanup(void *arg)
|
||||
{
|
||||
data_t *data = (data_t *)arg;
|
||||
|
||||
assert_x_eq(*data, THREAD_DATA,
|
||||
"Argument passed into cleanup function should match tsd value");
|
||||
data_cleanup_executed = true;
|
||||
}
|
||||
|
||||
malloc_tsd_protos(, 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)
|
||||
|
||||
static void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
data_t d = (data_t)(uintptr_t)arg;
|
||||
assert_x_eq(*data_tsd_get(), DATA_INIT,
|
||||
"Initial tsd get should return initialization value");
|
||||
|
||||
data_tsd_set(&d);
|
||||
assert_x_eq(*data_tsd_get(), d,
|
||||
"After tsd set, tsd get should return value that was set");
|
||||
|
||||
d = 0;
|
||||
assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg,
|
||||
"Resetting local data should have no effect on tsd");
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_tsd_main_thread)
|
||||
{
|
||||
|
||||
thd_start((void *) 0xa5f3e329);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_tsd_sub_thread)
|
||||
{
|
||||
thd_t thd;
|
||||
|
||||
data_cleanup_executed = false;
|
||||
thd_create(&thd, thd_start, (void *)THREAD_DATA);
|
||||
thd_join(thd, NULL);
|
||||
assert_true(data_cleanup_executed,
|
||||
"Cleanup function should have executed");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
data_tsd_boot();
|
||||
|
||||
return (test(
|
||||
test_tsd_main_thread,
|
||||
test_tsd_sub_thread));
|
||||
}
|
294
deps/jemalloc/test/unit/util.c
vendored
Normal file
294
deps/jemalloc/test/unit/util.c
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_pow2_ceil)
|
||||
{
|
||||
unsigned i, pow2;
|
||||
size_t x;
|
||||
|
||||
assert_zu_eq(pow2_ceil(0), 0, "Unexpected result");
|
||||
|
||||
for (i = 0; i < sizeof(size_t) * 8; i++) {
|
||||
assert_zu_eq(pow2_ceil(ZU(1) << i), ZU(1) << i,
|
||||
"Unexpected result");
|
||||
}
|
||||
|
||||
for (i = 2; i < sizeof(size_t) * 8; i++) {
|
||||
assert_zu_eq(pow2_ceil((ZU(1) << i) - 1), ZU(1) << i,
|
||||
"Unexpected result");
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(size_t) * 8 - 1; i++) {
|
||||
assert_zu_eq(pow2_ceil((ZU(1) << i) + 1), ZU(1) << (i+1),
|
||||
"Unexpected result");
|
||||
}
|
||||
|
||||
for (pow2 = 1; pow2 < 25; pow2++) {
|
||||
for (x = (ZU(1) << (pow2-1)) + 1; x <= ZU(1) << pow2; x++) {
|
||||
assert_zu_eq(pow2_ceil(x), ZU(1) << pow2,
|
||||
"Unexpected result, x=%zu", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_strtoumax_no_endptr)
|
||||
{
|
||||
int err;
|
||||
|
||||
set_errno(0);
|
||||
assert_ju_eq(malloc_strtoumax("0", NULL, 0), 0, "Unexpected result");
|
||||
err = get_errno();
|
||||
assert_d_eq(err, 0, "Unexpected failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_strtoumax)
|
||||
{
|
||||
struct test_s {
|
||||
const char *input;
|
||||
const char *expected_remainder;
|
||||
int base;
|
||||
int expected_errno;
|
||||
const char *expected_errno_name;
|
||||
uintmax_t expected_x;
|
||||
};
|
||||
#define ERR(e) e, #e
|
||||
#define UMAX(x) ((uintmax_t)x##ULL)
|
||||
struct test_s tests[] = {
|
||||
{"0", "0", -1, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"0", "0", 1, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"0", "0", 37, ERR(EINVAL), UINTMAX_MAX},
|
||||
|
||||
{"", "", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"+", "+", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"++3", "++3", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"-", "-", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
|
||||
{"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)}
|
||||
};
|
||||
#undef ERR
|
||||
#undef UMAX
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) {
|
||||
struct test_s *test = &tests[i];
|
||||
int err;
|
||||
uintmax_t result;
|
||||
char *remainder;
|
||||
|
||||
set_errno(0);
|
||||
result = malloc_strtoumax(test->input, &remainder, test->base);
|
||||
err = get_errno();
|
||||
assert_d_eq(err, test->expected_errno,
|
||||
"Expected errno %s for \"%s\", base %d",
|
||||
test->expected_errno_name, test->input, test->base);
|
||||
assert_str_eq(remainder, test->expected_remainder,
|
||||
"Unexpected remainder for \"%s\", base %d",
|
||||
test->input, test->base);
|
||||
if (err == 0) {
|
||||
assert_ju_eq(result, test->expected_x,
|
||||
"Unexpected result for \"%s\", base %d",
|
||||
test->input, test->base);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_snprintf_truncated)
|
||||
{
|
||||
#define BUFLEN 15
|
||||
char buf[BUFLEN];
|
||||
int result;
|
||||
size_t len;
|
||||
#define TEST(expected_str_untruncated, fmt...) do { \
|
||||
result = malloc_snprintf(buf, len, fmt); \
|
||||
assert_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0, \
|
||||
"Unexpected string inequality (\"%s\" vs \"%s\")", \
|
||||
buf, expected_str_untruncated); \
|
||||
assert_d_eq(result, strlen(expected_str_untruncated), \
|
||||
"Unexpected result"); \
|
||||
} while (0)
|
||||
|
||||
for (len = 1; len < BUFLEN; len++) {
|
||||
TEST("012346789", "012346789");
|
||||
TEST("a0123b", "a%sb", "0123");
|
||||
TEST("a01234567", "a%s%s", "0123", "4567");
|
||||
TEST("a0123 ", "a%-6s", "0123");
|
||||
TEST("a 0123", "a%6s", "0123");
|
||||
TEST("a 012", "a%6.3s", "0123");
|
||||
TEST("a 012", "a%*.*s", 6, 3, "0123");
|
||||
TEST("a 123b", "a% db", 123);
|
||||
TEST("a123b", "a%-db", 123);
|
||||
TEST("a-123b", "a%-db", -123);
|
||||
TEST("a+123b", "a%+db", 123);
|
||||
}
|
||||
#undef BUFLEN
|
||||
#undef TEST
|
||||
}
|
||||
TEST_END
|
||||
|
||||
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); \
|
||||
assert_str_eq(buf, expected_str, "Unexpected output"); \
|
||||
assert_d_eq(result, strlen(expected_str), "Unexpected result"); \
|
||||
} while (0)
|
||||
|
||||
TEST("hello", "hello");
|
||||
|
||||
TEST("50%, 100%", "50%%, %d%%", 100);
|
||||
|
||||
TEST("a0123b", "a%sb", "0123");
|
||||
|
||||
TEST("a 0123b", "a%5sb", "0123");
|
||||
TEST("a 0123b", "a%*sb", 5, "0123");
|
||||
|
||||
TEST("a0123 b", "a%-5sb", "0123");
|
||||
TEST("a0123b", "a%*sb", -1, "0123");
|
||||
TEST("a0123 b", "a%*sb", -5, "0123");
|
||||
TEST("a0123 b", "a%-*sb", -5, "0123");
|
||||
|
||||
TEST("a012b", "a%.3sb", "0123");
|
||||
TEST("a012b", "a%.*sb", 3, "0123");
|
||||
TEST("a0123b", "a%.*sb", -3, "0123");
|
||||
|
||||
TEST("a 012b", "a%5.3sb", "0123");
|
||||
TEST("a 012b", "a%5.*sb", 3, "0123");
|
||||
TEST("a 012b", "a%*.3sb", 5, "0123");
|
||||
TEST("a 012b", "a%*.*sb", 5, 3, "0123");
|
||||
TEST("a 0123b", "a%*.*sb", 5, -3, "0123");
|
||||
|
||||
TEST("_abcd_", "_%x_", 0xabcd);
|
||||
TEST("_0xabcd_", "_%#x_", 0xabcd);
|
||||
TEST("_1234_", "_%o_", 01234);
|
||||
TEST("_01234_", "_%#o_", 01234);
|
||||
TEST("_1234_", "_%u_", 1234);
|
||||
|
||||
TEST("_1234_", "_%d_", 1234);
|
||||
TEST("_ 1234_", "_% d_", 1234);
|
||||
TEST("_+1234_", "_%+d_", 1234);
|
||||
TEST("_-1234_", "_%d_", -1234);
|
||||
TEST("_-1234_", "_% d_", -1234);
|
||||
TEST("_-1234_", "_%+d_", -1234);
|
||||
|
||||
TEST("_-1234_", "_%d_", -1234);
|
||||
TEST("_1234_", "_%d_", 1234);
|
||||
TEST("_-1234_", "_%i_", -1234);
|
||||
TEST("_1234_", "_%i_", 1234);
|
||||
TEST("_01234_", "_%#o_", 01234);
|
||||
TEST("_1234_", "_%u_", 1234);
|
||||
TEST("_0x1234abc_", "_%#x_", 0x1234abc);
|
||||
TEST("_0X1234ABC_", "_%#X_", 0x1234abc);
|
||||
TEST("_c_", "_%c_", 'c');
|
||||
TEST("_string_", "_%s_", "string");
|
||||
TEST("_0x42_", "_%p_", ((void *)0x42));
|
||||
|
||||
TEST("_-1234_", "_%ld_", ((long)-1234));
|
||||
TEST("_1234_", "_%ld_", ((long)1234));
|
||||
TEST("_-1234_", "_%li_", ((long)-1234));
|
||||
TEST("_1234_", "_%li_", ((long)1234));
|
||||
TEST("_01234_", "_%#lo_", ((long)01234));
|
||||
TEST("_1234_", "_%lu_", ((long)1234));
|
||||
TEST("_0x1234abc_", "_%#lx_", ((long)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#lX_", ((long)0x1234ABC));
|
||||
|
||||
TEST("_-1234_", "_%lld_", ((long long)-1234));
|
||||
TEST("_1234_", "_%lld_", ((long long)1234));
|
||||
TEST("_-1234_", "_%lli_", ((long long)-1234));
|
||||
TEST("_1234_", "_%lli_", ((long long)1234));
|
||||
TEST("_01234_", "_%#llo_", ((long long)01234));
|
||||
TEST("_1234_", "_%llu_", ((long long)1234));
|
||||
TEST("_0x1234abc_", "_%#llx_", ((long long)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#llX_", ((long long)0x1234ABC));
|
||||
|
||||
TEST("_-1234_", "_%qd_", ((long long)-1234));
|
||||
TEST("_1234_", "_%qd_", ((long long)1234));
|
||||
TEST("_-1234_", "_%qi_", ((long long)-1234));
|
||||
TEST("_1234_", "_%qi_", ((long long)1234));
|
||||
TEST("_01234_", "_%#qo_", ((long long)01234));
|
||||
TEST("_1234_", "_%qu_", ((long long)1234));
|
||||
TEST("_0x1234abc_", "_%#qx_", ((long long)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#qX_", ((long long)0x1234ABC));
|
||||
|
||||
TEST("_-1234_", "_%jd_", ((intmax_t)-1234));
|
||||
TEST("_1234_", "_%jd_", ((intmax_t)1234));
|
||||
TEST("_-1234_", "_%ji_", ((intmax_t)-1234));
|
||||
TEST("_1234_", "_%ji_", ((intmax_t)1234));
|
||||
TEST("_01234_", "_%#jo_", ((intmax_t)01234));
|
||||
TEST("_1234_", "_%ju_", ((intmax_t)1234));
|
||||
TEST("_0x1234abc_", "_%#jx_", ((intmax_t)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#jX_", ((intmax_t)0x1234ABC));
|
||||
|
||||
TEST("_1234_", "_%td_", ((ptrdiff_t)1234));
|
||||
TEST("_-1234_", "_%td_", ((ptrdiff_t)-1234));
|
||||
TEST("_1234_", "_%ti_", ((ptrdiff_t)1234));
|
||||
TEST("_-1234_", "_%ti_", ((ptrdiff_t)-1234));
|
||||
|
||||
TEST("_-1234_", "_%zd_", ((ssize_t)-1234));
|
||||
TEST("_1234_", "_%zd_", ((ssize_t)1234));
|
||||
TEST("_-1234_", "_%zi_", ((ssize_t)-1234));
|
||||
TEST("_1234_", "_%zi_", ((ssize_t)1234));
|
||||
TEST("_01234_", "_%#zo_", ((ssize_t)01234));
|
||||
TEST("_1234_", "_%zu_", ((ssize_t)1234));
|
||||
TEST("_0x1234abc_", "_%#zx_", ((ssize_t)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#zX_", ((ssize_t)0x1234ABC));
|
||||
#undef BUFLEN
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_pow2_ceil,
|
||||
test_malloc_strtoumax_no_endptr,
|
||||
test_malloc_strtoumax,
|
||||
test_malloc_snprintf_truncated,
|
||||
test_malloc_snprintf));
|
||||
}
|
78
deps/jemalloc/test/unit/zero.c
vendored
Normal file
78
deps/jemalloc/test/unit/zero.c
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf =
|
||||
"abort:false,junk:false,zero:true,redzone:false,quarantine:0";
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_zero(size_t sz_min, size_t sz_max)
|
||||
{
|
||||
char *s;
|
||||
size_t sz_prev, sz, i;
|
||||
|
||||
sz_prev = 0;
|
||||
s = (char *)mallocx(sz_min, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
|
||||
for (sz = sallocx(s, 0); sz <= sz_max;
|
||||
sz_prev = sz, sz = sallocx(s, 0)) {
|
||||
if (sz_prev > 0) {
|
||||
assert_c_eq(s[0], 'a',
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
ZU(0), sz_prev);
|
||||
assert_c_eq(s[sz_prev-1], 'a',
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
sz_prev-1, sz_prev);
|
||||
}
|
||||
|
||||
for (i = sz_prev; i < sz; i++) {
|
||||
assert_c_eq(s[i], 0x0,
|
||||
"Newly allocated byte %zu/%zu isn't zero-filled",
|
||||
i, sz);
|
||||
s[i] = 'a';
|
||||
}
|
||||
|
||||
if (xallocx(s, sz+1, 0, 0) == sz) {
|
||||
s = (char *)rallocx(s, sz+1, 0);
|
||||
assert_ptr_not_null((void *)s,
|
||||
"Unexpected rallocx() failure");
|
||||
}
|
||||
}
|
||||
|
||||
dallocx(s, 0);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_zero_small)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_zero(1, SMALL_MAXCLASS-1);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_zero_large)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_zero(SMALL_MAXCLASS+1, arena_maxclass);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_zero_huge)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_zero(arena_maxclass+1, chunksize*2);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_zero_small,
|
||||
test_zero_large,
|
||||
test_zero_huge));
|
||||
}
|
Reference in New Issue
Block a user