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