Modules

Default_Allocator

moduleSource

Available on macOS, Linux, Windows, Wasm

#import "Default_Allocator";

The general-purpose heap allocator behind context.allocator. It is thread safe, can create separate heaps, and tells you whether it owns a pointer.

Example↗
memory := cast(*u8) allocator_proc(.ALLOCATE, 16, 0, null, null);
memory[0] = 42;
assert(memory[0] == 42);
allocator_proc(.FREE, 0, 16, memory, null);

Module parameters#

ENABLE_ASSERTS := true
Checks the allocator's internal invariants.
ENABLE_VALIDATE_ARGS := true
Checks the arguments of its procedures.

Procedures#

() -> did_init: bool

Sets the allocator up if nothing has used it yet. Returns true if this call did the setup. It is called for you on first use.

()

Frees every heap and every block in them, and returns the allocator to its unset-up state. For program shutdown.

()
()

Releases the allocator's lock whoever holds it. Only for the child of a fork, where a thread that no longer exists may have held it.

(ptr: *void) -> s64

Returns how many bytes the allocation at ptr can hold, which can exceed what was asked for. Returns 0 for null.

memory := allocator_proc(.ALLOCATE, 10, 0, null, null);
assert(usable_size(memory) >= 10);
allocator_proc(.FREE, 0, 10, memory, null);
↗
(mode: Allocator_Mode, requested_size: s64, old_size: s64, old_memory: *void, allocator_data: *void) -> *void
(mode: Allocator_Mode, size: s64, old_size: s64, old_memory: *void, allocator_data: *void) -> *void

The allocator procedure. It handles .ALLOCATE, .RESIZE, .FREE, .CREATE_HEAP, .DESTROY_HEAP and .IS_THIS_YOURS; allocator_data is the heap, or null for the default one. Allocation returns null when the size is invalid or memory runs out.

memory := cast(*u8) allocator_proc(.ALLOCATE, 8, 0, null, null);
memset(memory, 7, 8);
grown := cast(*u8) allocator_proc(.RESIZE, 64, 8, memory, null);
assert(grown[7] == 7);
allocator_proc(.FREE, 0, 64, grown, null);
↗

Types#

:: struct

Counters for the whole allocator, as returned by global_statistics.

mapped: s64
mapped_peak: s64
cached: s64
huge_alloc: s64
huge_alloc_peak: s64
mapped_total: s64
unmapped_total: s64
:: struct

Counters for one heap, as returned by heap_statistics.

sizecache: s64
spancache: s64
:: struct
block_size: u32
block_count: u16
class_idx: u16
:: struct
free_list: *void
block_count: u32
size_class: u32
free_list_limit: u32
used_count: u32
free_list_deferred: *void
list_size: u32
block_size: u32
flags: enum_flags u32 { MASTER :: 1; SUBSPAN :: 2; ALIGNED_BLOCKS :: 4; UNMAPPED_MASTER :: 8; }
span_count: u32
total_spans: u32
offset_from_master: u32
remaining_spans: s32
align_offset: u32
heap: *Heap
next: *Span
prev: *Span
:: struct
lock: *void
is_orphaned: bool
size_class: [126] Heap_Size_Class
span_free_deferred: *void
full_span_count: s64
span_reserve: *Span
span_reserve_master: *Span
spans_reserved: u32
child_count: s32
next_heap: *Heap
next_orphan: *Heap
id: s32
finalize: s32
master_heap: *Heap
full_span: [126] *Span
large_huge_span: *Span
SYSTEM_INFOstructWindows onlySource
:: struct
_pad0: u32
dwPageSize: u32
_pad1: [8] u32
dwAllocationGranularity: u32
_pad2: u32

Constants#