Refactor to support more varied testing.

Refactor the test harness to support three types of tests:
- unit: White box unit tests.  These tests have full access to all
  internal jemalloc library symbols.  Though in actuality all symbols
  are prefixed by jet_, macro-based name mangling abstracts this away
  from test code.
- integration: Black box integration tests.  These tests link with
  the installable shared jemalloc library, and with the exception of
  some utility code and configure-generated macro definitions, they have
  no access to jemalloc internals.
- stress: Black box stress tests.  These tests link with the installable
  shared jemalloc library, as well as with an internal allocator with
  symbols prefixed by jet_ (same as for unit tests) that can be used to
  allocate data structures that are internal to the test code.

Move existing tests into test/{unit,integration}/ as appropriate.

Split out internal parts of jemalloc_defs.h.in and put them in
jemalloc_internal_defs.h.in.  This reduces internals exposure to
applications that #include <jemalloc/jemalloc.h>.

Refactor jemalloc.h header generation so that a single header file
results, and the prototypes can be used to generate jet_ prototypes for
tests.  Split jemalloc.h.in into multiple parts (jemalloc_defs.h.in,
jemalloc_macros.h.in, jemalloc_protos.h.in, jemalloc_mangle.h.in) and
use a shell script to generate a unified jemalloc.h at configure time.

Change the default private namespace prefix from "" to "je_".

Add missing private namespace mangling.

Remove hard-coded private_namespace.h.  Instead generate it and
private_unnamespace.h from private_symbols.txt.  Use similar logic for
public symbols, which aids in name mangling for jet_ symbols.

Add test_warn() and test_fail().  Replace existing exit(1) calls with
test_fail() calls.
This commit is contained in:
Jason Evans 2013-11-30 15:25:42 -08:00
parent 6668853596
commit 86abd0dcd8
48 changed files with 1335 additions and 938 deletions

View file

@ -0,0 +1,67 @@
#include "test/jemalloc_test.h"
#define NTHREADS 10
void *
je_thread_start(void *arg)
{
unsigned thread_ind = (unsigned)(uintptr_t)arg;
unsigned arena_ind;
int r;
void *p;
size_t rsz, sz;
sz = sizeof(arena_ind);
if (mallctl("arenas.extend", &arena_ind, &sz, NULL, 0)
!= 0) {
malloc_printf("Error in arenas.extend\n");
abort();
}
if (thread_ind % 4 != 3) {
size_t mib[3];
size_t miblen = sizeof(mib) / sizeof(size_t);
const char *dss_precs[] = {"disabled", "primary", "secondary"};
const char *dss = dss_precs[thread_ind %
(sizeof(dss_precs)/sizeof(char*))];
if (mallctlnametomib("arena.0.dss", mib, &miblen) != 0) {
malloc_printf("Error in mallctlnametomib()\n");
abort();
}
mib[1] = arena_ind;
if (mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss,
sizeof(const char *))) {
malloc_printf("Error in mallctlbymib()\n");
abort();
}
}
r = allocm(&p, &rsz, 1, ALLOCM_ARENA(arena_ind));
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected allocm() error\n");
abort();
}
dallocm(p, 0);
return (NULL);
}
int
main(void)
{
je_thread_t threads[NTHREADS];
unsigned i;
malloc_printf("Test begin\n");
for (i = 0; i < NTHREADS; i++) {
je_thread_create(&threads[i], je_thread_start,
(void *)(uintptr_t)i);
}
for (i = 0; i < NTHREADS; i++)
je_thread_join(threads[i], NULL);
malloc_printf("Test end\n");
return (0);
}

View file

@ -0,0 +1,2 @@
Test begin
Test end

View file

