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.
#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.
- allocator_proc is the allocator procedure; call it directly or wrap it in an
Allocator. - usable_size, is_this_yours and heap_free_all ask about or clear a heap.
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#
True once the allocator has been set up.
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.
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);↗True if memory is a live allocation from heap.
memory := allocator_proc(.ALLOCATE, 10, 0, null, null);
assert(is_this_yours(allocator_default_heap, memory));
allocator_proc(.FREE, 0, 10, memory, null);↗Frees every allocation in heap at once.
Returns counters for the whole allocator. This allocator keeps none, so every field is zero.
Returns counters for heap. This allocator keeps none, so every field is zero.
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#
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
Counters for one heap, as returned by heap_statistics.
- sizecache: s64
- spancache: s64
- block_size: u32
- block_count: u16
- class_idx: u16
- 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
- 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
- _pad0: u32
- dwPageSize: u32
- _pad1: [8] u32
- dwAllocationGranularity: u32
- _pad2: u32
Constants#
The default heap as an Allocator.