universe@781: /* universe@781: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@781: * universe@781: * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved. universe@781: * universe@781: * Redistribution and use in source and binary forms, with or without universe@781: * modification, are permitted provided that the following conditions are met: universe@781: * universe@781: * 1. Redistributions of source code must retain the above copyright universe@781: * notice, this list of conditions and the following disclaimer. universe@781: * universe@781: * 2. Redistributions in binary form must reproduce the above copyright universe@781: * notice, this list of conditions and the following disclaimer in the universe@781: * documentation and/or other materials provided with the distribution. universe@781: * universe@781: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@781: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@781: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@781: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@781: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@781: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@781: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@781: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@781: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@781: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@781: * POSSIBILITY OF SUCH DAMAGE. universe@781: */ universe@781: universe@781: #include "cx/test.h" universe@781: #include "util_allocator.h" universe@781: universe@781: #include "cx/mempool.h" universe@781: universe@781: CX_TEST(test_mempool_create) { universe@781: CxMempool *pool = cxBasicMempoolCreate(16); universe@781: CX_TEST_DO { universe@781: CX_TEST_ASSERT(pool->auto_destr == NULL); universe@781: CX_TEST_ASSERT(pool->allocator != NULL); universe@781: CX_TEST_ASSERT(pool->allocator->cl != NULL); universe@781: CX_TEST_ASSERT(pool->allocator->data == pool); universe@781: CX_TEST_ASSERT(pool->allocator->cl->malloc != NULL); universe@781: CX_TEST_ASSERT(pool->allocator->cl->calloc != NULL); universe@781: CX_TEST_ASSERT(pool->allocator->cl->realloc != NULL); universe@781: CX_TEST_ASSERT(pool->allocator->cl->free != NULL); universe@781: CX_TEST_ASSERT(pool->capacity == 16); universe@781: CX_TEST_ASSERT(pool->size == 0); universe@781: CX_TEST_ASSERT(pool->data != NULL); universe@781: } universe@781: cxMempoolDestroy(pool); universe@781: } universe@781: universe@781: CX_TEST(test_mempool_malloc) { universe@781: CxMempool *pool = cxBasicMempoolCreate(4); universe@781: CX_TEST_DO { universe@781: CX_TEST_ASSERT(cxMalloc(pool->allocator, sizeof(int)) != NULL); universe@781: CX_TEST_ASSERT(cxMalloc(pool->allocator, sizeof(int)) != NULL); universe@781: CX_TEST_ASSERT(pool->size == 2); universe@781: CX_TEST_ASSERT(pool->capacity == 4); universe@781: CX_TEST_ASSERT(cxMalloc(pool->allocator, sizeof(int)) != NULL); universe@781: CX_TEST_ASSERT(cxMalloc(pool->allocator, sizeof(int)) != NULL); universe@781: CX_TEST_ASSERT(pool->size == 4); universe@781: CX_TEST_ASSERT(pool->capacity == 4); universe@781: CX_TEST_ASSERT(cxMalloc(pool->allocator, sizeof(int)) != NULL); universe@781: CX_TEST_ASSERT(cxMalloc(pool->allocator, sizeof(int)) != NULL); universe@781: CX_TEST_ASSERT(pool->size == 6); universe@781: CX_TEST_ASSERT(pool->capacity >= 6); universe@781: } universe@781: cxMempoolDestroy(pool); universe@781: } universe@781: universe@781: CX_TEST(test_mempool_calloc) { universe@781: CxMempool *pool = cxBasicMempoolCreate(4); universe@781: CX_TEST_DO { universe@781: int *test = cxCalloc(pool->allocator, 2, sizeof(int)); universe@781: CX_TEST_ASSERT(test != NULL); universe@781: CX_TEST_ASSERT(test[0] == 0); universe@781: CX_TEST_ASSERT(test[1] == 0); universe@781: } universe@781: cxMempoolDestroy(pool); universe@781: } universe@781: universe@781: static unsigned test_mempool_destructor_called; universe@781: universe@781: static void test_mempool_destructor(__attribute__((__unused__)) void *mem) { universe@781: test_mempool_destructor_called++; universe@781: } universe@781: universe@781: CX_TEST(test_mempool_realloc) { universe@781: CxMempool *pool = cxMempoolCreate(4, test_mempool_destructor); universe@781: CX_TEST_DO { universe@781: CX_TEST_ASSERT(pool->auto_destr == test_mempool_destructor); universe@781: int *data = cxMalloc(pool->allocator, sizeof(int)); universe@781: *data = 13; universe@781: universe@781: int *rdata = data; universe@781: unsigned n = 1; universe@781: while (rdata == data) { universe@781: n <<= 1; universe@781: // eventually the memory should be moved elsewhere universe@781: CX_TEST_ASSERTM(n < 65536, "Reallocation attempt failed - test not executable."); universe@781: rdata = cxRealloc(pool->allocator, data, n * sizeof(intptr_t)); universe@781: } universe@781: universe@781: CX_TEST_ASSERT(*rdata == 13); universe@781: // test if destructor is still intact universe@781: test_mempool_destructor_called = 0; universe@781: cxFree(pool->allocator, rdata); universe@781: CX_TEST_ASSERT(test_mempool_destructor_called == 1); universe@781: } universe@781: cxMempoolDestroy(pool); universe@781: } universe@781: universe@781: universe@781: CX_TEST(test_mempool_free) { universe@781: CxMempool *pool = cxBasicMempoolCreate(4); universe@781: void *mem1, *mem2; universe@781: CX_TEST_DO { universe@781: mem1 = cxMalloc(pool->allocator, 16); universe@781: cxFree(pool->allocator, mem1); universe@781: CX_TEST_ASSERT(pool->size == 0); universe@781: universe@781: cxMalloc(pool->allocator, 16); universe@781: cxMalloc(pool->allocator, 16); universe@781: mem1 = cxMalloc(pool->allocator, 16); universe@781: cxMalloc(pool->allocator, 16); universe@781: mem2 = cxMalloc(pool->allocator, 16); universe@781: universe@781: CX_TEST_ASSERT(pool->size == 5); universe@781: cxFree(pool->allocator, mem1); universe@781: CX_TEST_ASSERT(pool->size == 4); universe@781: cxFree(pool->allocator, mem2); universe@781: CX_TEST_ASSERT(pool->size == 3); universe@781: } universe@781: cxMempoolDestroy(pool); universe@781: } universe@781: universe@781: CX_TEST(test_mempool_destroy) { universe@781: CxMempool *pool = cxBasicMempoolCreate(4); universe@781: CX_TEST_DO { universe@781: int *data = cxMalloc(pool->allocator, sizeof(int)); universe@781: *data = 13; universe@781: cxMempoolSetDestructor(data, test_mempool_destructor); universe@781: CX_TEST_ASSERT(*data == 13); universe@781: test_mempool_destructor_called = 0; universe@781: cxFree(pool->allocator, data); universe@781: CX_TEST_ASSERT(test_mempool_destructor_called == 1); universe@781: data = cxMalloc(pool->allocator, sizeof(int)); universe@781: cxMempoolSetDestructor(data, test_mempool_destructor); universe@781: cxMempoolDestroy(pool); universe@781: CX_TEST_ASSERT(test_mempool_destructor_called == 2); universe@781: } universe@781: } universe@781: universe@781: CX_TEST(test_mempool_register) { universe@781: CxMempool *pool = cxBasicMempoolCreate(4); universe@781: CX_TEST_DO { universe@781: int *data = cxMalloc(pool->allocator, sizeof(int)); universe@781: test_mempool_destructor_called = 0; universe@781: cxMempoolSetDestructor(data, test_mempool_destructor); universe@781: int donotfree = 0; universe@781: cxMempoolRegister(pool, &donotfree, test_mempool_destructor); universe@781: cxMempoolDestroy(pool); universe@781: CX_TEST_ASSERT(test_mempool_destructor_called == 2); universe@781: } universe@781: } universe@781: universe@781: universe@781: CxTestSuite *cx_test_suite_mempool(void) { universe@781: CxTestSuite *suite = cx_test_suite_new("mempool"); universe@781: universe@781: cx_test_register(suite, test_mempool_create); universe@781: cx_test_register(suite, test_mempool_malloc); universe@781: cx_test_register(suite, test_mempool_calloc); universe@781: cx_test_register(suite, test_mempool_realloc); universe@781: cx_test_register(suite, test_mempool_free); universe@781: cx_test_register(suite, test_mempool_destroy); universe@781: cx_test_register(suite, test_mempool_register); universe@781: universe@781: return suite; universe@781: }