GCC Code Coverage Report


Directory: src/gate/
File: src/gate/memalloc.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 102 120 85.0%
Functions: 17 17 100.0%
Branches: 30 48 62.5%

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 67919 void* gate_mem_alloc(gate_size_t sz)
51 {
52 67919 GATE_DEBUG_ASSERT(sz != 0);
53 67919 return malloc(sz);
54 }
55 2486 void* gate_mem_realloc(void* ptr, gate_size_t newsize)
56 {
57 2486 GATE_DEBUG_ASSERT(newsize != 0);
58 2486 return realloc(ptr, newsize);
59 }
60 68433 void gate_mem_dealloc(void* ptr)
61 {
62 68433 GATE_DEBUG_ASSERT(ptr != NULL);
63 68433 free(ptr);
64 68433 }
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 228094 void* gate_mem_copy(void* dst, void const* src, gate_size_t sz)
80 {
81
3/6
✓ Branch 0 taken 228094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 228094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 228094 times.
✗ Branch 5 not taken.
228094 GATE_DEBUG_ASSERT((dst != NULL) && (src != NULL) && (sz != 0));
82 228094 return memcpy(dst, src, sz);
83 }
84
85 239 void* gate_mem_move(void* dst, void const* src, gate_size_t sz)
86 {
87
3/6
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 239 times.
✗ Branch 5 not taken.
239 GATE_DEBUG_ASSERT((dst != NULL) && (src != NULL) && (sz != 0));
88 239 return memmove(dst, src, sz);
89 }
90
91 18900 void gate_mem_clear(void* dst, gate_size_t sz)
92 {
93 18900 memset(dst, 0, sz);
94 18900 }
95
96 14 void gate_mem_fill(void* dst, char chr, gate_size_t count)
97 {
98 14 memset(dst, (unsigned char)chr, count);
99 14 }
100
101 6105 int gate_mem_compare(void const* ptr1, void const* ptr2, gate_size_t sz)
102 {
103 6105 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 129209 gate_size_t gate_mem_align_size(gate_size_t sz)
200 {
201 129209 gate_size_t m = sz % sizeof(gate_c_maxalign_t);
202
2/2
✓ Branch 0 taken 128016 times.
✓ Branch 1 taken 1193 times.
129209 if (m != 0)
203 {
204 128016 sz += (sizeof(gate_c_maxalign_t) - m);
205 }
206 129209 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 char tmp;
214
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 while (cnt-- != 0)
215 {
216 8 tmp = *ptr1;
217 8 *ptr1 = *ptr2;
218 8 *ptr2 = tmp;
219 8 ++ptr1;
220 8 --ptr2;
221 }
222 3 }
223 3 void* gate_mem_copy_reverse(void* dst, void const* src, gate_size_t sz)
224 {
225 3 char* ptrdst = (char*)dst;
226 3 char const* ptrsrc = (char const*)src + sz;
227
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 3 times.
19 while (sz-- != 0)
228 {
229 16 --ptrsrc;
230 16 *ptrdst = *ptrsrc;
231 16 ++ptrdst;
232 }
233 3 return dst;
234 }
235
236 4508 gate_result_t gate_mem_copy_construct(void* dest_item, void const* src_item, gate_size_t item_size, gate_mem_copyctor_t ctor)
237 {
238
2/2
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 4287 times.
4508 if (ctor == NULL)
239 {
240 221 gate_mem_copy(dest_item, src_item, item_size);
241 221 return GATE_RESULT_OK;
242 }
243 else
244 {
245 4287 return ctor(dest_item, src_item);
246 }
247 }
248
249 2852 void gate_mem_destruct(void* dest_item, gate_mem_dtor_t dtor)
250 {
251
2/2
✓ Branch 0 taken 2641 times.
✓ Branch 1 taken 211 times.
2852 if (dtor != NULL)
252 {
253 2641 dtor(dest_item);
254 }
255 2852 }
256 26 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)
257 {
258 gate_result_t result;
259
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 4 times.
26 if (dest_item == src_item)
260 {
261 22 return GATE_RESULT_OK;
262 }
263 4 result = gate_mem_copy_construct(dest_item, src_item, item_size, ctor);
264
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (GATE_SUCCEEDED(result))
265 {
266 4 gate_mem_destruct(src_item, dtor);
267 }
268 4 return result;
269 }
270
271
272 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)
273 {
274 gate_result_t result;
275 61 gate_bool_t ret = false;
276 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
277 61 char* ptr_buffer = &buffer[0];
278
279 do
280 {
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (item1 == item2)
282 {
283 /* pointers are equal -> nothing to swap */
284 ret = true;
285 break;
286 }
287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (item_size > sizeof(buffer))
288 {
289 ptr_buffer = gate_mem_alloc(item_size);
290 if (ptr_buffer == NULL)
291 {
292 ptr_buffer = &buffer[0];
293 break;
294 }
295 }
296
297 61 result = gate_mem_copy_construct(ptr_buffer, item1, item_size, copy_constructor);
298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 GATE_BREAK_IF_FAILED(result);
299
300 61 gate_mem_destruct(item1, destructor);
301 61 result = gate_mem_copy_construct(item1, item2, item_size, copy_constructor);
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (GATE_FAILED(result))
303 {
304 gate_mem_copy_construct(item1, ptr_buffer, item_size, copy_constructor);
305 gate_mem_destruct(ptr_buffer, destructor);
306 break;
307 }
308
309 61 gate_mem_destruct(item2, destructor);
310 61 result = gate_mem_copy_construct(item2, ptr_buffer, item_size, copy_constructor);
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (GATE_FAILED(result))
312 {
313 gate_mem_copy_construct(item2, item1, item_size, copy_constructor);
314 gate_mem_destruct(item1, destructor);
315 gate_mem_copy_construct(item1, ptr_buffer, item_size, copy_constructor);
316 gate_mem_destruct(ptr_buffer, destructor);
317 break;
318 }
319
320 61 gate_mem_destruct(ptr_buffer, destructor);
321 61 ret = true;
322 } while (0);
323
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if (ptr_buffer != &buffer[0])
325 {
326 gate_mem_dealloc(ptr_buffer);
327 }
328 61 return ret;
329 }
330
331 2 static gate_bool_t is_pointer_aligned(void const* ptr)
332 {
333 2 const gate_uintptr_t addr = (gate_uintptr_t)ptr;
334 2 return (addr % sizeof(void*) == 0);
335 }
336
337 1 void gate_mem_swap_bytes(void* mem1, void* mem2, gate_size_t length)
338 {
339 1 gate_size_t bytelen = length % sizeof(void*);
340 gate_uint8_t* b1;
341 gate_uint8_t* b2;
342
343
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))
344 {
345 /* faster transfer using aligned pointer-swap */
346 1 void** v1 = (void**)mem1;
347 1 void** v2 = (void**)mem2;
348 1 gate_size_t reglen = length / sizeof(void*);
349 1 const gate_size_t skiplen = reglen * sizeof(void*);
350
351
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (; reglen != 0; --reglen, ++v1, ++v2)
352 {
353 5 void* const tmp = *v1;
354 5 *v1 = *v2;
355 5 *v2 = tmp;
356 }
357
358 1 length -= skiplen;
359 1 mem1 = (void*)((char*)mem1 + skiplen);
360 1 mem2 = (void*)((char*)mem2 + skiplen);
361 }
362
363 1 b1 = (gate_uint8_t*)mem1;
364 1 b2 = (gate_uint8_t*)mem2;
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (; bytelen != 0; --bytelen, ++b1, ++b2)
366 {
367 const gate_uint8_t tmp = *b1;
368 *b1 = *b2;
369 *b2 = tmp;
370 }
371 1 }
372