GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 76 / 5 / 81
Functions: 100.0% 16 / 0 / 16
Branches: 80.0% 24 / 0 / 30

allocator.c
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 2 → 3 taken 1 time.
✓ Branch 2 → 7 taken 43 times.
44 if (ps == 0) {
51 1 long sc = sysconf(_SC_PAGESIZE);
52
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
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 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 1 time.
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 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
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 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 1 time.
✗ Branch 3 → 4 not taken.
✓ Branch 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 6 → 7 taken 1 time.
✓ Branch 6 → 8 taken 1 time.
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 8 → 9 not taken.
✓ Branch 8 → 10 taken 1 time.
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 22714 void *cxZalloc(
160 const CxAllocator *allocator,
161 size_t n
162 ) {
163 22714 void *mem = allocator->cl->malloc(allocator->data, n);
164
1/2
✓ Branch 3 → 4 taken 22714 times.
✗ Branch 3 → 5 not taken.
22714 if (mem != NULL) {
165 22714 memset(mem, 0, n);
166 }
167 22714 return mem;
168 }
169
170 615 void *cxRealloc(
171 const CxAllocator *allocator,
172 void *mem,
173 size_t n
174 ) {
175 615 return allocator->cl->realloc(allocator->data, mem, n);
176 }
177
178 653 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 3 → 4 taken 4 times.
✓ Branch 3 → 5 taken 649 times.
653 if (cx_szmul(nmemb, size, &n)) {
186 4 errno = EOVERFLOW;
187 4 return NULL;
188 } else {
189 649 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 2 → 3 taken 2 times.
✓ Branch 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 6 → 7 taken 1 time.
✓ Branch 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 651 int cxReallocateArray_(
213 const CxAllocator *allocator,
214 void **mem,
215 size_t nmemb,
216 size_t size
217 ) {
218
3/4
✓ Branch 2 → 3 taken 649 times.
✓ Branch 2 → 4 taken 2 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 649 times.
651 if (nmemb == 0 || size == 0) {
219 2 cxFree(allocator, *mem);
220 2 *mem = NULL;
221 2 return 0;
222 }
223 649 void *nmem = cxReallocArray(allocator, *mem, nmemb, size);
224
2/2
✓ Branch 7 → 8 taken 2 times.
✓ Branch 7 → 9 taken 647 times.
649 if (nmem == NULL) {
225 − return 1; // LCOV_EXCL_LINE
226 } else {
227 647 *mem = nmem;
228 647 return 0;
229 }
230 }
231
232 1943 void *cxCalloc(
233 const CxAllocator *allocator,
234 size_t nmemb,
235 size_t size
236 ) {
237 1943 return allocator->cl->calloc(allocator->data, nmemb, size);
238 }
239
240 49910 void cxFree(
241 const CxAllocator *allocator,
242 void *mem
243 ) {
244 49910 allocator->cl->free(allocator->data, mem);
245 49910 }
246
247 1541 void cxFreeDefault(void *mem) {
248 1541 cxDefaultAllocator->cl->free(cxDefaultAllocator->data, mem);
249 1541 }
250