Mon, 08 Aug 2022 17:12:00 +0200
#201 - remove dangerous allocator config
There is no plausible use case, except using the testing
allocator in the test case, and having the possibility to
specify any allocator (including another mempool) causes
more harm than good.
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 */
29 #include "cx/basic_mempool.h"
30 #include "util_allocator.h"
31 #include <gtest/gtest.h>
33 class CxBasicMempool : public ::testing::Test {
34 protected:
35 CxMempool *pool = nullptr;
37 void TearDown() override {
38 if (pool != nullptr) {
39 cxMempoolDestroy(pool);
40 }
41 }
42 };
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);
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 }
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 }
79 TEST_F(CxBasicMempool, calloc) {
80 pool = cxBasicMempoolCreate(4);
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 }
88 static unsigned test_destructor_called = 0;
90 static void test_destructor([[maybe_unused]] void *mem) {
91 test_destructor_called++;
92 }
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 }
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);
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 }
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 }
132 TEST_F(CxBasicMempool, free) {
133 pool = cxBasicMempoolCreate(4);
134 auto basic_pool = reinterpret_cast<cx_basic_mempool_s *>(pool);
136 void *mem1;
137 void *mem2;
139 mem1 = cxMalloc(pool->allocator, 16);
140 cxFree(pool->allocator, mem1);
141 EXPECT_EQ(basic_pool->ndata, 0);
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);
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 }