@ -0,0 +1,117 @@
#include "test/jemalloc_test.h"
#define CHUNK 0x400000
/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */
#define MAXALIGN ((size_t)0x2000000LU)
#define NITER 4
int
main(void)
{
size_t alignment, size, total;
unsigned i;
void *p, *ps[NITER];
malloc_printf("Test begin\n");
/* Test error conditions. */
alignment = 0;
set_errno(0);
p = aligned_alloc(alignment, 1);
if (p != NULL || get_errno() != EINVAL) {
malloc_printf(
"Expected error for invalid alignment %zu\n", alignment);
}
for (alignment = sizeof(size_t); alignment < MAXALIGN;
alignment <<= 1) {
set_errno(0);
p = aligned_alloc(alignment + 1, 1);
if (p != NULL || get_errno() != EINVAL) {
malloc_printf(
"Expected error for invalid alignment %zu\n",
alignment + 1);
}
}
#if LG_SIZEOF_PTR == 3
alignment = UINT64_C(0x8000000000000000);
size = UINT64_C(0x8000000000000000);
#else
alignment = 0x80000000LU;
size = 0x80000000LU;
#endif
set_errno(0);
p = aligned_alloc(alignment, size);
if (p != NULL || get_errno() != ENOMEM) {
malloc_printf(
"Expected error for aligned_alloc(%zu, %zu)\n",
alignment, size);
}
#if LG_SIZEOF_PTR == 3
alignment = UINT64_C(0x4000000000000000);
size = UINT64_C(0x8400000000000001);
#else
alignment = 0x40000000LU;
size = 0x84000001LU;
#endif
set_errno(0);
p = aligned_alloc(alignment, size);
if (p != NULL || get_errno() != ENOMEM) {
malloc_printf(
"Expected error for aligned_alloc(%zu, %zu)\n",
alignment, size);
}
alignment = 0x10LU;
#if LG_SIZEOF_PTR == 3
size = UINT64_C(0xfffffffffffffff0);
#else
size = 0xfffffff0LU;
#endif
set_errno(0);
p = aligned_alloc(alignment, size);
if (p != NULL || get_errno() != ENOMEM) {
malloc_printf(
"Expected error for aligned_alloc(&p, %zu, %zu)\n",
alignment, size);
}
for (i = 0; i < NITER; i++)
ps[i] = NULL;
for (alignment = 8;
alignment <= MAXALIGN;
alignment <<= 1) {
total = 0;
malloc_printf("Alignment: %zu\n", alignment);
for (size = 1;
size < 3 * alignment && size < (1U << 31);
size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
for (i = 0; i < NITER; i++) {
ps[i] = aligned_alloc(alignment, size);
if (ps[i] == NULL) {
char buf[BUFERROR_BUF];
buferror(buf, sizeof(buf));
test_fail(
"Error for size %zu (%#zx): %s\n",
size, size, buf);
}
total += malloc_usable_size(ps[i]);
if (total >= (MAXALIGN << 1))
break;
}
for (i = 0; i < NITER; i++) {
if (ps[i] != NULL) {
free(ps[i]);
ps[i] = NULL;
}
}
}
}
malloc_printf("Test end\n");
return (0);
}

View file

@ -0,0 +1,25 @@
Test begin
Alignment: 8
Alignment: 16
Alignment: 32
Alignment: 64
Alignment: 128
Alignment: 256
Alignment: 512
Alignment: 1024
Alignment: 2048
Alignment: 4096
Alignment: 8192
Alignment: 16384
Alignment: 32768
Alignment: 65536
Alignment: 131072
Alignment: 262144
Alignment: 524288
Alignment: 1048576
Alignment: 2097152
Alignment: 4194304
Alignment: 8388608
Alignment: 16777216
Alignment: 33554432
Test end

View file

