GCC Code Coverage Report


Directory: ./
File: allocator.c
Date: 2025-12-31 16:19:05
Exec Total Coverage
Lines: 76 76 100.0%
Functions: 16 16 100.0%
Branches: 24 30 80.0%

Line Branch Exec Source
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/allocator.h"
30
31 #include <errno.h>
32 #include <string.h>
33
34 #ifdef _WIN32
35 #include <Windows.h>
36 #include <sysinfoapi.h>
37 unsigned long cx_system_page_size(void) {
38 static unsigned long ps = 0;
39 if (ps == 0) {
40 SYSTEM_INFO sysinfo;
41 GetSystemInfo(&sysinfo);
42 ps = (unsigned long) sysinfo.dwPageSize;
43 }
44 return ps;
45 }
46 #else
47 #include <unistd.h>
48 44 unsigned long cx_system_page_size(void) {
49 static unsigned long ps = 0;
50
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→7) taken 43 times.
44 if (ps == 0) {
51 1 long sc = sysconf(_SC_PAGESIZE);
52
1/2
✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 1 times.
1 if (sc < 0) {
53 // fallback for systems which do not report a value here
54 ps = 4096; // LCOV_EXCL_LINE
55 } else {
56 1 ps = (unsigned long) sc;
57 }
58 }
59 44 return ps;
60 }
61 #endif
62
63 3 static void *cx_malloc_stdlib(
64 CX_UNUSED void *d,
65 size_t n
66 ) {
67 3 return malloc(n);
68 }
69
70 2 static void *cx_realloc_stdlib(
71 CX_UNUSED void *d,
72 void *mem,
73 size_t n
74 ) {
75 2 return realloc(mem, n);
76 }
77
78 4 static void *cx_calloc_stdlib(
79 CX_UNUSED void *d,
80 size_t nmemb,
81 size_t size
82 ) {
83 4 return calloc(nmemb, size);
84 }
85
86 7 static void cx_free_stdlib(
87 CX_UNUSED void *d,
88 void *mem
89 ) {
90 7 free(mem);
91 7 }
92
93 static cx_allocator_class cx_stdlib_allocator_class = {
94 cx_malloc_stdlib,
95 cx_realloc_stdlib,
96 cx_calloc_stdlib,
97 cx_free_stdlib
98 };
99
100 struct cx_allocator_s cx_stdlib_allocator = {
101 &cx_stdlib_allocator_class,
102 NULL
103 };
104 const CxAllocator * const cxStdlibAllocator = &cx_stdlib_allocator;
105 const CxAllocator * cxDefaultAllocator = &cx_stdlib_allocator;
106
107 2 int cx_reallocate_(
108 void **mem,
109 size_t n
110 ) {
111
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→4) taken 1 times.
2 if (n == 0) {
112 1 free(*mem);
113 1 *mem = NULL;
114 1 return 0;
115 }
116 1 void *nmem = realloc(*mem, n);
117
1/2
✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 1 times.
1 if (nmem == NULL) {
118 return 1; // LCOV_EXCL_LINE
119 } else {
120 1 *mem = nmem;
121 1 return 0;
122 }
123 }
124
125 3 int cx_reallocatearray_(
126 void **mem,
127 size_t nmemb,
128 size_t size
129 ) {
130
3/4
✓ Branch 0 (2→3) taken 2 times.
✓ Branch 1 (2→4) taken 1 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 2 times.
3 if (nmemb == 0 || size == 0) {
131 1 free(*mem);
132 1 *mem = NULL;
133 1 return 0;
134 }
135 size_t n;
136
2/2
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 1 (6→8) taken 1 times.
2 if (cx_szmul(nmemb, size, &n)) {
137 1 errno = EOVERFLOW;
138 1 return 1;
139 } else {
140 1 void *nmem = realloc(*mem, n);
141
1/2
✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→10) taken 1 times.
1 if (nmem == NULL) {
142 return 1; // LCOV_EXCL_LINE
143 } else {
144 1 *mem = nmem;
145 1 return 0;
146 }
147 }
148 }
149
150 // IMPLEMENTATION OF HIGH LEVEL API
151
152 26339 void *cxMalloc(
153 const CxAllocator *allocator,
154 size_t n
155 ) {
156 26339 return allocator->cl->malloc(allocator->data, n);
157 }
158
159 22713 void *cxZalloc(
160 const CxAllocator *allocator,
161 size_t n
162 ) {
163 22713 void *mem = allocator->cl->malloc(allocator->data, n);
164
1/2
✓ Branch 0 (3→4) taken 22713 times.
✗ Branch 1 (3→5) not taken.
22713 if (mem != NULL) {
165 22713 memset(mem, 0, n);
166 }
167 22713 return mem;
168 }
169
170 605 void *cxRealloc(
171 const CxAllocator *allocator,
172 void *mem,
173 size_t n
174 ) {
175 605 return allocator->cl->realloc(allocator->data, mem, n);
176 }
177
178 660 void *cxReallocArray(
179 const CxAllocator *allocator,
180 void *mem,
181 size_t nmemb,
182 size_t size
183 ) {
184 size_t n;
185
2/2
✓ Branch 0 (3→4) taken 4 times.
✓ Branch 1 (3→5) taken 656 times.
660 if (cx_szmul(nmemb, size, &n)) {
186 4 errno = EOVERFLOW;
187 4 return NULL;
188 } else {
189 656 return allocator->cl->realloc(allocator->data, mem, n);
190 }
191 }
192
193 139 int cxReallocate_(
194 const CxAllocator *allocator,
195 void **mem,
196 size_t n
197 ) {
198
2/2
✓ Branch 0 (2→3) taken 2 times.
✓ Branch 1 (2→5) taken 137 times.
139 if (n == 0) {
199 2 cxFree(allocator, *mem);
200 2 *mem = NULL;
201 2 return 0;
202 }
203 137 void *nmem = allocator->cl->realloc(allocator->data, *mem, n);
204
2/2
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 1 (6→8) taken 136 times.
137 if (nmem == NULL) {
205 return 1; // LCOV_EXCL_LINE
206 } else {
207 136 *mem = nmem;
208 136 return 0;
209 }
210 }
211
212 657 int cxReallocateArray_(
213 const CxAllocator *allocator,
214 void **mem,
215 size_t nmemb,
216 size_t size
217 ) {
218
3/4
✓ Branch 0 (2→3) taken 656 times.
✓ Branch 1 (2→4) taken 1 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→6) taken 656 times.
657 if (nmemb == 0 || size == 0) {
219 1 cxFree(allocator, *mem);
220 1 *mem = NULL;
221 1 return 0;
222 }
223 656 void *nmem = cxReallocArray(allocator, *mem, nmemb, size);
224
2/2
✓ Branch 0 (7→8) taken 2 times.
✓ Branch 1 (7→9) taken 654 times.
656 if (nmem == NULL) {
225 return 1; // LCOV_EXCL_LINE
226 } else {
227 654 *mem = nmem;
228 654 return 0;
229 }
230 }
231
232 1940 void *cxCalloc(
233 const CxAllocator *allocator,
234 size_t nmemb,
235 size_t size
236 ) {
237 1940 return allocator->cl->calloc(allocator->data, nmemb, size);
238 }
239
240 49905 void cxFree(
241 const CxAllocator *allocator,
242 void *mem
243 ) {
244 49905 allocator->cl->free(allocator->data, mem);
245 49905 }
246
247 1541 void cxFreeDefault(void *mem) {
248 1541 cxDefaultAllocator->cl->free(cxDefaultAllocator->data, mem);
249 1541 }
250