GCC Code Coverage Report


Directory: src/gate/
File: src/gate/memalloc.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 102 120 85.0%
Functions: 17 17 100.0%
Branches: 33 54 61.1%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | 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 notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/memalloc.h"
30 #include "gate/gatetypes.h"
31 #include "gate/debugging.h"
32 #include "gate/results.h"
33
34 #if defined(GATE_SYS_EFI)
35 # define GATE_MEMALLOC_ALLOC_STD_IMPL
36 # define GATE_MEMALLOC_ACCESS_INTERNAL_IMPL
37 #else
38 # define GATE_MEMALLOC_ALLOC_STD_IMPL
39 # define GATE_MEMALLOC_ACCESS_STD_IMPL
40 #endif
41
42
43 #if defined(GATE_MEMALLOC_ALLOC_STD_IMPL)
44
45 /* memory allocation C standard implementation */
46
47 #include <stdlib.h>
48 #include <string.h>
49
50 201889 void* gate_mem_alloc(gate_size_t sz)
51 {
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 201889 times.
201889 GATE_DEBUG_ASSERT(sz != 0);
53 201889 return malloc(sz);
54 }
55 3518 void* gate_mem_realloc(void* ptr, gate_size_t newsize)
56 {
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3518 times.
3518 GATE_DEBUG_ASSERT(newsize != 0);
58 3518 return realloc(ptr, newsize);
59 }
60 202737 void gate_mem_dealloc(void* ptr)
61 {
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202737 times.
202737 GATE_DEBUG_ASSERT(ptr != NULL);
63 202737 free(ptr);
64 202737 }
65
66 #endif /* GATE_MEMALLOC_ALLOC_STD_IMPL */
67
68
69
70
71
72 #if defined(GATE_MEMALLOC_ACCESS_STD_IMPL)
73
74 /* memory access C standard implementation */
75
76 #include <stdlib.h>
77 #include <string.h>
78
79 1432408 void* gate_mem_copy(void* dst, void const* src, gate_size_t sz)
80 {
81
3/6
✓ Branch 0 taken 1432408 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1432408 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1432408 times.
✗ Branch 5 not taken.
1432408 GATE_DEBUG_ASSERT((dst != NULL) && (src != NULL) && (sz != 0));
82 1432408 return memcpy(dst, src, sz);
83 }
84
85 259 void* gate_mem_move(void* dst, void const* src, gate_size_t sz)
86 {
87
3/6
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 GATE_DEBUG_ASSERT((dst != NULL) && (src != NULL) && (sz != 0));
88 259 return memmove(dst, src, sz);
89 }
90
91 1895918 void gate_mem_clear(void* dst, gate_size_t sz)
92 {
93 1895918 memset(dst, 0, sz);
94 1895918 }
95
96 32 void gate_mem_fill(void* dst, char chr, gate_size_t count)
97 {
98 32 memset(dst, (unsigned char)chr, count);
99 32 }
100
101 6114 int gate_mem_compare(void const* ptr1, void const* ptr2, gate_size_t sz)
102 {
103 6114 return (int)memcmp(ptr1, ptr2, sz);
104 }
105
106 #endif /* GATE_MEMALLOC_MOVE_STD_IMPL */
107
108
109 #if defined(GATE_MEMALLOC_ACCESS_INTERNAL_IMPL)
110
111 /* internal direct byte access implementation */
112
113 void* gate_mem_copy(void* dst, void const* src, gate_size_t sz)
114 {
115 char* ptr_dst = (char*)dst;
116 char const* ptr_src = (char const*)src;
117 GATE_DEBUG_ASSERT((dst != NULL) && (src != NULL) && (sz != 0));
118
119 while (sz-- != 0)
120 {
121 *ptr_dst = *ptr_src;
122 ++ptr_dst;
123 ++ptr_src;
124 }
125 return dst;
126 }
127
128 void* gate_mem_move(void* dst, void const* src, gate_size_t sz)
129 {
130 char* ptr_dst = (char*)dst;
131 char const* ptr_src = (char const*)src;
132 GATE_DEBUG_ASSERT((dst != NULL) && (src != NULL) && (sz != 0));
133
134 if ((ptr_dst <= ptr_src) || (ptr_src + sz < ptr_dst))
135 {
136 return gate_mem_copy(dst, src, sz);
137 }
138 else
139 {
140 ptr_dst += sz;
141 ptr_src += sz;
142 while (sz-- != 0)
143 {
144 --ptr_dst;
145 --ptr_src;
146 *ptr_dst = *ptr_src;
147 }
148 return dst;
149 }
150 }
151
152 void gate_mem_clear(void* dst, gate_size_t count)
153 {
154 gate_mem_fill(dst, 0, count);
155 }
156
157 void gate_mem_fill(void* dst, char chr, gate_size_t count)
158 {
159 char* ptr = (char*)dst;
160 while (count-- != 0)
161 {
162 *ptr = chr;
163 ++ptr;
164 }
165 }
166
167
168 int gate_mem_compare(void const* ptr1, void const* ptr2, gate_size_t sz)
169 {
170 unsigned char const* p1 = (unsigned char const*)ptr1;
171 unsigned char const* p2 = (unsigned char const*)ptr2;
172 while (sz-- != 0)
173 {
174 if (*p1 < *p2)
175 {
176 return -1;
177 }
178 if (*p1 > *p2)
179 {
180 return 1;
181 }
182 ++p1;
183 ++p2;
184 }
185 return 0;
186 }
187
188 #endif /* GATE_MEMALLOC_ACCESS_INTERNAL_IMPL */
189
190
191
192
193
194
195 /***************************
196 * Generic implementations *
197 ***************************/
198
199 130162 gate_size_t gate_mem_align_size(gate_size_t sz)
200 {
201 130162 gate_size_t m = sz % sizeof(gate_c_maxalign_t);
202
2/2
✓ Branch 0 taken 128738 times.
✓ Branch 1 taken 1424 times.
130162 if (m != 0)
203 {
204 128738 sz += (sizeof(gate_c_maxalign_t) - m);
205 }
206 130162 return sz;
207 }
208 3 void gate_mem_reversebyteorder(void* ptr, gate_size_t sz)
209 {
210 3 gate_size_t cnt = sz / 2;
211 3 char* ptr1 = (char*)ptr;
212 3 char* ptr2 = ptr1 + sz - 1;
213
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 while (cnt-- != 0)
214 {
215 8 char tmp = *ptr1;
216 8 *ptr1 = *ptr2;
217 8 *ptr2 = tmp;
218 8 ++ptr1;
219 8 --ptr2;
220 }
221 3 }
222 3 void* gate_mem_copy_reverse(void* dst, void const* src, gate_size_t sz)
223 {
224 3 char* ptrdst = (char*)dst;
225 3 char const* ptrsrc = (char const*)src + sz;
226
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 3 times.
19 while (sz-- != 0)
227 {
228 16 --ptrsrc;
229 16 *ptrdst = *ptrsrc;
230 16 ++ptrdst;
231 }
232 3 return dst;
233 }
234
235 4971 gate_result_t gate_mem_copy_construct(void* dest_item, void const* src_item, gate_size_t item_size, gate_mem_copyctor_t ctor)
236 {
237
2/2
✓ Branch 0 taken 359 times.
✓ Branch 1 taken 4612 times.
4971 if (ctor == NULL)
238 {
239 359 gate_mem_copy(dest_item, src_item, item_size);
240 359 return GATE_RESULT_OK;
241 }
242 else
243 {
244 4612 return ctor(dest_item, src_item);
245 }
246 }
247
248 3040 void gate_mem_destruct(void* dest_item, gate_mem_dtor_t dtor)
249 {
250
2/2
✓ Branch 0 taken 2821 times.
✓ Branch 1 taken 219 times.
3040 if (dtor != NULL)
251 {
252 2821 dtor(dest_item);
253 }
254 3040 }
255 67 gate_result_t gate_mem_move_construct(void* dest_item, void* src_item, gate_size_t item_size, gate_mem_copyctor_t ctor, gate_mem_dtor_t dtor)
256 {
257 gate_result_t result;
258
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 7 times.
67 if (dest_item == src_item)
259 {
260 60 return GATE_RESULT_OK;
261 }
262 7 result = gate_mem_copy_construct(dest_item, src_item, item_size, ctor);
263
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (GATE_SUCCEEDED(result))
264 {
265 7 gate_mem_destruct(src_item, dtor);
266 }
267 7 return result;
268 }
269
270
271 61 gate_bool_t gate_mem_swap(void* item1, void* item2, gate_size_t item_size, gate_mem_copyctor_t copy_constructor, gate_mem_dtor_t destructor)
272 {
273 gate_result_t result;
274 61 gate_bool_t ret = false;
275 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
276 61 char* ptr_buffer = &buffer[0];
277
278 do
279 {
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (item1 == item2)
281 {
282 /* pointers are equal -> nothing to swap */
283 ret = true;
284 break;
285 }
286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (item_size > sizeof(buffer))
287 {
288 ptr_buffer = gate_mem_alloc(item_size);
289 if (ptr_buffer == NULL)
290 {
291 ptr_buffer = &buffer[0];
292 break;
293 }
294 }
295
296 61 result = gate_mem_copy_construct(ptr_buffer, item1, item_size, copy_constructor);
297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 GATE_BREAK_IF_FAILED(result);
298
299 61 gate_mem_destruct(item1, destructor);
300 61 result = gate_mem_copy_construct(item1, item2, item_size, copy_constructor);
301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (GATE_FAILED(result))
302 {
303 gate_mem_copy_construct(item1, ptr_buffer, item_size, copy_constructor);
304 gate_mem_destruct(ptr_buffer, destructor);
305 break;
306 }
307
308 61 gate_mem_destruct(item2, destructor);
309 61 result = gate_mem_copy_construct(item2, ptr_buffer, item_size, copy_constructor);
310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (GATE_FAILED(result))
311 {
312 gate_mem_copy_construct(item2, item1, item_size, copy_constructor);
313 gate_mem_destruct(item1, destructor);
314 gate_mem_copy_construct(item1, ptr_buffer, item_size, copy_constructor);
315 gate_mem_destruct(ptr_buffer, destructor);
316 break;
317 }
318
319 61 gate_mem_destruct(ptr_buffer, destructor);
320 61 ret = true;
321 } while (0);
322
323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (ptr_buffer != &buffer[0])
324 {
325 gate_mem_dealloc(ptr_buffer);
326 }
327 61 return ret;
328 }
329
330 2 static gate_bool_t is_pointer_aligned(void const* ptr)
331 {
332 2 const gate_uintptr_t addr = (gate_uintptr_t)ptr;
333 2 return (addr % sizeof(void*) == 0);
334 }
335
336 1 void gate_mem_swap_bytes(void* mem1, void* mem2, gate_size_t length)
337 {
338 1 gate_size_t bytelen = length % sizeof(void*);
339 gate_uint8_t* b1;
340 gate_uint8_t* b2;
341
342
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 if (is_pointer_aligned(mem1) && is_pointer_aligned(mem2))
343 {
344 /* faster transfer using aligned pointer-swap */
345 1 void** v1 = (void**)mem1;
346 1 void** v2 = (void**)mem2;
347 1 gate_size_t reglen = length / sizeof(void*);
348 1 const gate_size_t skiplen = reglen * sizeof(void*);
349
350
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (; reglen != 0; --reglen, ++v1, ++v2)
351 {
352 5 void* const tmp = *v1;
353 5 *v1 = *v2;
354 5 *v2 = tmp;
355 }
356
357 1 length -= skiplen;
358 1 mem1 = (void*)((char*)mem1 + skiplen);
359 1 mem2 = (void*)((char*)mem2 + skiplen);
360 }
361
362 1 b1 = (gate_uint8_t*)mem1;
363 1 b2 = (gate_uint8_t*)mem2;
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (; bytelen != 0; --bytelen, ++b1, ++b2)
365 {
366 const gate_uint8_t tmp = *b1;
367 *b1 = *b2;
368 *b2 = tmp;
369 }
370 1 }
371