libmemalloc  v3.5.00
Modern Memory Allocator
Loading...
Searching...
No Matches
memalloc_utils.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024-2025 Rafael V. Volkmer
3 * SPDX-FileCopyrightText: <rafael.v.volkmer@gmail.com>
4 * SPDX-License-Identifier: MIT
5 */
6
27#pragma once
28
29/*< C++ Compatibility >*/
30#ifdef __cplusplus
31extern "C"
32{
33#endif
34
47#ifndef __LIBMEMALLOC_HAS_ATTRIBUTE
48 #if defined(__has_attribute)
49 #define __LIBMEMALLOC_HAS_ATTRIBUTE(attr_) __has_attribute(attr_)
50 #else
51 #define __LIBMEMALLOC_HAS_ATTRIBUTE(attr_) 0
52 #endif
53#endif
54
59#ifndef __LIBMEMALLOC_GNUC_PREREQ
60 #if defined(__GNUC__) && !defined(__clang__)
61 #define __LIBMEMALLOC_GNUC_PREREQ(maj_, min_) \
62 ((__GNUC__ > (maj_)) || (__GNUC__ == (maj_) && __GNUC_MINOR__ >= (min_)))
63 #else
64 #define __LIBMEMALLOC_GNUC_PREREQ(maj_, min_) 0
65 #endif
66#endif
67
72#ifndef __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS
73 #if __LIBMEMALLOC_HAS_ATTRIBUTE(zero_call_used_regs) \
74 || __LIBMEMALLOC_GNUC_PREREQ(11, 0)
75 #define __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS , zero_call_used_regs("all")
76 #else
77 #define __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS
78 #endif
79#endif
80
92#ifndef ARCH_ALIGNMENT
93 /* x86_64 processor [64-bit] - Vendor: AMD/Intel */
94 #if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__)
95 #define ARCH_ALIGNMENT (8U)
96
97 /* i386 processor [32-bit] - Vendor: Intel */
98 #elif defined(__i386__) || defined(_M_IX86) || defined(__386__)
99 #define ARCH_ALIGNMENT (4U)
100
101 /* aarch64 processor [64-bit] - Vendor: ARM */
102 #elif defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64__)
103 #define ARCH_ALIGNMENT (8U)
104
105 /* arm processor [32-bit] - Vendor: ARM (v7/v6) */
106 #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_6__) || defined(__arm__) \
107 || defined(_M_ARM)
108 #define ARCH_ALIGNMENT (4U)
109
110 /* riscv processor [64-bit] - Vendor: RISC-V */
111 #elif defined(__riscv) && (__riscv_xlen == 64)
112 #define ARCH_ALIGNMENT (8U)
113 /* riscv processor [32-bit] - Vendor: RISC-V */
114 #elif defined(__riscv) && (__riscv_xlen == 32)
115 #define ARCH_ALIGNMENT (4U)
116
117 /* powerpc processor [64-bit] - Vendor: IBM */
118 #elif defined(__powerpc64__) || defined(__PPC64__)
119 #define ARCH_ALIGNMENT (8U)
120 /* powerpc processor [32-bit] - Vendor: IBM */
121 #elif defined(__powerpc__) || defined(__PPC__)
122 #define ARCH_ALIGNMENT (4U)
123
124 /* s390x processor [64-bit] - Vendor: IBM */
125 #elif defined(__s390x__) || defined(__s390__)
126 #define ARCH_ALIGNMENT (8U)
127
128 /* mips processor [64-bit] - Vendor: MIPS */
129 #elif defined(__mips64) || defined(__mips64el__)
130 #define ARCH_ALIGNMENT (8U)
131 /* mips processor [32-bit] - Vendor: MIPS */
132 #elif defined(__mips__)
133 #define ARCH_ALIGNMENT (4U)
134
135 /* loongarch processor [64-bit] - Vendor: Loongson */
136 #elif defined(__loongarch__)
137 #define ARCH_ALIGNMENT (8U)
138
139 /* avr processor [8-bit] - Vendor: Microchip */
140 #elif defined(__AVR__)
141 #define ARCH_ALIGNMENT (2U)
142 /* avr32 processor [32-bit] - Vendor: Microchip */
143 #elif defined(__avr32__)
144 #define ARCH_ALIGNMENT (4U)
145
146 /* microblaze processor [32-bit] - Vendor: Xilinx */
147 #elif defined(__MICROBLAZE__)
148 #define ARCH_ALIGNMENT (4U)
149
150 /* sh processor [32-bit] - Vendor: Renesas */
151 #elif defined(__sh__)
152 #define ARCH_ALIGNMENT (4U)
153
154 /* arc processor [32-bit] - Vendor: Synopsys */
155 #elif defined(__arc__)
156 #define ARCH_ALIGNMENT (4U)
157
158 /* bfin processor [32-bit] - Vendor: Analog Devices */
159 #elif defined(__bfin__)
160 #define ARCH_ALIGNMENT (4U)
161
162 /* wasm processor [32-bit] - Vendor: WebAssembly/Emscripten */
163 #elif defined(__EMSCRIPTEN__) || defined(__wasm__)
164 #define ARCH_ALIGNMENT (4U)
165
166 /* sparc processor [32-bit] - Vendor: Oracle */
167 #elif defined(__sparc__) || defined(__sparc)
168 #define ARCH_ALIGNMENT (4U)
169 /* sparc processor [64-bit] - Vendor: Oracle (V9) */
170 #elif defined(__sparcv9__)
171 #define ARCH_ALIGNMENT (8U)
172
173 /* ia64 processor [64-bit] - Vendor: Intel Itanium */
174 #elif defined(__ia64__)
175 #define ARCH_ALIGNMENT (8U)
176
177 /* alpha processor [64-bit] - Vendor: DEC */
178 #elif defined(__alpha__)
179 #define ARCH_ALIGNMENT (8U)
180
181 /* pru processor [32-bit] - Vendor: TI */
182 #elif defined(__TI_PRU__) || defined(__PRU__)
183 #define ARCH_ALIGNMENT (4U)
184 /* PA-RISC [32-bit] – Vendor: HP PA-RISC */
185 #elif defined(__hppa__)
186 #define ARCH_ALIGNMENT (4U)
187
188 /* z/Arch [64-bit] – Vendor: IBM Z */
189 #elif defined(__zarch__)
190 #define ARCH_ALIGNMENT (8U)
191
192 /* SPU [32-bit] – Vendor: Cell Broadband */
193 #elif defined(__cell_spu__)
194 #define ARCH_ALIGNMENT (16U) /* SPU natural aligns to 16 bytes */
195
196 /* NVPTX [64-bit] – Vendor: NVIDIA PTX */
197 #elif defined(__NVPTX__) || defined(__PTX__)
198 #define ARCH_ALIGNMENT (8U)
199
200 /* eBPF [64-bit] – in-kernel VM */
201 #elif defined(__bpf__)
202 #define ARCH_ALIGNMENT (8U)
203
204 /* Elbrus E2K [64-bit] – Vendor: MCST */
205 #elif defined(__e2k__)
206 #define ARCH_ALIGNMENT (8U)
207
208 /* CRIS [32-bit] – Vendor: Axis Communications */
209 #elif defined(__CRIS__)
210 #define ARCH_ALIGNMENT (4U)
211
212 /* TILEGX [64-bit] – Vendor: Tilera */
213 #elif defined(__tilegx__)
214 #define ARCH_ALIGNMENT (8U)
215
216 /* Generic fallback */
217 #else
218 #error "[ERROR] Unknown Architecture: check 'ARCH_ALIGNMENT'"
219 #endif
220#endif
221
231#define ALIGN(val_) (((val_) + (ARCH_ALIGNMENT - 1U)) & ~(ARCH_ALIGNMENT - 1U))
232
243#define PTR_ERR(ptr_) ((void *)((intptr_t)(ptr_)))
244
257#ifndef __LIBMEMALLOC_API
258 #if defined(_WIN32)
259 #ifdef BUILDING_LIBMEMALLOC
260 #define __LIBMEMALLOC_API __declspec(dllexport)
261 #else
262 #define __LIBMEMALLOC_API __declspec(dllimport)
263 #endif
264 #else
265 #if defined(__GNUC__) || defined(__clang__)
266 #define __LIBMEMALLOC_API __attribute__((visibility("default")))
267 #else
268 #define __LIBMEMALLOC_API
269 #endif
270 #endif
271#endif
272
286#ifndef __ALIGN
287 #if __LIBMEMALLOC_HAS_ATTRIBUTE(scalar_storage_order) \
288 || __LIBMEMALLOC_GNUC_PREREQ(8, 0)
289 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
290 #define __LIBMEMALLOC_ATTR_SSO \
291 __attribute__((scalar_storage_order("big-endian")))
292 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
293 #define __LIBMEMALLOC_ATTR_SSO \
294 __attribute__((scalar_storage_order("little-endian")))
295 #else
296 #error "[ERROR] Unknown Endianness: check '__BYTE_ORDER__'"
297 #endif
298 #else
299 #define __LIBMEMALLOC_ATTR_SSO
300 #endif
301
302 #if (defined(__GNUC__) || defined(__clang__) \
303 || __LIBMEMALLOC_HAS_ATTRIBUTE(aligned))
304 #define __LIBMEMALLOC_ATTR_ALIGNED __attribute__((aligned(ARCH_ALIGNMENT)))
305 #else
306 #define __LIBMEMALLOC_ATTR_ALIGNED
307 #endif
308
309 #define __ALIGN __LIBMEMALLOC_ATTR_SSO __LIBMEMALLOC_ATTR_ALIGNED
310#endif
311
320#ifndef __UNUSED
321 #if defined(__GNUC__) || defined(__clang__)
322 #define __UNUSED __attribute__((unused))
323 #else
324 #define __UNUSED
325 #endif
326#endif
327
338#ifndef __GC_HOT
339 #if defined(__GNUC__) || defined(__clang__)
340 #define __GC_HOT __attribute__((hot))
341 #else
342 #define __GC_HOT
343 #endif
344#endif
345
356#ifndef __GC_COLD
357 #if defined(__GNUC__) || defined(__clang__)
358 #define __GC_COLD __attribute__((cold))
359 #else
360 #define __GC_COLD
361 #endif
362#endif
363
377#ifndef __LIBMEMALLOC_INTERNAL_MALLOC
378 #if defined(__GNUC__) || defined(__clang__)
379 #define __LIBMEMALLOC_INTERNAL_MALLOC \
380 __attribute__((malloc, \
381 alloc_size(2), \
382 warn_unused_result, \
383 returns_nonnull __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS))
384 #else
385 #define __LIBMEMALLOC_INTERNAL_MALLOC
386 #endif
387#endif
388
402#ifndef __LIBMEMALLOC_MALLOC
403 #if defined(__GNUC__) || defined(__clang__)
404 #define __LIBMEMALLOC_MALLOC \
405 __attribute__((malloc, \
406 alloc_size(1), \
407 warn_unused_result, \
408 returns_nonnull __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS))
409 #else
410 #define __LIBMEMALLOC_MALLOC
411 #endif
412#endif
413
426#ifndef __LIBMEMALLOC_REALLOC
427 #if defined(__GNUC__) || defined(__clang__)
428 #define __LIBMEMALLOC_REALLOC \
429 __attribute__((malloc, \
430 alloc_size(2), \
431 warn_unused_result, \
432 returns_nonnull __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS))
433 #else
434 #define __LIBMEMALLOC_REALLOC
435 #endif
436#endif
437
450#ifndef __LIBMEMALLOC_INTERNAL_REALLOC
451 #if defined(__GNUC__) || defined(__clang__)
452 #define __LIBMEMALLOC_INTERNAL_REALLOC \
453 __attribute__((malloc, \
454 alloc_size(3), \
455 warn_unused_result, \
456 returns_nonnull __LIBMEMALLOC_ATTR_ZERO_CALL_USED_REGS))
457 #else
458 #define __LIBMEMALLOC_INTERNAL_REALLOC
459 #endif
460#endif
461
475#ifndef LIKELY
476 #if (defined(__has_builtin) && __has_builtin(__builtin_expect)) \
477 || defined(__GNUC__) || defined(__clang__)
478 #define LIKELY(cond_) (__builtin_expect(!!(cond_), 1))
479 #else
480 #define LIKELY(cond_) (!!(cond_))
481 #endif
482#endif
483
493#ifndef UNLIKELY
494 #if (defined(__has_builtin) && __has_builtin(__builtin_expect)) \
495 || defined(__GNUC__) || defined(__clang__)
496 #define UNLIKELY(cond_) (__builtin_expect(!!(cond_), 0))
497 #else
498 #define UNLIKELY(cond_) (!!(cond_))
499 #endif
500#endif
501
511#ifndef PREFETCH_R
512 #if (defined(__has_builtin) && __has_builtin(__builtin_prefetch)) \
513 || defined(__GNUC__) || defined(__clang__)
514 #define PREFETCH_R(addr_) __builtin_prefetch((addr_), 0, 1)
515 #else
516 #define PREFETCH_R(addr_) ((void)0)
517 #endif
518#endif
519
529#ifndef PREFETCH_W
530 #if (defined(__has_builtin) && __has_builtin(__builtin_prefetch)) \
531 || defined(__GNUC__) || defined(__clang__)
532 #define PREFETCH_W(addr_) __builtin_prefetch((addr_), 1, 1)
533 #else
534 #define PREFETCH_W(addr_) ((void)0)
535 #endif
536#endif
537
550#ifndef ASSUME_ALIGNED
551 #if (defined(__has_builtin) && __has_builtin(__builtin_assume_aligned)) \
552 || defined(__GNUC__) || defined(__clang__)
553 #define ASSUME_ALIGNED(ptr_, align_) \
554 __builtin_assume_aligned((ptr_), (align_))
555 #else
556 #define ASSUME_ALIGNED(ptr_, align_) (align_)
557 #endif
558#endif
559
560/*< C++ Compatibility >*/
561#ifdef __cplusplus
562}
563#endif
564
567/*< end of header file >*/