@ -0,0 +1,111 @@
#include "test/jemalloc_test.h"
void *
je_thread_start(void *arg)
{
int err;
void *p;
uint64_t a0, a1, d0, d1;
uint64_t *ap0, *ap1, *dp0, *dp1;
size_t sz, usize;
sz = sizeof(a0);
if ((err = mallctl("thread.allocated", &a0, &sz, NULL, 0))) {
if (err == ENOENT) {
#ifdef JEMALLOC_STATS
assert(false);
#endif
goto label_return;
}
test_fail("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
}
sz = sizeof(ap0);
if ((err = mallctl("thread.allocatedp", &ap0, &sz, NULL, 0))) {
if (err == ENOENT) {
#ifdef JEMALLOC_STATS
assert(false);
#endif
goto label_return;
}
test_fail("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
}
assert(*ap0 == a0);
sz = sizeof(d0);
if ((err = mallctl("thread.deallocated", &d0, &sz, NULL, 0))) {
if (err == ENOENT) {
#ifdef JEMALLOC_STATS
assert(false);
#endif
goto label_return;
}
test_fail("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
}
sz = sizeof(dp0);
if ((err = mallctl("thread.deallocatedp", &dp0, &sz, NULL, 0))) {
if (err == ENOENT) {
#ifdef JEMALLOC_STATS
assert(false);
#endif
goto label_return;
}
test_fail("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
}
assert(*dp0 == d0);
p = malloc(1);
if (p == NULL)
test_fail("%s(): Error in malloc()\n", __func__);
sz = sizeof(a1);
mallctl("thread.allocated", &a1, &sz, NULL, 0);
sz = sizeof(ap1);
mallctl("thread.allocatedp", &ap1, &sz, NULL, 0);
assert(*ap1 == a1);
assert(ap0 == ap1);
usize = malloc_usable_size(p);
assert(a0 + usize <= a1);
free(p);
sz = sizeof(d1);
mallctl("thread.deallocated", &d1, &sz, NULL, 0);
sz = sizeof(dp1);
mallctl("thread.deallocatedp", &dp1, &sz, NULL, 0);
assert(*dp1 == d1);
assert(dp0 == dp1);
assert(d0 + usize <= d1);
label_return:
return (NULL);
}
int
main(void)
{
int ret = 0;
je_thread_t thread;
malloc_printf("Test begin\n");
je_thread_start(NULL);
je_thread_create(&thread, je_thread_start, NULL);
je_thread_join(thread, NULL);
je_thread_start(NULL);
je_thread_create(&thread, je_thread_start, NULL);
je_thread_join(thread, NULL);
je_thread_start(NULL);
malloc_printf("Test end\n");
return (ret);
}

View file

@ -0,0 +1,2 @@
Test begin
Test end

191
test/integration/allocm.c Normal file
View file

@ -0,0 +1,191 @@
#include "test/jemalloc_test.h"
#define CHUNK 0x400000
/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */
#define MAXALIGN ((size_t)0x2000000LU)
#define NITER 4
int
main(void)
{
int r;
void *p;
size_t nsz, rsz, sz, alignment, total;
unsigned i;
void *ps[NITER];
malloc_printf("Test begin\n");
sz = 42;
nsz = 0;
r = nallocm(&nsz, sz, 0);
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected nallocm() error\n");
abort();
}
rsz = 0;
r = allocm(&p, &rsz, sz, 0);
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected allocm() error\n");
abort();
}
if (rsz < sz)
malloc_printf("Real size smaller than expected\n");
if (nsz != rsz)
malloc_printf("nallocm()/allocm() rsize mismatch\n");
if (dallocm(p, 0) != ALLOCM_SUCCESS)
malloc_printf("Unexpected dallocm() error\n");
r = allocm(&p, NULL, sz, 0);
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected allocm() error\n");
abort();
}
if (dallocm(p, 0) != ALLOCM_SUCCESS)
malloc_printf("Unexpected dallocm() error\n");
nsz = 0;
r = nallocm(&nsz, sz, ALLOCM_ZERO);
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected nallocm() error\n");
abort();
}
rsz = 0;
r = allocm(&p, &rsz, sz, ALLOCM_ZERO);
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected allocm() error\n");
abort();
}
if (nsz != rsz)
malloc_printf("nallocm()/allocm() rsize mismatch\n");
if (dallocm(p, 0) != ALLOCM_SUCCESS)
malloc_printf("Unexpected dallocm() error\n");
#if LG_SIZEOF_PTR == 3
alignment = UINT64_C(0x8000000000000000);
sz = UINT64_C(0x8000000000000000);
#else
alignment = 0x80000000LU;
sz = 0x80000000LU;
#endif
nsz = 0;
r = nallocm(&nsz, sz, ALLOCM_ALIGN(alignment));
if (r == ALLOCM_SUCCESS) {
malloc_printf(
"Expected error for nallocm(&nsz, %zu, %#x)\n",
sz, ALLOCM_ALIGN(alignment));
}
rsz = 0;
r = allocm(&p, &rsz, sz, ALLOCM_ALIGN(alignment));
if (r == ALLOCM_SUCCESS) {
malloc_printf(
"Expected error for allocm(&p, %zu, %#x)\n",
sz, ALLOCM_ALIGN(alignment));
}
if (nsz != rsz)
malloc_printf("nallocm()/allocm() rsize mismatch\n");
#if LG_SIZEOF_PTR == 3
alignment = UINT64_C(0x4000000000000000);
sz = UINT64_C(0x8400000000000001);
#else
alignment = 0x40000000LU;
sz = 0x84000001LU;
#endif
nsz = 0;
r = nallocm(&nsz, sz, ALLOCM_ALIGN(alignment));
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected nallocm() error\n");
rsz = 0;
r = allocm(&p, &rsz, sz, ALLOCM_ALIGN(alignment));
if (r == ALLOCM_SUCCESS) {
malloc_printf(
"Expected error for allocm(&p, %zu, %#x)\n",
sz, ALLOCM_ALIGN(alignment));
}
alignment = 0x10LU;
#if LG_SIZEOF_PTR == 3
sz = UINT64_C(0xfffffffffffffff0);
#else
sz = 0xfffffff0LU;
#endif
nsz = 0;
r = nallocm(&nsz, sz, ALLOCM_ALIGN(alignment));
if (r == ALLOCM_SUCCESS) {
malloc_printf(
"Expected error for nallocm(&nsz, %zu, %#x)\n",
sz, ALLOCM_ALIGN(alignment));
}
rsz = 0;
r = allocm(&p, &rsz, sz, ALLOCM_ALIGN(alignment));
if (r == ALLOCM_SUCCESS) {
malloc_printf(
"Expected error for allocm(&p, %zu, %#x)\n",
sz, ALLOCM_ALIGN(alignment));
}
if (nsz != rsz)
malloc_printf("nallocm()/allocm() rsize mismatch\n");
for (i = 0; i < NITER; i++)
ps[i] = NULL;
for (alignment = 8;
alignment <= MAXALIGN;
alignment <<= 1) {
total = 0;
malloc_printf("Alignment: %zu\n", alignment);
for (sz = 1;
sz < 3 * alignment && sz < (1U << 31);
sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
for (i = 0; i < NITER; i++) {
nsz = 0;
r = nallocm(&nsz, sz,
ALLOCM_ALIGN(alignment) | ALLOCM_ZERO);
if (r != ALLOCM_SUCCESS) {
test_fail(
"nallocm() error for size %zu"
" (%#zx): %d\n",
sz, sz, r);
}
rsz = 0;
r = allocm(&ps[i], &rsz, sz,
ALLOCM_ALIGN(alignment) | ALLOCM_ZERO);
if (r != ALLOCM_SUCCESS) {
test_fail(
"allocm() error for size %zu"
" (%#zx): %d\n",
sz, sz, r);
}
if (rsz < sz) {
malloc_printf(
"Real size smaller than"
" expected\n");
}
if (nsz != rsz) {
malloc_printf(
"nallocm()/allocm() rsize"
" mismatch\n");
}
if ((uintptr_t)p & (alignment-1)) {
malloc_printf(
"%p inadequately aligned for"
" alignment: %zu\n", p, alignment);
}
sallocm(ps[i], &rsz, 0);
total += rsz;
if (total >= (MAXALIGN << 1))
break;
}
for (i = 0; i < NITER; i++) {
if (ps[i] != NULL) {
dallocm(ps[i], 0);
ps[i] = NULL;
}
}
}
}
malloc_printf("Test end\n");
return (0);
}

