HeapAllocatorInit
Description
Construct a HeapAllocator with default alignment (1). Use as a designated-initializer at any storage class. The allocator starts empty: no descriptors, no XL regions, no recycled pages; all kernel page mappings happen lazily on the first alloc per class.
HeapAllocator h = HeapAllocatorInit(); void *p = AllocatorAlloc(&h, 64, false); AllocatorFree(&h, p); HeapAllocatorDeinit(&h);
Success
Returns a fully-initialised HeapAllocator value. No OS calls are made; first per-class alloc triggers the lazy page-map.
Failure
Cannot fail at macro-expansion time.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Log.h:42:
#define LOG_FATAL(...) \
do { \
HeapAllocator UNPL(log_alloc) = HeapAllocatorInit(); \
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \- In
Log.h:66:
#define LOG_ERROR(...) \
do { \
HeapAllocator UNPL(log_alloc) = HeapAllocatorInit(); \
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \- In
Log.h:89:
#define LOG_INFO(...) \
do { \
HeapAllocator UNPL(log_alloc) = HeapAllocatorInit(); \
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \- In
Log.h:124:
do { \
i32 UNPL(sys_eno) = (i32)(eno); \
HeapAllocator UNPL(log_alloc) = HeapAllocatorInit(); \
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \
- In
Log.h:153:
do { \
i32 UNPL(sys_eno) = (i32)(eno); \
HeapAllocator UNPL(log_alloc) = HeapAllocatorInit(); \
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \
- In
Log.h:181:
do { \
i32 UNPL(sys_eno) = (i32)(eno); \
HeapAllocator UNPL(log_alloc) = HeapAllocatorInit(); \
Str UNPL(m) = StrInit(&UNPL(log_alloc)); \
StrAppendFmt(&UNPL(m), __VA_ARGS__); \
- In
Default.h:84:
# endif
#else
# define DefaultAllocatorInit() HeapAllocatorInit()
#endif- In
Debug.h:516:
.__magic = DEBUG_ALLOCATOR_MAGIC | MAGIC_VALIDATED_BIT, \
.footprint_bytes = 0}, \
.heap = HeapAllocatorInit(), \
.meta = HeapAllocatorInit(), \
.page = PageAllocatorInit(), \
- In
Debug.h:517:
.footprint_bytes = 0}, \
.heap = HeapAllocatorInit(), \
.meta = HeapAllocatorInit(), \
.page = PageAllocatorInit(), \
.config = (_cfg), \
- In
Log.c:53:
};
HeapAllocator h = HeapAllocatorInit();
Str full = StrInit(&h);
StrAppendFmt(&full, "[{}] [{}:{}] {}\n", (Zstr)NAMES[type], (Zstr)tag, line, (Zstr)msg);- In
Dir.c:536:
// we don't know the entry count in advance. The per-entry path
// string is stack-backed via StrInitStack below.
HeapAllocator ha = HeapAllocatorInit();
// dir_get_contents takes `Allocator *` (it's a generic helper used
// by both typed and erased callers) -- legitimate erasure boundary;
- In
Socket.c:978:
bool used_heap = false;
if (count > STACK_MAX) {
halloc = HeapAllocatorInit();
pfds = (plat_pollfd_t *)AllocatorAlloc(&halloc, sizeof(plat_pollfd_t) * count, true);
if (!pfds) {
static bool test_basic_alloc_free(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_zeroed_alloc(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_zero_byte_alloc_returns_null(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_free_null_is_noop(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap); // Three allocs of the same size must yield three distinct pointers.
// After the third alloc, bits 0..2 of bitmap_32 should be set.
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_free_then_alloc_recycles(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap); N = HEAP_PAGES_PER_OS_PAGE * SLOTS_PER_32_PAGE + 1
};
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap); // set after the power-of-two rewrite, so each alloc lands in a
// distinct class and provisions its own page(s).
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap); static bool test_large_alloc_passthrough(void) {
// > 2 KiB hits the XL path.
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_realloc_same_bin_keeps_pointer(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_realloc_cross_bin_copies(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
static bool test_independent_heaps(void) {
HeapAllocator h1 = HeapAllocatorInit();
HeapAllocator h2 = HeapAllocatorInit();
Allocator *alloc1 = ALLOCATOR_OF(&h1); static bool test_independent_heaps(void) {
HeapAllocator h1 = HeapAllocatorInit();
HeapAllocator h2 = HeapAllocatorInit();
Allocator *alloc1 = ALLOCATOR_OF(&h1);
Allocator *alloc2 = ALLOCATOR_OF(&h2);
static bool test_reject_foreign_pointer(void) {
HeapAllocator h1 = HeapAllocatorInit();
HeapAllocator h2 = HeapAllocatorInit();
Allocator *alloc1 = ALLOCATOR_OF(&h1); static bool test_reject_foreign_pointer(void) {
HeapAllocator h1 = HeapAllocatorInit();
HeapAllocator h2 = HeapAllocatorInit();
Allocator *alloc1 = ALLOCATOR_OF(&h1);
Allocator *alloc2 = ALLOCATOR_OF(&h2);
static bool test_reject_double_free(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
void *p = AllocatorAlloc(alloc, 32, false);
static bool test_reject_misaligned_pointer(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
u8 *p = (u8 *)AllocatorAlloc(alloc, 64, false);
static bool test_reject_mid_xl_pointer(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
size n = 16 * 1024;- In
AllocDebug.c:123:
// allocator -- not through `dbg` -- so its own storage isn't
// counted as a leak by the very report we're about to generate.
HeapAllocator scratch = HeapAllocatorInit();
Str out = StrInit(&scratch);
DebugAllocatorReportLeaks(&dbg, &out); (void)p;
HeapAllocator scratch = HeapAllocatorInit();
Str out = StrInit(&scratch);
DebugAllocatorReportLeaks(&dbg, &out);- In
Vec.Insert.c:363:
typedef Vec(int) IntVec;
HeapAllocator local_heap = HeapAllocatorInit();
// intentional bypass: no public setter on `Allocator` for effort /
// retry_limit -- pre-seeded directly so the inheritance path below
ok = ok && (rec != NULL) && (rec->alloc_trace_n >= 2);
HeapAllocator scratch = HeapAllocatorInit();
Str out = StrInit(&scratch);
DebugAllocatorReportLeaks(&dbg, &out); u32 n = ok ? rec->alloc_trace_n : 0;
HeapAllocator scratch = HeapAllocatorInit();
Str out = StrInit(&scratch);
DebugAllocatorReportLeaks(&dbg, &out);- In
Vec.Complex.c:23:
static Allocator *fixture_alloc(void) {
if (!g_fixture_heap_ready) {
g_fixture_heap = HeapAllocatorInit();
g_fixture_heap_ready = true;
}- In
Io.Leak.c:57:
// Float backed by a SEPARATE heap so only the formatter scratch shows
// up in dbg's live count.
HeapAllocator fa = HeapAllocatorInit();
Float v = FloatFromStr("12345.67", ALLOCATOR_OF(&fa));- In
Io.Leak.c:83:
Allocator *adbg = ALLOCATOR_OF(&dbg);
HeapAllocator fa = HeapAllocatorInit();
Float v = FloatFromStr("0.0", ALLOCATOR_OF(&fa));- In
Io.Leak.c:109:
Allocator *adbg = ALLOCATOR_OF(&dbg);
HeapAllocator fa = HeapAllocatorInit();
Float v = FloatFromStr("3.14159", ALLOCATOR_OF(&fa));- In
Io.Leak.c:136:
Allocator *adbg = ALLOCATOR_OF(&dbg);
HeapAllocator fa = HeapAllocatorInit();
Float v = FloatFromStr("42", ALLOCATOR_OF(&fa));- In
Io.Leak.c:297:
bool test_leak_write_str_freed(void) {
HeapAllocator va = HeapAllocatorInit();
Str s = StrInit(ALLOCATOR_OF(&va));
StrAppendFmt(&s, "payload");- In
Io.Leak.c:311:
bool test_leak_write_int_freed(void) {
HeapAllocator va = HeapAllocatorInit();
Int v = IntFromStr("123456789012345678901234567890", ALLOCATOR_OF(&va));
LEAK_WRITE_PRELUDE();- In
Io.Leak.c:324:
bool test_leak_write_float_freed(void) {
HeapAllocator va = HeapAllocatorInit();
Float v = FloatFromStr("2.718281828", ALLOCATOR_OF(&va));
LEAK_WRITE_PRELUDE();- In
Io.Leak.c:337:
bool test_leak_write_bitvec_freed(void) {
HeapAllocator va = HeapAllocatorInit();
BitVec v = BitVecInit(ALLOCATOR_OF(&va));
BitVecResize(&v, 12);- In
Io.Leak.c:358:
// 1794: _write_Str `{x}` (FMT_FLAG_HEX) per-byte `hex` scratch.
bool test_leak_write_str_hex_per_byte_freed(void) {
HeapAllocator sa = HeapAllocatorInit();
Str s = StrInit(ALLOCATOR_OF(&sa));
for (int i = 0; i < 8; ++i)- In
Io.Leak.c:382:
// 2286: _write_Float default-decimal `temp` (via float_try_to_decimal_str).
bool test_leak_write_float_default_freed(void) {
HeapAllocator fa = HeapAllocatorInit();
Float f = FloatFromStr("12345678901234567890123456789012345678901234567890.5", ALLOCATOR_OF(&fa));
LEAK_WRITE_PRELUDE();- In
Vec.Memory.c:375:
// reserve_vec zeroes it.
static bool reserve_zero_grown_region(int probe_index) {
HeapAllocator heap = HeapAllocatorInit();
typedef Vec(int) IntVec;- In
Vec.Memory.c:423:
WriteFmt("Testing reserve at the overflow boundary returns false (112:42)\n");
HeapAllocator heap = HeapAllocatorInit(); // alignment 1 -> aligned_size == 1
typedef Vec(char) CharVec;- In
Vec.Init.c:174:
// that the pointer-based allocator stored in the vector reflects each
// allocator's settings.
HeapAllocator h_default = HeapAllocatorInit();
HeapAllocator h8 = HeapAllocatorInitAligned(8);
HeapAllocator h16 = HeapAllocatorInitAligned(16); // 112 (stats.peak_bytes_in_use = in_use -> = 42): same for peak.
static bool test_al_reset_stats_preserves_outstanding(void) {
HeapAllocator heap = HeapAllocatorInit();
Allocator *alloc = ALLOCATOR_OF(&heap);
Last updated on