tests/util_allocator.cpp

Fri, 05 May 2023 19:07:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 05 May 2023 19:07:56 +0200
changeset 702
3390b58ad15a
parent 653
e081643aae2a
permissions
-rw-r--r--

fix cx_linked_list_sort() not working for empty lists

universe@422 1 /*
universe@422 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@422 3 *
universe@422 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@422 5 *
universe@422 6 * Redistribution and use in source and binary forms, with or without
universe@422 7 * modification, are permitted provided that the following conditions are met:
universe@422 8 *
universe@422 9 * 1. Redistributions of source code must retain the above copyright
universe@422 10 * notice, this list of conditions and the following disclaimer.
universe@422 11 *
universe@422 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@422 13 * notice, this list of conditions and the following disclaimer in the
universe@422 14 * documentation and/or other materials provided with the distribution.
universe@422 15 *
universe@422 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@422 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@422 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@422 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@422 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@422 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@422 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@422 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@422 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@422 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@422 26 * POSSIBILITY OF SUCH DAMAGE.
universe@422 27 */
universe@422 28
universe@422 29 #include "util_allocator.h"
universe@422 30
universe@422 31 void *cx_malloc_testing(void *d, size_t n) {
universe@518 32 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 33 void *ptr = malloc(n);
universe@422 34 data->alloc_total++;
universe@518 35 if (ptr == nullptr) {
universe@422 36 data->alloc_failed++;
universe@422 37 } else {
universe@518 38 data->tracked.insert(ptr);
universe@422 39 }
universe@422 40 return ptr;
universe@422 41 }
universe@422 42
universe@422 43 void *cx_realloc_testing(void *d, void *mem, size_t n) {
universe@518 44 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 45 void *ptr = realloc(mem, n);
universe@422 46 if (ptr == mem) {
universe@422 47 return ptr;
universe@422 48 } else {
universe@422 49 data->alloc_total++;
universe@518 50 if (ptr == nullptr) {
universe@422 51 data->alloc_failed++;
universe@422 52 } else {
universe@422 53 data->free_total++;
universe@518 54 if (data->tracked.erase(mem) == 0) {
universe@422 55 data->free_failed++;
universe@422 56 }
universe@518 57 data->tracked.insert(ptr);
universe@422 58 }
universe@422 59 return ptr;
universe@422 60 }
universe@422 61 }
universe@422 62
universe@422 63 void *cx_calloc_testing(void *d, size_t nelem, size_t n) {
universe@518 64 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 65 void *ptr = calloc(nelem, n);
universe@422 66 data->alloc_total++;
universe@518 67 if (ptr == nullptr) {
universe@422 68 data->alloc_failed++;
universe@422 69 } else {
universe@518 70 data->tracked.insert(ptr);
universe@422 71 }
universe@422 72 return ptr;
universe@422 73 }
universe@422 74
universe@422 75 void cx_free_testing(void *d, void *mem) {
universe@518 76 auto data = reinterpret_cast<CxTestingAllocator *>(d);
universe@422 77 data->free_total++;
universe@518 78 if (data->tracked.erase(mem) == 0) {
universe@422 79 data->free_failed++;
universe@422 80 // do not even attempt to free mem, because it is likely to segfault
universe@422 81 } else {
universe@422 82 free(mem);
universe@422 83 }
universe@422 84 }
universe@422 85
universe@422 86 cx_allocator_class cx_testing_allocator_class = {
universe@422 87 cx_malloc_testing,
universe@422 88 cx_realloc_testing,
universe@422 89 cx_calloc_testing,
universe@422 90 cx_free_testing
universe@422 91 };
universe@422 92
universe@518 93 CxTestingAllocator::CxTestingAllocator() : CxAllocator() {
universe@518 94 cl = &cx_testing_allocator_class;
universe@518 95 data = this;
universe@422 96 }
universe@422 97
universe@571 98 bool CxTestingAllocator::used() const {
universe@571 99 return alloc_total > 0;
universe@571 100 }
universe@571 101
universe@518 102 bool CxTestingAllocator::verify() const {
universe@518 103 return tracked.empty() && alloc_failed == 0 && free_failed == 0 && alloc_total == free_total;
universe@422 104 }
universe@518 105
universe@518 106 // SELF-TEST
universe@518 107
universe@518 108 #include <gtest/gtest.h>
universe@518 109
universe@518 110 TEST(TestingAllocator, ExpectFree) {
universe@518 111 CxTestingAllocator allocator;
universe@518 112
universe@518 113 ASSERT_TRUE(allocator.verify());
universe@642 114 EXPECT_FALSE(allocator.used());
universe@518 115 auto ptr = cxMalloc(&allocator, 16);
universe@642 116 EXPECT_TRUE(allocator.used());
universe@518 117 ASSERT_NE(ptr, nullptr);
universe@518 118 EXPECT_FALSE(allocator.verify());
universe@518 119
universe@518 120 cxFree(&allocator, ptr);
universe@518 121 EXPECT_TRUE(allocator.verify());
universe@518 122 }
universe@518 123
universe@518 124 TEST(TestingAllocator, DetectDoubleFree) {
universe@518 125 CxTestingAllocator allocator;
universe@518 126
universe@518 127 ASSERT_TRUE(allocator.verify());
universe@518 128 auto ptr = cxMalloc(&allocator, 16);
universe@518 129 ASSERT_NE(ptr, nullptr);
universe@518 130
universe@518 131 cxFree(&allocator, ptr);
universe@518 132 EXPECT_TRUE(allocator.verify());
universe@518 133 ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
universe@518 134 EXPECT_FALSE(allocator.verify());
universe@518 135 }
universe@518 136
universe@518 137 TEST(TestingAllocator, FreeUntracked) {
universe@518 138 CxTestingAllocator allocator;
universe@518 139
universe@518 140 auto ptr = malloc(16);
universe@518 141 ASSERT_TRUE(allocator.verify());
universe@518 142 ASSERT_NO_FATAL_FAILURE(cxFree(&allocator, ptr));
universe@518 143 EXPECT_FALSE(allocator.verify());
universe@518 144 ASSERT_NO_FATAL_FAILURE(free(ptr));
universe@518 145 }
universe@518 146
universe@518 147 TEST(TestingAllocator, FullLifecycleWithRealloc) {
universe@518 148 CxTestingAllocator allocator;
universe@518 149 ASSERT_TRUE(allocator.verify());
universe@518 150 auto ptr = cxMalloc(&allocator, 16);
universe@518 151 ASSERT_NE(ptr, nullptr);
universe@518 152 EXPECT_EQ(allocator.tracked.size(), 1);
universe@518 153 ptr = cxRealloc(&allocator, ptr, 256);
universe@518 154 ASSERT_NE(ptr, nullptr);
universe@518 155 EXPECT_EQ(allocator.tracked.size(), 1);
universe@518 156 cxFree(&allocator, ptr);
universe@518 157 EXPECT_TRUE(allocator.verify());
universe@518 158 }
universe@518 159
universe@518 160 TEST(TestingAllocator, CallocInitializes) {
universe@518 161 CxTestingAllocator allocator;
universe@642 162 const char zeros[16] = {0};
universe@518 163 auto ptr = cxCalloc(&allocator, 16, 1);
universe@518 164 EXPECT_EQ(memcmp(ptr, zeros, 16), 0);
universe@518 165 cxFree(&allocator, ptr);
universe@518 166 EXPECT_TRUE(allocator.verify());
universe@518 167 }

mercurial