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@571: #include "cx/basic_mempool.h" universe@571: #include "util_allocator.h" universe@571: #include universe@571: universe@571: class CxBasicMempool : public ::testing::Test { universe@571: protected: universe@571: CxMempool *pool = nullptr; universe@571: universe@571: void TearDown() override { universe@571: if (pool != nullptr) { universe@571: cxMempoolDestroy(pool); universe@571: } universe@571: } universe@571: }; universe@571: universe@571: TEST_F(CxBasicMempool, Create) { universe@572: pool = cxBasicMempoolCreate(16); universe@571: ASSERT_NE(pool->allocator, nullptr); universe@571: ASSERT_NE(pool->cl, nullptr); universe@571: EXPECT_NE(pool->cl->destroy, 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@571: universe@571: auto basic_pool = reinterpret_cast(pool); universe@571: EXPECT_EQ(basic_pool->size, 16); universe@571: EXPECT_EQ(basic_pool->ndata, 0); universe@571: EXPECT_NE(basic_pool->data, nullptr); universe@571: } universe@571: universe@571: TEST_F(CxBasicMempool, malloc) { universe@572: pool = cxBasicMempoolCreate(4); universe@571: auto basic_pool = reinterpret_cast(pool); universe@571: EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); universe@571: EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); universe@571: EXPECT_EQ(basic_pool->ndata, 2); universe@571: EXPECT_EQ(basic_pool->size, 4); universe@571: EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); universe@571: EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); universe@571: EXPECT_EQ(basic_pool->ndata, 4); universe@571: EXPECT_EQ(basic_pool->size, 4); universe@571: EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); universe@571: EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); universe@571: EXPECT_EQ(basic_pool->ndata, 6); universe@571: EXPECT_GE(basic_pool->size, 6); universe@571: } universe@571: universe@571: TEST_F(CxBasicMempool, calloc) { universe@572: 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@571: } universe@571: universe@571: static unsigned test_destructor_called = 0; universe@571: universe@571: static void test_destructor([[maybe_unused]] void *mem) { universe@571: test_destructor_called++; universe@571: } universe@571: universe@571: TEST_F(CxBasicMempool, destructor) { universe@572: pool = cxBasicMempoolCreate(4); universe@571: auto data = cxMalloc(pool->allocator, sizeof(int)); universe@571: *((int *) data) = 13; universe@571: cxMempoolSetDestructor(pool, data, test_destructor); universe@571: EXPECT_EQ(*((int *) data), 13); universe@571: test_destructor_called = 0; universe@571: cxFree(pool->allocator, data); universe@571: EXPECT_EQ(test_destructor_called, 1); universe@571: data = cxMalloc(pool->allocator, sizeof(int)); universe@571: cxMempoolSetDestructor(pool, data, test_destructor); universe@571: cxMempoolDestroy(pool); universe@571: pool = nullptr; universe@571: EXPECT_EQ(test_destructor_called, 2); universe@571: } universe@571: universe@571: TEST_F(CxBasicMempool, realloc) { universe@572: pool = cxBasicMempoolCreate(4); universe@571: auto data = cxMalloc(pool->allocator, sizeof(int)); universe@571: *((int *) data) = 13; universe@571: cxMempoolSetDestructor(pool, data, test_destructor); 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@571: } universe@571: universe@571: universe@571: TEST_F(CxBasicMempool, free) { universe@572: pool = cxBasicMempoolCreate(4); universe@571: auto basic_pool = reinterpret_cast(pool); 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@571: EXPECT_EQ(basic_pool->ndata, 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@571: EXPECT_EQ(basic_pool->ndata, 5); universe@571: cxFree(pool->allocator, mem1); universe@571: EXPECT_EQ(basic_pool->ndata, 4); universe@571: cxFree(pool->allocator, mem2); universe@571: EXPECT_EQ(basic_pool->ndata, 3); universe@571: }