View file

@ -0,0 +1,25 @@
Test begin
Alignment: 8
Alignment: 16
Alignment: 32
Alignment: 64
Alignment: 128
Alignment: 256
Alignment: 512
Alignment: 1024
Alignment: 2048
Alignment: 4096
Alignment: 8192
Alignment: 16384
Alignment: 32768
Alignment: 65536
Alignment: 131072
Alignment: 262144
Alignment: 524288
Alignment: 1048576
Alignment: 2097152
Alignment: 4194304
Alignment: 8388608
Alignment: 16777216
Alignment: 33554432
Test end

View file

@ -0,0 +1,50 @@
/*
* This header should be included by tests, rather than directly including
* jemalloc/jemalloc.h, because --with-install-suffix may cause the header to
* have a different name.
*/
#include "jemalloc/jemalloc@install_suffix@.h"
#include "jemalloc/internal/jemalloc_internal.h"
/* Abstraction layer for threading in tests. */
#ifdef _WIN32
#include <windows.h>
typedef HANDLE je_thread_t;
void
je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg)
{
LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc;
*thread = CreateThread(NULL, 0, routine, arg, 0, NULL);
if (*thread == NULL)
test_fail("Error in CreateThread()\n");
}
void
je_thread_join(je_thread_t thread, void **ret)
{
WaitForSingleObject(thread, INFINITE);
}
#else
#include <pthread.h>
typedef pthread_t je_thread_t;
void
je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg)
{
if (pthread_create(thread, NULL, proc, arg) != 0)
test_fail("Error in pthread_create()\n");
}
void
je_thread_join(je_thread_t thread, void **ret)
{
pthread_join(thread, ret);
}
#endif

