UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "cx/basic_mempool.h" 30 #include "util_allocator.h" 31 #include <gtest/gtest.h> 32 33 class CxBasicMempool : public ::testing::Test { 34 protected: 35 CxMempool *pool = nullptr; 36 37 void TearDown() override { 38 if (pool != nullptr) { 39 cxMempoolDestroy(pool); 40 } 41 } 42 }; 43 44 TEST_F(CxBasicMempool, Create) { 45 pool = cxBasicMempoolCreate(16); 46 ASSERT_NE(pool->allocator, nullptr); 47 ASSERT_NE(pool->cl, nullptr); 48 EXPECT_NE(pool->cl->destroy, nullptr); 49 ASSERT_NE(pool->allocator->cl, nullptr); 50 EXPECT_EQ(pool->allocator->data, pool); 51 EXPECT_NE(pool->allocator->cl->malloc, nullptr); 52 EXPECT_NE(pool->allocator->cl->calloc, nullptr); 53 EXPECT_NE(pool->allocator->cl->realloc, nullptr); 54 EXPECT_NE(pool->allocator->cl->free, nullptr); 55 56 auto basic_pool = reinterpret_cast<cx_basic_mempool_s *>(pool); 57 EXPECT_EQ(basic_pool->size, 16); 58 EXPECT_EQ(basic_pool->ndata, 0); 59 EXPECT_NE(basic_pool->data, nullptr); 60 } 61 62 TEST_F(CxBasicMempool, malloc) { 63 pool = cxBasicMempoolCreate(4); 64 auto basic_pool = reinterpret_cast<cx_basic_mempool_s *>(pool); 65 EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); 66 EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); 67 EXPECT_EQ(basic_pool->ndata, 2); 68 EXPECT_EQ(basic_pool->size, 4); 69 EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); 70 EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); 71 EXPECT_EQ(basic_pool->ndata, 4); 72 EXPECT_EQ(basic_pool->size, 4); 73 EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); 74 EXPECT_NE(cxMalloc(pool->allocator, sizeof(int)), nullptr); 75 EXPECT_EQ(basic_pool->ndata, 6); 76 EXPECT_GE(basic_pool->size, 6); 77 } 78 79 TEST_F(CxBasicMempool, calloc) { 80 pool = cxBasicMempoolCreate(4); 81 82 auto test = (int *) cxCalloc(pool->allocator, 2, sizeof(int)); 83 ASSERT_NE(test, nullptr); 84 EXPECT_EQ(test[0], 0); 85 EXPECT_EQ(test[1], 0); 86 } 87 88 static unsigned test_destructor_called = 0; 89 90 static void test_destructor([[maybe_unused]] void *mem) { 91 test_destructor_called++; 92 } 93 94 TEST_F(CxBasicMempool, destructor) { 95 pool = cxBasicMempoolCreate(4); 96 auto data = cxMalloc(pool->allocator, sizeof(int)); 97 *((int *) data) = 13; 98 cxMempoolSetDestructor(pool, data, test_destructor); 99 EXPECT_EQ(*((int *) data), 13); 100 test_destructor_called = 0; 101 cxFree(pool->allocator, data); 102 EXPECT_EQ(test_destructor_called, 1); 103 data = cxMalloc(pool->allocator, sizeof(int)); 104 cxMempoolSetDestructor(pool, data, test_destructor); 105 cxMempoolDestroy(pool); 106 pool = nullptr; 107 EXPECT_EQ(test_destructor_called, 2); 108 } 109 110 TEST_F(CxBasicMempool, realloc) { 111 pool = cxBasicMempoolCreate(4); 112 auto data = cxMalloc(pool->allocator, sizeof(int)); 113 *((int *) data) = 13; 114 cxMempoolSetDestructor(pool, data, test_destructor); 115 116 void *rdata = data; 117 unsigned n = 1; 118 while (rdata == data) { 119 n <<= 1; 120 ASSERT_LT(n, 65536); // eventually the memory should be moved elsewhere 121 rdata = cxRealloc(pool->allocator, data, n * sizeof(intptr_t)); 122 } 123 124 EXPECT_EQ(*((int *) rdata), 13); 125 // test if destructor is still intact 126 test_destructor_called = 0; 127 cxFree(pool->allocator, rdata); 128 EXPECT_EQ(test_destructor_called, 1); 129 } 130 131 132 TEST_F(CxBasicMempool, free) { 133 pool = cxBasicMempoolCreate(4); 134 auto basic_pool = reinterpret_cast<cx_basic_mempool_s *>(pool); 135 136 void *mem1; 137 void *mem2; 138 139 mem1 = cxMalloc(pool->allocator, 16); 140 cxFree(pool->allocator, mem1); 141 EXPECT_EQ(basic_pool->ndata, 0); 142 143 cxMalloc(pool->allocator, 16); 144 cxMalloc(pool->allocator, 16); 145 mem1 = cxMalloc(pool->allocator, 16); 146 cxMalloc(pool->allocator, 16); 147 mem2 = cxMalloc(pool->allocator, 16); 148 149 EXPECT_EQ(basic_pool->ndata, 5); 150 cxFree(pool->allocator, mem1); 151 EXPECT_EQ(basic_pool->ndata, 4); 152 cxFree(pool->allocator, mem2); 153 EXPECT_EQ(basic_pool->ndata, 3); 154 }