#include "unittest.h"
#define TEST_STRING_VALUE "Some test text, to check memory"
#define TEST_REPEAT_CREATE_POOLS (20)
static int custom_allocs;
static int custom_alloc_calls;
static int expect_malloc;
static void *
malloc_null(size_t size)
{
++custom_alloc_calls;
#ifdef _WIN32
if (custom_alloc_calls < 4) {
custom_allocs++;
return malloc(size);
}
#endif
return NULL;
}
static void *
malloc_custom(size_t size)
{
++custom_alloc_calls;
++custom_allocs;
return malloc(size);
}
static void
free_custom(void *ptr)
{
++custom_alloc_calls;
--custom_allocs;
free(ptr);
}
static void *
realloc_custom(void *ptr, size_t size)
{
++custom_alloc_calls;
return realloc(ptr, size);
}
static char *
strdup_custom(const char *s)
{
++custom_alloc_calls;
++custom_allocs;
return strdup(s);
}
static void
pool_test(const char *dir)
{
VMEM *vmp = NULL;
if (dir != NULL) {
vmp = vmem_create(dir, VMEM_MIN_POOL);
} else {
void *mem_pool = MMAP_ANON_ALIGNED(VMEM_MIN_POOL, 4 << 20);
vmp = vmem_create_in_region(mem_pool, VMEM_MIN_POOL);
}
if (vmp == NULL) {
if (dir == NULL) {
UT_FATAL("!vmem_create_in_region");
} else {
UT_FATAL("!vmem_create");
}
}
char *test = vmem_malloc(vmp, strlen(TEST_STRING_VALUE) + 1);
if (expect_malloc == 0) {
UT_ASSERTeq(test, NULL);
} else {
strcpy(test, TEST_STRING_VALUE);
UT_ASSERTeq(strcmp(test, TEST_STRING_VALUE), 0);
UT_ASSERT(vmem_malloc_usable_size(vmp, test) > 0);
vmem_free(vmp, test);
}
vmem_delete(vmp);
}
int
main(int argc, char *argv[])
{
int expect_custom_alloc = 0;
START(argc, argv, "vmem_custom_alloc");
if (argc < 2 || argc > 3 || strlen(argv[1]) != 1)
UT_FATAL("usage: %s (0-2) [directory]", argv[0]);
switch (argv[1][0]) {
case '0': {
expect_custom_alloc = 0;
expect_malloc = 1;
break;
}
case '1': {
expect_custom_alloc = 1;
expect_malloc = 0;
vmem_set_funcs(malloc_null, free_custom,
realloc_custom, strdup_custom, NULL);
break;
}
case '2': {
expect_custom_alloc = 1;
expect_malloc = 1;
vmem_set_funcs(malloc_custom, free_custom,
realloc_custom, strdup_custom, NULL);
break;
}
default: {
UT_FATAL("usage: %s (0-2) [directory]", argv[0]);
break;
}
}
if (argc == 3) {
pool_test(argv[2]);
} else {
int i;
for (i = 0; i < TEST_REPEAT_CREATE_POOLS; ++i)
pool_test(NULL);
}
UT_ASSERTeq(custom_allocs, 0);
if (expect_custom_alloc == 0) {
UT_ASSERTeq(custom_alloc_calls, 0);
} else {
UT_ASSERTne(custom_alloc_calls, 0);
}
DONE(NULL);
}