59
test/integration/mremap.c Normal file
View file

@ -0,0 +1,59 @@
#include "test/jemalloc_test.h"
int
main(void)
{
int ret, err;
size_t sz, lg_chunk, chunksize, i;
char *p, *q;
malloc_printf("Test begin\n");
sz = sizeof(lg_chunk);
if ((err = mallctl("opt.lg_chunk", &lg_chunk, &sz, NULL, 0))) {
assert(err != ENOENT);
malloc_printf("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
ret = 1;
goto label_return;
}
chunksize = ((size_t)1U) << lg_chunk;
p = (char *)malloc(chunksize);
if (p == NULL) {
malloc_printf("malloc(%zu) --> %p\n", chunksize, p);
ret = 1;
goto label_return;
}
memset(p, 'a', chunksize);
q = (char *)realloc(p, chunksize * 2);
if (q == NULL) {
malloc_printf("realloc(%p, %zu) --> %p\n", p, chunksize * 2,
q);
ret = 1;
goto label_return;
}
for (i = 0; i < chunksize; i++) {
assert(q[i] == 'a');
}
p = q;
q = (char *)realloc(p, chunksize);
if (q == NULL) {
malloc_printf("realloc(%p, %zu) --> %p\n", p, chunksize, q);
ret = 1;
goto label_return;
}
for (i = 0; i < chunksize; i++) {
assert(q[i] == 'a');
}
free(q);
ret = 0;
label_return:
malloc_printf("Test end\n");
return (ret);
}

View file

@ -0,0 +1,2 @@
Test begin
Test end

View file

@ -0,0 +1,113 @@
#include "test/jemalloc_test.h"
#define CHUNK 0x400000
/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */
#define MAXALIGN ((size_t)0x2000000LU)
#define NITER 4
int
main(void)
{
size_t alignment, size, total;
unsigned i;
int err;
void *p, *ps[NITER];
malloc_printf("Test begin\n");
/* Test error conditions. */
for (alignment = 0; alignment < sizeof(void *); alignment++) {
err = posix_memalign(&p, alignment, 1);
if (err != EINVAL) {
malloc_printf(
"Expected error for invalid alignment %zu\n",
alignment);
}
}
for (alignment = sizeof(size_t); alignment < MAXALIGN;
alignment <<= 1) {
err = posix_memalign(&p, alignment + 1, 1);
if (err == 0) {
malloc_printf(
"Expected error for invalid alignment %zu\n",
alignment + 1);
}
}
#if LG_SIZEOF_PTR == 3
alignment = UINT64_C(0x8000000000000000);
size = UINT64_C(0x8000000000000000);
#else
alignment = 0x80000000LU;
size = 0x80000000LU;
#endif
err = posix_memalign(&p, alignment, size);
if (err == 0) {
malloc_printf(
"Expected error for posix_memalign(&p, %zu, %zu)\n",
alignment, size);
}
#if LG_SIZEOF_PTR == 3
alignment = UINT64_C(0x4000000000000000);
size = UINT64_C(0x8400000000000001);
#else
alignment = 0x40000000LU;
size = 0x84000001LU;
#endif
err = posix_memalign(&p, alignment, size);
if (err == 0) {
malloc_printf(
"Expected error for posix_memalign(&p, %zu, %zu)\n",
alignment, size);
}
alignment = 0x10LU;
#if LG_SIZEOF_PTR == 3
size = UINT64_C(0xfffffffffffffff0);
#else
size = 0xfffffff0LU;
#endif
err = posix_memalign(&p, alignment, size);
if (err == 0) {
malloc_printf(
"Expected error for posix_memalign(&p, %zu, %zu)\n",
alignment, size);
}
for (i = 0; i < NITER; i++)
ps[i] = NULL;
for (alignment = 8;
alignment <= MAXALIGN;
alignment <<= 1) {
total = 0;
malloc_printf("Alignment: %zu\n", alignment);
for (size = 1;
size < 3 * alignment && size < (1U << 31);
size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
for (i = 0; i < NITER; i++) {
err = posix_memalign(&ps[i],
alignment, size);
if (err) {
test_fail(
"Error for size %zu (%#zx): %s\n",
size, size, strerror(err));
}
total += malloc_usable_size(ps[i]);
if (total >= (MAXALIGN << 1))
break;
}
for (i = 0; i < NITER; i++) {
if (ps[i] != NULL) {
free(ps[i]);
ps[i] = NULL;
}
}
}
}
malloc_printf("Test end\n");
return (0);
}

View file

@ -0,0 +1,25 @@
Test begin
Alignment: 8
Alignment: 16
Alignment: 32
Alignment: 64
Alignment: 128
Alignment: 256
Alignment: 512
Alignment: 1024
Alignment: 2048
Alignment: 4096
Alignment: 8192
Alignment: 16384
Alignment: 32768
Alignment: 65536
Alignment: 131072
Alignment: 262144
Alignment: 524288
Alignment: 1048576
Alignment: 2097152
Alignment: 4194304
Alignment: 8388608
Alignment: 16777216
Alignment: 33554432
Test end

128
test/integration/rallocm.c Normal file
View file

@ -0,0 +1,128 @@
#include <unistd.h>
#include "test/jemalloc_test.h"
int
main(void)
{
size_t pagesize;
void *p, *q;
size_t sz, tsz;
int r;
malloc_printf("Test begin\n");
/* Get page size. */
{
#ifdef _WIN32
SYSTEM_INFO si;
GetSystemInfo(&si);
pagesize = (size_t)si.dwPageSize;
#else
long result = sysconf(_SC_PAGESIZE);
assert(result != -1);
pagesize = (size_t)result;
#endif
}
r = allocm(&p, &sz, 42, 0);
if (r != ALLOCM_SUCCESS) {
malloc_printf("Unexpected allocm() error\n");
abort();
}
q = p;
r = rallocm(&q, &tsz, sz, 0, ALLOCM_NO_MOVE);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (q != p)
malloc_printf("Unexpected object move\n");
if (tsz != sz) {
malloc_printf("Unexpected size change: %zu --> %zu\n",
sz, tsz);
}
q = p;
r = rallocm(&q, &tsz, sz, 5, ALLOCM_NO_MOVE);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (q != p)
malloc_printf("Unexpected object move\n");
if (tsz != sz) {
malloc_printf("Unexpected size change: %zu --> %zu\n",
sz, tsz);
}
q = p;
r = rallocm(&q, &tsz, sz + 5, 0, ALLOCM_NO_MOVE);
if (r != ALLOCM_ERR_NOT_MOVED)
malloc_printf("Unexpected rallocm() result\n");
if (q != p)
malloc_printf("Unexpected object move\n");
if (tsz != sz) {
malloc_printf("Unexpected size change: %zu --> %zu\n",
sz, tsz);
}
q = p;
r = rallocm(&q, &tsz, sz + 5, 0, 0);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (q == p)
malloc_printf("Expected object move\n");
if (tsz == sz) {
malloc_printf("Expected size change: %zu --> %zu\n",
sz, tsz);
}
p = q;
sz = tsz;
r = rallocm(&q, &tsz, pagesize*2, 0, 0);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (q == p)
malloc_printf("Expected object move\n");
if (tsz == sz) {
malloc_printf("Expected size change: %zu --> %zu\n",
sz, tsz);
}
p = q;
sz = tsz;
r = rallocm(&q, &tsz, pagesize*4, 0, 0);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (tsz == sz) {
malloc_printf("Expected size change: %zu --> %zu\n",
sz, tsz);
}
p = q;
sz = tsz;
r = rallocm(&q, &tsz, pagesize*2, 0, ALLOCM_NO_MOVE);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (q != p)
malloc_printf("Unexpected object move\n");
if (tsz == sz) {
malloc_printf("Expected size change: %zu --> %zu\n",
sz, tsz);
}
sz = tsz;
r = rallocm(&q, &tsz, pagesize*4, 0, ALLOCM_NO_MOVE);
if (r != ALLOCM_SUCCESS)
malloc_printf("Unexpected rallocm() error\n");
if (q != p)
malloc_printf("Unexpected object move\n");
if (tsz == sz) {
malloc_printf("Expected size change: %zu --> %zu\n",
sz, tsz);
}
sz = tsz;
dallocm(p, 0);
malloc_printf("Test end\n");
return (0);
}

View file

@ -0,0 +1,2 @@
Test begin
Test end

View file

@ -0,0 +1,84 @@
#include "test/jemalloc_test.h"
#define NTHREADS 10
void *
je_thread_start(void *arg)
{
unsigned main_arena_ind = *(unsigned *)arg;
void *p;
unsigned arena_ind;
size_t size;
int err;
p = malloc(1);
if (p == NULL) {
malloc_printf("%s(): Error in malloc()\n", __func__);
return (void *)1;
}
free(p);
size = sizeof(arena_ind);
if ((err = mallctl("thread.arena", &arena_ind, &size, &main_arena_ind,
sizeof(main_arena_ind)))) {
malloc_printf("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
return (void *)1;
}
size = sizeof(arena_ind);
if ((err = mallctl("thread.arena", &arena_ind, &size, NULL,
0))) {
malloc_printf("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
return (void *)1;
}
assert(arena_ind == main_arena_ind);
return (NULL);
}
int
main(void)
{
int ret = 0;
void *p;
unsigned arena_ind;
size_t size;
int err;
je_thread_t threads[NTHREADS];
unsigned i;
malloc_printf("Test begin\n");
p = malloc(1);
if (p == NULL) {
malloc_printf("%s(): Error in malloc()\n", __func__);
ret = 1;
goto label_return;
}
size = sizeof(arena_ind);
if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) {
malloc_printf("%s(): Error in mallctl(): %s\n", __func__,
strerror(err));
ret = 1;
goto label_return;
}
for (i = 0; i < NTHREADS; i++) {
je_thread_create(&threads[i], je_thread_start,
(void *)&arena_ind);
}
for (i = 0; i < NTHREADS; i++) {
intptr_t join_ret;
je_thread_join(threads[i], (void *)&join_ret);
if (join_ret != 0)
ret = 1;
}
label_return:
malloc_printf("Test end\n");
return (ret);
}

View file

@ -0,0 +1,2 @@
Test begin
Test end

View file

@ -0,0 +1,90 @@
#include "test/jemalloc_test.h"
void *
je_thread_start(void *arg)
{
int err;
size_t sz;
bool e0, e1;
sz = sizeof(bool);
if ((err = mallctl("thread.tcache.enabled", &e0, &sz, NULL, 0))) {
if (err == ENOENT) {
#ifdef JEMALLOC_TCACHE
assert(false);
#endif
}
goto label_return;
}
if (e0) {
e1 = false;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz)
== 0);
assert(e0);
}
e1 = true;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0 == false);
e1 = true;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0);
e1 = false;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0);
e1 = false;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0 == false);
free(malloc(1));
e1 = true;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0 == false);
free(malloc(1));
e1 = true;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0);
free(malloc(1));
e1 = false;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0);
free(malloc(1));
e1 = false;
assert(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz) == 0);
assert(e0 == false);
free(malloc(1));
label_return:
return (NULL);
}
int
main(void)
{
int ret = 0;
je_thread_t thread;
malloc_printf("Test begin\n");
je_thread_start(NULL);
je_thread_create(&thread, je_thread_start, NULL);
je_thread_join(thread, NULL);
je_thread_start(NULL);
je_thread_create(&thread, je_thread_start, NULL);
je_thread_join(thread, NULL);
je_thread_start(NULL);
malloc_printf("Test end\n");
return (ret);
}

View file

@ -0,0 +1,2 @@
Test begin
Test end