CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
xalloc.h
Go to the documentation of this file.
1
6
7#pragma once
8
9#include <cx/platform/cpp.h>
11#include <cx/utils/macros/salieri.h>
13#include <stdbool.h>
14#include <stddef.h>
15
16#ifdef XALLOC_REMAP_MALLOC
17// these need to be pulled in first so our #defines don't cause chaos when they
18// are included
19#include <stdlib.h>
20#include <string.h>
21
22#ifdef _WIN32
23// never use this; we have heap profilers these days
24#undef _CRTDBG_MAP_ALLOC
25#include <crtdbg.h>
26#endif
27#endif
28
29// If this macro is defined, causes the xalloc system to use the
30// system-provided allocator rather than mimalloc. There may be some
31// loss of functionality and performance when this option is in use,
32// but it may be needed on systems with very tightly constrained limits
33// on virtual address space allocation.
34// #define XALLOC_USE_SYSTEM_MALLOC 1
35
36CX_C_BEGIN
37
76
82
83#define XA_LG_ALIGN_MASK ((unsigned int)0x3f)
84
88#define XA_Align(exp) ((unsigned int)(exp & XA_LG_ALIGN_MASK))
89
91#define XA_Zero ((unsigned int)0x0040)
92
93enum XA_OPTIONAL_FLAG_ENUM {
94 XA_Optional_High = 0x0100,
95 XA_Optional_Low = 0x0200,
96 XA_Optional_None = 0x0400
97};
98#define XA_Optional(typ) ((unsigned int)XA_Optional_##typ)
99#define XA_Optional_Mask (XA_Optional_High | XA_Optional_Low | XA_Optional_None)
100
109#define XA_Opt XA_Optional(High)
110
112// end of xalloc_flags group
113
119
151
152#ifndef _MSC_VER
153// &* is a safe way to ensure the operand is a pointer, even a pointer to void
154#define _xa_ptr_ptr_verify(ptr) unused_noeval(&*(*(ptr)))
155#else
156// &* doesn't work for void* on MSVC, check for void* conversion instead, but this results
157// in a false negative for intptr_t* or pointer-sized ints
158#define _xa_ptr_ptr_verify(ptr) unused_noeval((void*)(*(ptr)))
159#endif
160
168typedef void (*xaOOMCallback)(int phase, size_t allocsz);
169
173
177
179// end of xalloc_oom group
180
186
199#define xaAlloc(size, ...) _xaAlloc(size, opt_flags(__VA_ARGS__))
200
213#define xaAllocStruct(typn, ...) (typn*)_xaAlloc(sizeof(typn), opt_flags(__VA_ARGS__))
214
215_Check_return_ _When_(flags & XA_Optional_Mask, _Must_inspect_result_ _Ret_maybenull_)
216 _When_(!(flags & XA_Optional_Mask), _Ret_notnull_)
217 _When_(!(flags & XA_Optional_Mask) && (flags & XA_Zero), _Ret_valid_)
218 _Post_writable_byte_size_(size) void*
219_xaAlloc(size_t size, unsigned int flags);
220
230#define xaResize(ptr, size, ...) \
231 (_xa_ptr_ptr_verify(ptr), _xaResize((void**)(ptr), size, opt_flags(__VA_ARGS__)))
232_At_(*ptr, _Pre_maybenull_) _When_(!(flags & XA_Optional_Mask), _At_(*ptr, _Post_writable_byte_size_(size)) ) bool _xaResize(_Inout_ void** ptr, size_t size, unsigned int flags);
233
237void xaFree(_Pre_maybenull_ _Post_invalid_ void* ptr);
238
245#define xaDestroy(ptr) (_xa_ptr_ptr_verify(ptr), _xaDestroy((void**)(ptr)))
246_At_(*ptr, _Pre_maybenull_ _Post_null_) bool _xaDestroy(_Inout_ void** ptr);
247
249// end of xalloc_core group
250
256
270size_t xaSize(_In_ const void* ptr);
271
282size_t xaOptSize(size_t sz);
283
285// end of xalloc_introspection group
286
288void xaFlush();
289
290CX_C_END
291
292// String utilities because cstrDup is tied in with xalloc
293// and there's no better place for them
294#include <cx/xalloc/cstrutil.h>
295
296#ifdef XALLOC_REMAP_MALLOC
297#define malloc(sz) xa_malloc(sz)
298#define calloc(num, sz) xa_calloc(num, sz)
299#define free(ptr) xa_free(ptr)
300#define realloc(ptr, sz) xa_realloc(ptr, sz)
301#define strdup(s) cstrDup(s)
302#define _strdup(s) cstrDup(s)
303#define wcsdup(s) cstrDupw(s)
304#define _wcsdup(s) cstrDupw(s)
305
306#ifdef _WIN32
307#undef _malloc_dbg
308#define _malloc_dbg(sz, t, f, ln) xa_malloc(sz)
309#undef _calloc_dbg
310#define _calloc_dbg(num, sz, t, f, ln) xa_calloc(num, sz)
311#undef _free_dbg
312#define _free_dbg(ptr, t) xa_free(ptr)
313#undef _realloc_dbg
314#define _realloc_dbg(ptr, sz, t, f, ln) xa_realloc(ptr, sz)
315#undef _strdup_dbg
316#define _strdup_dbg(s, t, f, ln) cstrDup(s)
317#undef _wcsdup_dbg
318#define _wcsdup_dbg(s, t, f, ln) cstrDupw(s)
319#endif
320#endif
321
334
335#ifdef XALLOC_COMPAT_REQUIRE
336#define XA_COMPAT_OPT_FLAG 0
337#else
338#define XA_COMPAT_OPT_FLAG XA_Opt
339#endif
340
341// for compatibility with 3rd party libraries only
343inline void* xa_malloc(size_t size)
344{
345 return _xaAlloc(size, XA_COMPAT_OPT_FLAG);
346}
347
349inline void* xa_calloc(size_t number, size_t size)
350{
351 return _xaAlloc(number * size, XA_Zero | XA_COMPAT_OPT_FLAG);
352}
353
355inline void* xa_realloc(void* ptr, size_t size)
356{
357 return _xaResize(&ptr, size, XA_COMPAT_OPT_FLAG) ? ptr : (void*)0;
358}
359
361inline void xa_free(void* ptr)
362{
363 xaFree(ptr);
364}
365
367inline char* xa_strdup(const char* src)
368{
369 return cstrDup(src);
370}
371
373// end of xalloc_compat group
374
376// end of xalloc group
C string utility functions.
char * cstrDup(const char *s)
char * xa_strdup(const char *src)
strdup-compatible string duplication function
Definition xalloc.h:367
void * xa_realloc(void *ptr, size_t size)
realloc-compatible allocation function
Definition xalloc.h:355
void * xa_malloc(size_t size)
malloc-compatible allocation function
Definition xalloc.h:343
void * xa_calloc(size_t number, size_t size)
calloc-compatible allocation function
Definition xalloc.h:349
void xa_free(void *ptr)
free-compatible deallocation function
Definition xalloc.h:361
void xaFree(void *ptr)
#define XA_Zero
Zero-fills returned memory.
Definition xalloc.h:91
size_t xaSize(const void *ptr)
size_t xaOptSize(size_t sz)
void(* xaOOMCallback)(int phase, size_t allocsz)
Definition xalloc.h:168
void xaRemoveOOMCallback(xaOOMCallback cb)
void xaAddOOMCallback(xaOOMCallback cb)
XA_OOM_PHASE_ENUM
Phases of out-of-memory handling, indicating escalating urgency.
Definition xalloc.h:121
@ XA_Urgent
Definition xalloc.h:140
@ XA_Fatal
Definition xalloc.h:149
@ XA_LowEffort
Definition xalloc.h:127
@ XA_HighEffort
Definition xalloc.h:133
void xaFlush()
Flushes any deferred free() operations and returns as much memory to the OS as possible.
Optional macro argument handling.
Copy-on-write strings with automatic memory management and rope optimization.
Macros for suppressing compiler warnings.