Various allocators and provides helpers for dealing with memory, pointers and slices. The documentation below describes basic concepts, applicable to the `mem` package. ## Pointers, multipointers, and slices A *pointer* is an abstraction of an *address*, a numberic value representing the location of an object in memory. That object is said to be *pointed to* by the pointer. To obtain the address of a pointer, cast it to `uintptr`. A multipointer is a pointer that points to multiple objects. Unlike a pointer, a multipointer can be indexed, but does not have a definite length. A slice is a pointer that points to multiple objects equipped with the length, specifying the amount of objects a slice points to. When an object's values are read through a pointer, that operation is called a *load* operation. When memory is written to through a pointer, that operation is called a *store* operation. Both of these operations can be called a *memory access operation*. ## Allocators In C and C++ memory models, allocations of objects in memory are typically treated individually with a generic allocator (The `malloc` procedure). Which in some scenarios can lead to poor cache utilization, slowdowns on individual objects' memory management and growing complexity of the code needing to keep track of the pointers and their lifetimes. Using different kinds of *allocators* for different purposes can solve these problems. The allocators are typically optimized for specific use-cases and can potentially simplify the memory management code. For example, in the context of making a game, having an Arena allocator could simplify allocations of any temporary memory, because the programmer doesn't have to keep track of which objects need to be freed every time they are allocated, because at the end of every frame the whole allocator is reset to its initial state and all objects are freed at once. The allocators have different kinds of restrictions on object lifetimes, sizes, alignment and can be a significant gain, if used properly. Odin supports allocators on a language level. Operations such as `new`, `free` and `delete` by default will use `context.allocator`, which can be overridden by the user. When an override happens all called procedures will inherit the new context and use the same allocator. We will define one concept to simplify the description of some allocator-related procedures, which is ownership. If the memory was allocated via a specific allocator, that allocator is said to be the *owner* of that memory region. To note, unlike Rust, in Odin the memory ownership model is not strict. ## Alignment An address is said to be *aligned to `N` bytes*, if the addresses's numeric value is divisible by `N`. The number `N` in this case can be referred to as the *alignment boundary*. Typically an alignment is a power of two integer value. A *natural alignment* of an object is typically equal to its size. For example a 16 bit integer has a natural alignment of 2 bytes. When an object is not located on its natural alignment boundary, accesses to that object are considered *unaligned*. Some machines issue a hardware **exception**, or experience **slowdowns** when a memory access operation occurs from an unaligned address. Examples of such operations are: - SIMD instructions on x86. These instructions require all memory accesses to be on an address that is aligned to 16 bytes. - On ARM unaligned loads have an extra cycle penalty. As such, many operations that allocate memory in this package allow to explicitly specify the alignment of allocated pointers/slices. The default alignment for all operations is specified in a constant `mem.DEFAULT_ALIGNMENT`. ## Zero by default Whenever new memory is allocated, via an allocator, or on the stack, by default Odin will zero-initialize that memory, even if it wasn't explicitly initialized. This allows for some convenience in certain scenarios and ease of debugging, which will not be described in detail here. However zero-initialization can be a cause of slowdowns, when allocating large buffers. For this reason, allocators have `*_non_zeroed` modes of allocation that allow the user to request for uninitialized memory and will avoid a relatively expensive zero-filling of the buffer. ## Naming conventions The word `size` is used to denote the **size in bytes**. The word `length` is used to denote the count of objects. The allocation procedures use the following conventions: - If the name contains `alloc_bytes` or `resize_bytes`, then the procedure takes in slice parameters and returns slices. - If the procedure name contains `alloc` or `resize`, then the procedure takes in a raw pointer and returns raw pointers. - If the procedure name contains `free_bytes`, then the procedure takes in a slice. - If the procedure name contains `free`, then the procedure takes in a pointer. Higher-level allocation procedures follow the following naming scheme: - `new`: Allocates a single object - `free`: Free a single object (opposite of `new`) - `make`: Allocate a group of objects - `delete`: Free a group of objects (opposite of `make`)

Collection Info

View Source
Collection
core
Path
mem
Entries
256

Source Files

Constants

15

Byte #

Source
Byte :: runtime.Byte

The size, in bytes, of a single byte. This constant is equal to the value of `1`.

DEFAULT_ALIGNMENT #

Source
DEFAULT_ALIGNMENT :: 2 * align_of(rawptr)

Default alignment. This value is the default alignment for all platforms that is used, if the alignment is not specified explicitly.

DEFAULT_PAGE_SIZE #

Source
DEFAULT_PAGE_SIZE :: 64 * 1024 when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 else 16 * 1024 when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 else 4 * 1024

Default page size. This value is the default page size for the current platform.

DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT #

Source
DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT :: 65536

Default block size for dynamic arena.

DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT #

Source
DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT :: 6554

Default out-band size of the dynamic arena.

DYNAMIC_POOL_BLOCK_SIZE_DEFAULT #

Source
DYNAMIC_POOL_BLOCK_SIZE_DEFAULT :: DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT

DYNAMIC_POOL_OUT_OF_BAND_SIZE_DEFAULT #

Source
DYNAMIC_POOL_OUT_OF_BAND_SIZE_DEFAULT :: DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT

Exabyte #

Source
Exabyte :: runtime.Exabyte

The size, in bytes, of one exabyte. This constant is equal to the amount of bytes in one exabyte (also known as exbibyte), which is equal to 1024 petabytes.

Gigabyte #

Source
Gigabyte :: runtime.Gigabyte

The size, in bytes, of one gigabyte. This constant is equal to the amount of bytes in one gigabyte (also known as gibiibyte), which is equal to 1024 megabytes.

Kilobyte #

Source
Kilobyte :: runtime.Kilobyte

The size, in bytes, of one kilobyte. This constant is equal to the amount of bytes in one kilobyte (also known as kibibyte), which is equal to 1024 bytes.

Megabyte #

Source
Megabyte :: runtime.Megabyte

The size, in bytes, of one megabyte. This constant is equal to the amount of bytes in one megabyte (also known as mebibyte), which is equal to 1024 kilobyte.

Petabyte #

Source
Petabyte :: runtime.Petabyte

The size, in bytes, of one petabyte. This constant is equal to the amount of bytes in one petabyte (also known as pebiibyte), which is equal to 1024 terabytes.

ROLLBACK_STACK_DEFAULT_BLOCK_SIZE #

Source
ROLLBACK_STACK_DEFAULT_BLOCK_SIZE :: 4 * Megabyte

Rollback stack default block size.

ROLLBACK_STACK_MAX_HEAD_BLOCK_SIZE #

Source
ROLLBACK_STACK_MAX_HEAD_BLOCK_SIZE :: 2 * Gigabyte

Rollback stack max head block size. This limitation is due to the size of `prev_ptr`, but it is only for the head block; any allocation in excess of the allocator's `block_size` is valid, so long as the block allocator can handle it. This is because allocations over the block size are not split up if the item within is freed; they are immediately returned to the block allocator.

Terabyte #

Source
Terabyte :: runtime.Terabyte

The size, in bytes, of one terabyte. This constant is equal to the amount of bytes in one terabyte (also known as tebiibyte), which is equal to 1024 gigabytes.

Types

45

Allocator #

Source
Allocator :: Allocator

Allocator. This type represents generic interface for all allocators. Currently this type is defined as follows: Allocator :: struct { procedure: Allocator_Proc, data: rawptr, } - `procedure`: Pointer to the allocation procedure. - `data`: Pointer to the allocator data.

Allocator_Error #

Source
Allocator_Error :: Allocator_Error

An allocation request error. This type represents error values the allocators may return upon requests. Allocator_Error :: enum byte { None = 0, Out_Of_Memory = 1, Invalid_Pointer = 2, Invalid_Argument = 3, Mode_Not_Implemented = 4, } The meaning of the errors is as follows: - `None`: No error. - `Out_Of_Memory`: Either: 1. The allocator has ran out of the backing buffer, or the requested allocation size is too large to fit into a backing buffer. 2. The operating system error during memory allocation. 3. The backing allocator was used to allocate a new backing buffer and the backing allocator returned Out_Of_Memory. - `Invalid_Pointer`: The pointer referring to a memory region does not belong to any of the allocators backing buffers or does not point to a valid start of an allocation made in that allocator. - `Invalid_Argument`: Can occur if one of the arguments makes it impossible to satisfy a request (i.e. having alignment larger than the backing buffer of the allocation). - `Mode_Not_Implemented`: The allocator does not support the specified operation. For example, an arena does not support freeing individual allocations.

Allocator_Mode #

Source
Allocator_Mode :: Allocator_Mode

A request to allocator procedure. This type represents a type of allocation request made to an allocator procedure. There is one allocator procedure per allocator, and this value is used to discriminate between different functions of the allocator. The type is defined as follows: Allocator_Mode :: enum byte { Alloc, Alloc_Non_Zeroed, Free, Free_All, Resize, Resize_Non_Zeroed, Query_Features, } Depending on which value is used, the allocator procedure will perform different functions: - `Alloc`: Allocates a memory region with a given `size` and `alignment`. - `Alloc_Non_Zeroed`: Same as `Alloc` without explicit zero-initialization of the memory region. - `Free`: Free a memory region located at address `ptr` with a given `size`. - `Free_All`: Free all memory allocated using this allocator. - `Resize`: Resize a memory region located at address `old_ptr` with size `old_size` to be `size` bytes in length and have the specified `alignment`, in case a re-alllocation occurs. - `Resize_Non_Zeroed`: Same as `Resize`, without explicit zero-initialization.

Allocator_Mode_Set #

Source
Allocator_Mode_Set :: Allocator_Mode_Set

A set of allocator features. This type represents values that contain a set of features an allocator has. Currently the type is defined as follows: Allocator_Mode_Set :: distinct bit_set[Allocator_Mode];

Allocator_Proc #

Source
Allocator_Proc :: Allocator_Proc

The allocator procedure. This type represents allocation procedures. An allocation procedure is a single procedure, implementing all allocator functions such as allocating the memory, freeing the memory, etc. Currently the type is defined as follows: Allocator_Proc :: #type proc( allocator_data: rawptr, mode: Allocator_Mode, size: int, alignment: int, old_memory: rawptr, old_size: int, location: Source_Code_Location = #caller_location, ) -> ([]byte, Allocator_Error); The function of this procedure and the meaning of parameters depends on the value of the `mode` parameter. For any operation the following constraints apply: - The `alignment` must be a power of two. - The `size` must be a positive integer. ## 1. `.Alloc`, `.Alloc_Non_Zeroed` Allocates a memory region of size `size`, aligned on a boundary specified by `alignment`. **Inputs**: - `allocator_data`: Pointer to the allocator data. - `mode`: `.Alloc` or `.Alloc_Non_Zeroed`. - `size`: The desired size of the memory region. - `alignment`: The desired alignmnet of the allocation. - `old_memory`: Unused, should be `nil`. - `old_size`: Unused, should be 0. **Returns**: 1. The memory region, if allocated successfully, or `nil` otherwise. 2. An error, if allocation failed. **Note**: The nil allocator may return `nil`, even if no error is returned. Always check both the error and the allocated buffer. **Note**: The `.Alloc` mode is required to be implemented for an allocator and can not return a `.Mode_Not_Implemented` error. ## 2. `Free` Frees a memory region located at the address specified by `old_memory`. If the allocator does not track sizes of allocations, the size should be specified in the `old_size` parameter. **Inputs**: - `allocator_data`: Pointer to the allocator data. - `mode`: `.Free`. - `size`: Unused, should be 0. - `alignment`: Unused, should be 0. - `old_memory`: Pointer to the memory region to free. - `old_size`: The size of the memory region to free. This parameter is optional if the allocator keeps track of the sizes of allocations. **Returns**: 1. `nil` 2. Error, if freeing failed. ## 3. `Free_All` Frees all allocations, associated with the allocator, making it available for further allocations using the same backing buffers. **Inputs**: - `allocator_data`: Pointer to the allocator data. - `mode`: `.Free_All`. - `size`: Unused, should be 0. - `alignment`: Unused, should be 0. - `old_memory`: Unused, should be `nil`. - `old_size`: Unused, should be `0`. **Returns**: 1. `nil`. 2. Error, if freeing failed. ## 4. `Resize`, `Resize_Non_Zeroed` Resizes the memory region, of the size `old_size` located at the address specified by `old_memory` to have the new size `size`. The slice of the new memory region is returned from the procedure. The allocator may attempt to keep the new memory region at the same address as the previous allocation, however no such guarantee is made. Do not assume the new memory region will be at the same address as the old memory region. If `old_memory` pointer is `nil`, this function acts just like `.Alloc` or `.Alloc_Non_Zeroed`, using `size` and `alignment` to allocate a new memory region. If `new_size` is `nil`, the procedure acts just like `.Free`, freeing the memory region `old_size` bytes in length, located at the address specified by `old_memory`. If the `old_memory` pointer is not aligned to the boundary specified by `alignment`, the procedure relocates the buffer such that the reallocated buffer is aligned to the boundary specified by `alignment`. **Inputs**: - `allocator_data`: Pointer to the allocator data. - `mode`: `.Resize` or `.Resize_All`. - `size`: The desired new size of the memory region. - `alignment`: The alignment of the new memory region, if its allocated - `old_memory`: The pointer to the memory region to resize. - `old_size`: The size of the memory region to resize. If the allocator keeps track of the sizes of allocations, this parameter is optional. **Returns**: 1. The slice of the memory region after resize operation, if successfull, `nil` otherwise. 2. An error, if the resize failed. **Note**: Some allocators may return `nil`, even if no error is returned. Always check both the error and the allocated buffer. **Note**: if `old_size` is `0` and `old_memory` is `nil`, this operation is a no-op, and should not return errors.

Allocator_Query_Info #

Source
Allocator_Query_Info :: Allocator_Query_Info

Allocator information. This type represents information about a given allocator at a specific point in time. Currently the type is defined as follows: Allocator_Query_Info :: struct { pointer: rawptr, size: Maybe(int), alignment: Maybe(int), } - `pointer`: Pointer to a backing buffer. - `size`: Size of the backing buffer. - `alignment`: The allocator's alignment. If not applicable, any of these fields may be `nil`.

Arena_Temp_Memory #

Source
Arena_Temp_Memory :: Arena_Temp_Memory

Temporary memory region of an `Arena` allocator. Temporary memory regions of an arena act as "save-points" for the allocator. When one is created, the subsequent allocations are done inside the temporary memory region. When `end_arena_temp_memory` is called, the arena is rolled back, and all of the memory that was allocated from the arena will be freed. Multiple temporary memory regions can exist at the same time for an arena.

Compat_Allocator #

Source
Compat_Allocator :: Compat_Allocator

An allocator that keeps track of allocation sizes and passes it along to resizes. This is useful if you are using a library that needs an equivalent of `realloc` but want to use the Odin allocator interface. You want to wrap your allocator into this one if you are trying to use any allocator that relies on the old size to work. The overhead of this allocator is an extra max(alignment, size_of(Header)) bytes allocated for each allocation, these bytes are used to store the size and alignment.

Procedures

193

align_backward #

Source
@(require_results)
align_backward :: proc(ptr: rawptr, align: uintptr) -> rawptr {…}

Align rawptr backwards. This procedure returns the previous address before `ptr`, that is located on the alignment boundary specified by `align`. If `ptr` is already aligned to `align` bytes, `ptr` is returned. The specified alignment must be a power of 2.

align_backward_int #

Source
@(require_results)
align_backward_int :: proc(ptr, align: int) -> int {…}

Align int backwards. This procedure returns the previous address before `ptr`, that is located on the alignment boundary specified by `align`. If `ptr` is already aligned to `align` bytes, `ptr` is returned. The specified alignment must be a power of 2.

align_backward_uint #

Source
@(require_results)
align_backward_uint :: proc(ptr, align: uint) -> uint {…}

Align uint backwards. This procedure returns the previous address before `ptr`, that is located on the alignment boundary specified by `align`. If `ptr` is already aligned to `align` bytes, `ptr` is returned. The specified alignment must be a power of 2.

align_backward_uintptr #

Source
@(require_results)
align_backward_uintptr :: proc(ptr, align: uintptr) -> uintptr {…}

Align uintptr backwards. This procedure returns the previous address before `ptr`, that is located on the alignment boundary specified by `align`. If `ptr` is already aligned to `align` bytes, `ptr` is returned. The specified alignment must be a power of 2.

align_formula #

Source
@(require_results)
align_formula :: proc "contextless" (size, align: int) -> int {…}

General-purpose align formula. This procedure is equivalent to `align_forward`, but it does not require the alignment to be a power of two.

align_forward #

Source
@(require_results)
align_forward :: proc(ptr: rawptr, align: uintptr) -> rawptr {…}

Align pointer forward. This procedure returns the next address after `ptr`, that is located on the alignment boundary specified by `align`. If `ptr` is already aligned to `align` bytes, `ptr` is returned. The specified alignment must be a power of 2.

alloc #

Source
@(require_results)
alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory. This function allocates `size` bytes of memory, aligned to a boundary specified by `alignment` using the allocator specified by `allocator`. If the `size` parameter is `0`, the operation is a no-op. **Inputs**: - `size`: The desired size of the allocated memory region. - `alignment`: The desired alignment of the allocated memory region. - `allocator`: The allocator to allocate from. **Returns**: 1. Pointer to the allocated memory, or `nil` if allocation failed. 2. Error, if the allocation failed. **Errors**: - `None`: If no error occurred. - `Out_Of_Memory`: Occurs when the allocator runs out of space in any of its backing buffers, the backing allocator has ran out of space, or an operating system failure occurred. - `Invalid_Argument`: If the supplied `size` is negative, alignment is not a power of two.

alloc_bytes #

Source
@(require_results)
alloc_bytes :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory. This function allocates `size` bytes of memory, aligned to a boundary specified by `alignment` using the allocator specified by `allocator`. **Inputs**: - `size`: The desired size of the allocated memory region. - `alignment`: The desired alignment of the allocated memory region. - `allocator`: The allocator to allocate from. **Returns**: 1. Slice of the allocated memory region, or `nil` if allocation failed. 2. Error, if the allocation failed. **Errors**: - `None`: If no error occurred. - `Out_Of_Memory`: Occurs when the allocator runs out of space in any of its backing buffers, the backing allocator has ran out of space, or an operating system failure occurred. - `Invalid_Argument`: If the supplied `size` is negative, alignment is not a power of two.

alloc_bytes_non_zeroed #

Source
@(require_results)
alloc_bytes_non_zeroed :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate non-zeroed memory. This function allocates `size` bytes of memory, aligned to a boundary specified by `alignment` using the allocator specified by `allocator`. This procedure does not explicitly zero-initialize allocated memory region. **Inputs**: - `size`: The desired size of the allocated memory region. - `alignment`: The desired alignment of the allocated memory region. - `allocator`: The allocator to allocate from. **Returns**: 1. Slice of the allocated memory region, or `nil` if allocation failed. 2. Error, if the allocation failed. **Errors**: - `None`: If no error occurred. - `Out_Of_Memory`: Occurs when the allocator runs out of space in any of its backing buffers, the backing allocator has ran out of space, or an operating system failure occurred. - `Invalid_Argument`: If the supplied `size` is negative, alignment is not a power of two.

any_to_bytes #

Source
@(require_results)
any_to_bytes :: proc "contextless" (val: any) -> []u8 {…}

Obtain the slice, pointing to the contents of `any`. This procedure returns the slice, pointing to the contents of the specified value of the `any` type.

arena_alloc #

Source
@(require_results)
arena_alloc :: proc(a: ^Arena, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from an arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from an arena `a`. The allocated memory is zero-initialized. This procedure returns a pointer to the newly allocated memory region.

arena_alloc_bytes #

Source
@(require_results)
arena_alloc_bytes :: proc(a: ^Arena, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from an arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from an arena `a`. The allocated memory is zero-initialized. This procedure returns a slice of the newly allocated memory region.

arena_alloc_bytes_non_zeroed #

Source
@(require_results)
arena_alloc_bytes_non_zeroed :: proc(a: ^Arena, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate non-initialized memory from an arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from an arena `a`. The allocated memory is not explicitly zero-initialized. This procedure returns a slice of the newly allocated memory region.

arena_alloc_non_zeroed #

Source
@(require_results)
arena_alloc_non_zeroed :: proc(a: ^Arena, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate non-initialized memory from an arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from an arena `a`. The allocated memory is not explicitly zero-initialized. This procedure returns a pointer to the newly allocated memory region.

arena_allocator #

Source
@(require_results)
arena_allocator :: proc(arena: ^Arena) -> Allocator {…}

Arena allocator. The arena allocator (also known as a linear allocator, bump allocator, region allocator) is an allocator that uses a single backing buffer for allocations. The buffer is used contiguously, from start to end. Each subsequent allocation occupies the next adjacent region of memory in the buffer. Since the arena allocator does not keep track of any metadata associated with the allocations and their locations, it is impossible to free individual allocations. The arena allocator can be used for temporary allocations in frame-based memory management. Games are one example of such applications. A global arena can be used for any temporary memory allocations, and at the end of each frame all temporary allocations are freed. Since no temporary object is going to live longer than a frame, no lifetimes are violated.

arena_free_all #

Source
arena_free_all :: proc(a: ^Arena) {…}

Free all memory back to the arena allocator.

arena_init #

Source
arena_init :: proc(a: ^Arena, data: []u8) {…}

Initialize an arena. This procedure initializes the arena `a` with memory region `data` as its backing buffer.

begin_arena_temp_memory #

Source
@(require_results)
begin_arena_temp_memory :: proc(a: ^Arena) -> Arena_Temp_Memory {…}

Start a temporary memory region. This procedure creates a temporary memory region. After a temporary memory region is created, all allocations are said to be *inside* the temporary memory region, until `end_arena_temp_memory` is called.

buddy_allocator #

Source
@(require_results)
buddy_allocator :: proc(b: ^Buddy_Allocator) -> Allocator {…}

Buddy allocator. The buddy allocator is a type of allocator that splits the backing buffer into multiple regions called buddy blocks. Initially, the allocator only has one block with the size of the backing buffer. Upon each allocation, the allocator finds the smallest block that can fit the size of requested memory region, and splits the block according to the allocation size. If no block can be found, the contiguous free blocks are coalesced and the search is performed again.

buddy_allocator_alloc #

Source
@(require_results)
@(no_sanitize_address)
buddy_allocator_alloc :: proc(b: ^Buddy_Allocator, size: uint) -> (rawptr, Allocator_Error) {…}

Allocate memory from a buddy allocator. This procedure allocates `size` bytes of memory. The allocation's alignment is fixed to the `alignment` specified at initialization. The allocated memory region is zero-initialized. This procedure returns a pointer to the allocated memory region.

buddy_allocator_alloc_bytes #

Source
@(require_results)
@(no_sanitize_address)
buddy_allocator_alloc_bytes :: proc(b: ^Buddy_Allocator, size: uint) -> ([]u8, Allocator_Error) {…}

Allocate memory from a buddy allocator. This procedure allocates `size` bytes of memory. The allocation's alignment is fixed to the `alignment` specified at initialization. The allocated memory region is zero-initialized. This procedure returns a slice of the allocated memory region.

buddy_allocator_alloc_bytes_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
buddy_allocator_alloc_bytes_non_zeroed :: proc(b: ^Buddy_Allocator, size: uint) -> ([]u8, Allocator_Error) {…}

Allocate non-initialized memory from a buddy allocator. This procedure allocates `size` bytes of memory. The allocation's alignment is fixed to the `alignment` specified at initialization. The allocated memory region is not explicitly zero-initialized. This procedure returns a slice of the allocated memory region.

buddy_allocator_alloc_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
buddy_allocator_alloc_non_zeroed :: proc(b: ^Buddy_Allocator, size: uint) -> (rawptr, Allocator_Error) {…}

Allocate non-initialized memory from a buddy allocator. This procedure allocates `size` bytes of memory. The allocation's alignment is fixed to the `alignment` specified at initialization. The allocated memory region is not explicitly zero-initialized. This procedure returns a pointer to the allocated memory region.

buddy_allocator_free #

Source
@(no_sanitize_address)
buddy_allocator_free :: proc(b: ^Buddy_Allocator, ptr: rawptr) -> Allocator_Error {…}

Free memory back to the buddy allocator. This procedure frees the memory region allocated at pointer `ptr`. If `ptr` is not the latest allocation and is not a leaked allocation, this operation is a no-op.

buddy_allocator_free_all #

Source
@(no_sanitize_address)
buddy_allocator_free_all :: proc(b: ^Buddy_Allocator) {…}

Free all memory back to the buddy allocator.

buddy_allocator_init #

Source
buddy_allocator_init :: proc(b: ^Buddy_Allocator, data: []u8, alignment: uint, loc := #caller_location) {…}

Initialize a buddy allocator. This procedure initializes the buddy allocator `b` with a backing buffer `data` and block alignment specified by `alignment`. `alignment` may be any power of two, but the backing buffer must be aligned to at least `size_of(Buddy_Block)`.

buddy_block_coalescence #

Source
@(no_sanitize_address)
buddy_block_coalescence :: proc(head, tail: ^Buddy_Block) {…}

Coalesce contiguous blocks in a range of blocks into one.

buddy_block_find_best #

Source
@(require_results)
@(no_sanitize_address)
buddy_block_find_best :: proc(head, tail: ^Buddy_Block, size: uint) -> ^Buddy_Block {…}

Find the best block for storing a given size in a range of blocks.

buddy_block_size_required #

Source
@(require_results)
buddy_block_size_required :: proc(b: ^Buddy_Allocator, size: uint) -> uint {…}

Get required block size to fit in the allocation as well as the alignment padding.

buddy_block_split #

Source
@(require_results)
@(no_sanitize_address)
buddy_block_split :: proc(block: ^Buddy_Block, size: uint) -> ^Buddy_Block {…}

Split the block into two, by truncating the given block to a given size.

buffer_from_slice #

Source
@(require_results)
buffer_from_slice :: proc "contextless" (backing: $T/[]$E) -> $$deferred_return {…}

Create a dynamic array from slice. This procedure creates a dynamic array, using slice `backing` as the backing buffer for the dynamic array. The resulting dynamic array can not grow beyond the size of the specified slice.

byte_slice #

Source
@(require_results)
byte_slice :: proc "contextless" (data: rawptr, len: int) -> []u8 {…}

Construct a byte slice from raw pointer and length. This procedure creates a byte slice, that points to `len` amount of bytes located at an address specified by `data`.

calc_padding_with_header #

Source
@(require_results)
calc_padding_with_header :: proc "contextless" (ptr: uintptr, align: uintptr, header_size: int) -> int {…}

Calculate the padding for header preceding aligned data. This procedure returns the padding, following the specified pointer `ptr` that will be able to fit in a header of the size `header_size`, immediately preceding the memory region, aligned on a boundary specified by `align`. See the following diagram for a visual representation. header size |<------>| +---+--------+------------- - - - | HEADER | DATA... +---+--------+------------- - - - ^ ^ |<---------->| | padding | ptr aligned ptr The function takes in `ptr` and `header_size`, as well as the required alignment for `DATA`. The return value of the function is the padding between `ptr` and `aligned_ptr` that will be able to fit the header.

check_zero #

Source
@(require_results)
check_zero :: proc(data: []u8) -> bool {…}

Check if the memory range defined by a slice is zero-filled. This procedure checks whether every byte, pointed to by the slice, specified by the parameter `data`, is zero. If all bytes of the slice are zero, this procedure returns `true`. Otherwise this procedure returns `false`.

check_zero_ptr #

Source
@(require_results)
check_zero_ptr :: proc(ptr: rawptr, len: int) -> bool {…}

Check if the memory range defined defined by a pointer is zero-filled. This procedure checks whether each of the `len` bytes, starting at address `ptr` is zero. If all bytes of this range are zero, this procedure returns `true`. Otherwise this procedure returns `false`.

compare #

Source
@(require_results)
compare :: proc "contextless" (a, b: []u8) -> int {…}

Compare two memory ranges defined by slices. This procedure performs a byte-by-byte comparison between memory ranges specified by slices `a` and `b`, and returns a value, specifying their relative ordering. If the return value is: - Equal to `-1`, then `a` is "smaller" than `b`. - Equal to `+1`, then `a` is "bigger" than `b`. - Equal to `0`, then `a` and `b` are equal. The comparison is performed as follows: 1. Each byte, upto `min(len(a), len(b))` bytes is compared between `a` and `b`. - If the byte in slice `a` is smaller than a byte in slice `b`, then comparison stops and this procedure returns `-1`. - If the byte in slice `a` is bigger than a byte in slice `b`, then comparison stops and this procedure returns `+1`. - Otherwise the comparison continues until `min(len(a), len(b))` are compared. 2. If all the bytes in the range are equal, then the lengths of the slices are compared. - If the length of slice `a` is smaller than the length of slice `b`, then `-1` is returned. - If the length of slice `b` is smaller than the length of slice `b`, then `+1` is returned. - Otherwise `0` is returned.

compare_byte_ptrs #

Source
@(require_results)
compare_byte_ptrs :: proc "contextless" (a, b: ^u8, n: int) -> int {…}

Compare two memory ranges defined by byte pointers. This procedure performs a byte-by-byte comparison between memory ranges of size `n` located at addresses `a` and `b`, and returns a value, specifying their relative ordering. If the return value is: - Equal to `-1`, then `a` is "smaller" than `b`. - Equal to `+1`, then `a` is "bigger" than `b`. - Equal to `0`, then `a` and `b` are equal. The comparison is performed as follows: 1. Each byte, upto `n` bytes is compared between `a` and `b`. - If the byte in `a` is smaller than a byte in `b`, then comparison stops and this procedure returns `-1`. - If the byte in `a` is bigger than a byte in `b`, then comparison stops and this procedure returns `+1`. - Otherwise the comparison continues until `n` bytes are compared. 2. If all the bytes in the range are equal, this procedure returns `0`.

compare_ptrs #

Source
@(require_results)
compare_ptrs :: proc "contextless" (a, b: rawptr, n: int) -> int {…}

Compare two memory ranges defined by pointers. This procedure performs a byte-by-byte comparison between memory ranges of size `n` located at addresses `a` and `b`, and returns a value, specifying their relative ordering. If the return value is: - Equal to `-1`, then `a` is "smaller" than `b`. - Equal to `+1`, then `a` is "bigger" than `b`. - Equal to `0`, then `a` and `b` are equal. The comparison is performed as follows: 1. Each byte, upto `n` bytes is compared between `a` and `b`. - If the byte in `a` is smaller than a byte in `b`, then comparison stops and this procedure returns `-1`. - If the byte in `a` is bigger than a byte in `b`, then comparison stops and this procedure returns `+1`. - Otherwise the comparison continues until `n` bytes are compared. 2. If all the bytes in the range are equal, this procedure returns `0`.

context_from_allocator #

Source
@(require_results)
context_from_allocator :: proc(a: Allocator) -> Context {…}

Create a context with a given allocator. This procedure returns a copy of the current context with the allocator replaced by the allocator `a`.

copy #

Source
copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {…}

Copy bytes from one memory range to another. This procedure copies `len` bytes of data, from the memory range pointed to by the `src` pointer into the memory range pointed to by the `dst` pointer, and returns the `dst` pointer.

copy_non_overlapping #

Source
copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {…}

Copy bytes between two non-overlapping memory ranges. This procedure copies `len` bytes of data, from the memory range pointed to by the `src` pointer into the memory range pointed to by the `dst` pointer, and returns the `dst` pointer. This is a slightly more optimized version of the `copy` procedure that requires that memory ranges specified by the parameters to this procedure are not overlapping. If the memory ranges specified by `dst` and `src` pointers overlap, the behavior of this function may be unpredictable.

default_resize_align #

Source
@(require_results)
default_resize_align :: proc(
	old_memory: rawptr, 
	old_size:   int, 
	new_size:   int, 
	alignment:  int, 
	allocator := context.allocator, 
	loc := #caller_location, 
) -> (res: rawptr, err: Allocator_Error) {…}

Default resize procedure. When allocator does not support resize operation, but supports `.Alloc` and `.Free`, this procedure is used to implement allocator's default behavior on resize. The behavior of the function is as follows: - If `new_size` is `0`, the function acts like `free()`, freeing the memory region of `old_size` bytes located at `old_memory`. - If `old_memory` is `nil`, the function acts like `alloc()`, allocating `new_size` bytes of memory aligned on a boundary specified by `alignment`. - Otherwise, a new memory region of size `new_size` is allocated, then the data from the old memory region is copied and the old memory region is freed.

default_resize_bytes_align #

Source
@(require_results)
default_resize_bytes_align :: proc(old_data: []u8, new_size: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Default resize procedure. When allocator does not support resize operation, but supports `.Alloc` and `.Free`, this procedure is used to implement allocator's default behavior on resize. The behavior of the function is as follows: - If `new_size` is `0`, the function acts like `free()`, freeing the memory region specified by `old_data`. - If `old_data` is `nil`, the function acts like `alloc()`, allocating `new_size` bytes of memory aligned on a boundary specified by `alignment`. - Otherwise, a new memory region of size `new_size` is allocated, then the data from the old memory region is copied and the old memory region is freed.

default_resize_bytes_align_non_zeroed #

Source
@(require_results)
default_resize_bytes_align_non_zeroed :: proc(old_data: []u8, new_size: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Default resize procedure. When allocator does not support resize operation, but supports `.Alloc_Non_Zeroed` and `.Free`, this procedure is used to implement allocator's default behavior on resize. Unlike `default_resize_align` no new memory is being explicitly zero-initialized. The behavior of the function is as follows: - If `new_size` is `0`, the function acts like `free()`, freeing the memory region of `old_size` bytes located at `old_memory`. - If `old_memory` is `nil`, the function acts like `alloc()`, allocating `new_size` bytes of memory aligned on a boundary specified by `alignment`. - Otherwise, a new memory region of size `new_size` is allocated, then the data from the old memory region is copied and the old memory region is freed.

delete_dynamic_array #

Source
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) -> Allocator_Error {…}

Free a dynamic array.

delete_slice #

Source
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

Free a slice.

delete_soa_dynamic_array #

Source
delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) -> Allocator_Error {…}

Free an SoA dynamic array.

delete_soa_slice #

Source
delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

Free an SoA slice.

dynamic_arena_alloc #

Source
@(require_results)
dynamic_arena_alloc :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a dynamic arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from a dynamic arena `a`. The allocated memory is zero-initialized. This procedure returns a pointer to the newly allocated memory region.

dynamic_arena_alloc_bytes #

Source
@(require_results)
dynamic_arena_alloc_bytes :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a dynamic arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from a dynamic arena `a`. The allocated memory is zero-initialized. This procedure returns a slice of the newly allocated memory region.

dynamic_arena_alloc_bytes_non_zeroed #

Source
@(require_results)
dynamic_arena_alloc_bytes_non_zeroed :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate non-initialized memory from a dynamic arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from a dynamic arena `a`. The allocated memory is not explicitly zero-initialized. This procedure returns a slice of the newly allocated memory region.

dynamic_arena_alloc_non_zeroed #

Source
@(require_results)
dynamic_arena_alloc_non_zeroed :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate non-initialized memory from a dynamic arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from a dynamic arena `a`. The allocated memory is not explicitly zero-initialized. This procedure returns a pointer to the newly allocated memory region.

dynamic_arena_allocator #

Source
@(require_results)
dynamic_arena_allocator :: proc(a: ^Dynamic_Arena) -> Allocator {…}

Dynamic arena allocator. The dynamic arena allocator uses blocks of a specific size, allocated on-demand using the block allocator. This allocator acts similarly to `Arena`. All allocations in a block happen contiguously, from start to end. If an allocation does not fit into the remaining space of the block and its size is smaller than the specified out-band size, a new block is allocated using the `block_allocator` and the allocation is performed from a newly-allocated block. If an allocation is larger than the specified out-band size, a new block is allocated such that the allocation fits into this new block. This is referred to as an *out-band allocation*. The out-band blocks are kept separately from normal blocks. Just like `Arena`, the dynamic arena does not support freeing of individual objects.

dynamic_arena_destroy #

Source
dynamic_arena_destroy :: proc(a: ^Dynamic_Arena) {…}

Destroy a dynamic arena. This procedure frees all allocations made on a dynamic arena, including the unused blocks, as well as the arrays for storing blocks.

dynamic_arena_free_all #

Source
dynamic_arena_free_all :: proc(a: ^Dynamic_Arena, loc := #caller_location) {…}

Free all memory back to the dynamic arena allocator. This procedure frees all the allocations owned by the dynamic arena, including the unused blocks.

dynamic_arena_init #

Source
dynamic_arena_init :: proc(
	pool:            ^Dynamic_Arena, 
	block_allocator := context.allocator, 
	array_allocator := context.allocator, 
	block_size:      int = DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT, 
	out_band_size:   int = DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT, 
	alignment:       int = DEFAULT_ALIGNMENT, 
) {…}

Initialize a dynamic arena. This procedure initializes a dynamic arena. The specified `block_allocator` will be used to allocate arena blocks, and `array_allocator` to allocate arrays of blocks and out-band blocks. The blocks have the default size of `block_size` and out-band threshold will be `out_band_size`. All allocations will be aligned to a boundary specified by `alignment`.

dynamic_arena_reset #

Source
dynamic_arena_reset :: proc(a: ^Dynamic_Arena, loc := #caller_location) {…}

Reset a dynamic arena allocator. This procedure frees all the allocations owned by the dynamic arena, excluding the unused blocks.

dynamic_arena_resize #

Source
@(require_results)
dynamic_arena_resize :: proc(a: ^Dynamic_Arena, old_memory: rawptr, old_size: int, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a dynamic arena allocator. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `dynamic_arena_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. This procedure returns the pointer to the resized memory region.

dynamic_arena_resize_bytes #

Source
@(require_results)
dynamic_arena_resize_bytes :: proc(a: ^Dynamic_Arena, old_data: []u8, size: int, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a dynamic arena allocator. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `dynamic_arena_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. This procedure returns the slice of the resized memory region.

dynamic_arena_resize_bytes_non_zeroed #

Source
@(require_results)
dynamic_arena_resize_bytes_non_zeroed :: proc(a: ^Dynamic_Arena, old_data: []u8, size: int, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a dynamic arena allocator, without zero-initialization. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `dynamic_arena_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. This procedure returns the slice of the resized memory region.

dynamic_arena_resize_non_zeroed #

Source
@(require_results)
dynamic_arena_resize_non_zeroed :: proc(a: ^Dynamic_Arena, old_memory: rawptr, old_size: int, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a dynamic arena allocator, without zero-initialization. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `dynamic_arena_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. This procedure returns the pointer to the resized memory region.

dynamic_pool_alloc #

Source
@(require_results)
dynamic_pool_alloc :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a dynamic arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from a dynamic arena `a`. The allocated memory is zero-initialized. This procedure returns a pointer to the newly allocated memory region.

dynamic_pool_alloc_bytes #

Source
@(require_results)
dynamic_pool_alloc_bytes :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a dynamic arena. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment` from a dynamic arena `a`. The allocated memory is zero-initialized. This procedure returns a slice of the newly allocated memory region.

dynamic_pool_allocator #

Source
@(require_results)
dynamic_pool_allocator :: proc(a: ^Dynamic_Arena) -> Allocator {…}

Dynamic arena allocator. The dynamic arena allocator uses blocks of a specific size, allocated on-demand using the block allocator. This allocator acts similarly to `Arena`. All allocations in a block happen contiguously, from start to end. If an allocation does not fit into the remaining space of the block and its size is smaller than the specified out-band size, a new block is allocated using the `block_allocator` and the allocation is performed from a newly-allocated block. If an allocation is larger than the specified out-band size, a new block is allocated such that the allocation fits into this new block. This is referred to as an *out-band allocation*. The out-band blocks are kept separately from normal blocks. Just like `Arena`, the dynamic arena does not support freeing of individual objects.

dynamic_pool_destroy #

Source
dynamic_pool_destroy :: proc(a: ^Dynamic_Arena) {…}

Destroy a dynamic arena. This procedure frees all allocations made on a dynamic arena, including the unused blocks, as well as the arrays for storing blocks.

dynamic_pool_free_all #

Source
dynamic_pool_free_all :: proc(a: ^Dynamic_Arena, loc := #caller_location) {…}

Free all memory back to the dynamic arena allocator. This procedure frees all the allocations owned by the dynamic arena, including the unused blocks.

dynamic_pool_init #

Source
dynamic_pool_init :: proc(
	pool:            ^Dynamic_Arena, 
	block_allocator := context.allocator, 
	array_allocator := context.allocator, 
	block_size:      int = DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT, 
	out_band_size:   int = DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT, 
	alignment:       int = DEFAULT_ALIGNMENT, 
) {…}

Initialize a dynamic arena. This procedure initializes a dynamic arena. The specified `block_allocator` will be used to allocate arena blocks, and `array_allocator` to allocate arrays of blocks and out-band blocks. The blocks have the default size of `block_size` and out-band threshold will be `out_band_size`. All allocations will be aligned to a boundary specified by `alignment`.

dynamic_pool_reset #

Source
dynamic_pool_reset :: proc(a: ^Dynamic_Arena, loc := #caller_location) {…}

Reset a dynamic arena allocator. This procedure frees all the allocations owned by the dynamic arena, excluding the unused blocks.

end_arena_temp_memory #

Source
end_arena_temp_memory :: proc(tmp: Arena_Temp_Memory) {…}

End a temporary memory region. This procedure ends the temporary memory region for an arena. All of the allocations *inside* the temporary memory region will be freed to the arena.

free #

Source
free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

Free memory. This procedure frees memory region located at the address, specified by `ptr`, allocated from the allocator specified by `allocator`. **Inputs**: - `ptr`: Pointer to the memory region to free. - `allocator`: The allocator to free to. **Returns**: - The error, if freeing failed. **Errors**: - `None`: When no error has occurred. - `Invalid_Pointer`: The specified pointer is not owned by the specified allocator, or does not point to a valid allocation. - `Mode_Not_Implemented`: If the specified allocator does not support the `.Free` mode.

free_all #

Source
free_all :: proc(allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

Free all allocations. This procedure frees all allocations made on the allocator specified by `allocator` to that allocator, making it available for further allocations. **Inputs**: - `allocator`: The allocator to free to. **Errors**: - `None`: When no error has occurred. - `Mode_Not_Implemented`: If the specified allocator does not support the `.Free` mode.

free_bytes #

Source
free_bytes :: proc(bytes: []u8, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

Free a memory region. This procedure frees memory region, specified by `bytes`, allocated from the allocator specified by `allocator`. If the length of the specified slice is zero, the `.Invalid_Argument` error is returned. **Inputs**: - `bytes`: The memory region to free. - `allocator`: The allocator to free to. **Returns**: - The error, if freeing failed. **Errors**: - `None`: When no error has occurred. - `Invalid_Pointer`: The specified pointer is not owned by the specified allocator, or does not point to a valid allocation. - `Mode_Not_Implemented`: If the specified allocator does not support the `.Free` mode.

free_with_size #

Source
free_with_size :: proc(ptr: rawptr, size: int, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {…}

Free a memory region. This procedure frees `size` bytes of memory region located at the address, specified by `ptr`, allocated from the allocator specified by `allocator`. If the `size` parameter is `0`, this call is equivalent to `free()`. **Inputs**: - `ptr`: Pointer to the memory region to free. - `size`: The size of the memory region to free. - `allocator`: The allocator to free to. **Returns**: - The error, if freeing failed. **Errors**: - `None`: When no error has occurred. - `Invalid_Pointer`: The specified pointer is not owned by the specified allocator, or does not point to a valid allocation. - `Mode_Not_Implemented`: If the specified allocator does not support the `.Free` mode.

is_aligned #

Source
is_aligned :: proc "contextless" (x: rawptr, align: int) -> bool {…}

Check if a pointer is aligned. This procedure checks whether a pointer `x` is aligned to a boundary specified by `align`, and returns `true` if the pointer is aligned, and false otherwise. The specified alignment must be a power of 2.

make_aligned #

Source
@(require_results)
make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (slice: $$deferred_return, err: Allocator_Error) {…}

Allocate a new slice with alignment. This procedure allocates a new slice of type `T` with length `len`, aligned on a boundary specified by `alignment` from an allocator specified by `allocator`, and returns the allocated slice.

make_any #

Source
make_any :: proc "contextless" (data: rawptr, id: typeid) -> any {…}

Create a value of the any type. This procedure creates a value with type `any` that points to an object with typeid `id` located at an address specified by `data`.

make_dynamic_array #

Source
@(require_results)
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> ($$deferred_return, Allocator_Error) {…}

Allocate a dynamic array. This procedure creates a dynamic array of type `T`, with `allocator` as its backing allocator, and initial length and capacity of `0`.

make_dynamic_array_len #

Source
@(require_results)
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> ($$deferred_return, Allocator_Error) {…}

Allocate a dynamic array with initial length. This procedure creates a dynamic array of type `T`, with `allocator` as its backing allocator, and initial capacity and length specified by `len`.

make_dynamic_array_len_cap #

Source
@(require_results)
make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

Allocate a dynamic array with initial length and capacity. This procedure creates a dynamic array of type `T`, with `allocator` as its backing allocator, and initial capacity specified by `cap`, and initial length specified by `len`.

make_map #

Source
@(require_results)
make_map :: proc($T: typeid/map[$K]$E, allocator := context.allocator, loc := #caller_location) -> (m: $$deferred_return) {…}

Create a map with no initial allocation. This procedure creates a map of type `T` with no initial allocation, which will use the allocator specified by `allocator` as its backing allocator when it allocates.

make_map_cap #

Source
@(require_results)
make_map_cap :: proc($T: typeid/map[$K]$E, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (m: $$deferred_return, err: Allocator_Error) {…}

Allocate a map. This procedure creates a map of type `T` with initial capacity specified by `cap`, that is using an allocator specified by `allocator` as its backing allocator.

make_multi_pointer #

Source
@(require_results)
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: $$deferred_return, err: Allocator_Error) {…}

Allocate a multi pointer. This procedure allocates a multipointer of type `T` pointing to `len` elements, from an allocator specified by `allocator`.

make_over_aligned #

Source
@(require_results)
make_over_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator: Allocator, loc := #caller_location) -> (slice: $$deferred_return, original_data: []u8, err: Allocator_Error) {…}

Allocate a new slice with alignment for allocators that might not support the specified alignment requirement. This procedure allocates a new slice of type `T` with length `len`, aligned on a boundary specified by `alignment` from an allocator specified by `allocator`, and returns the allocated slice. The user should `delete` the return `original_data` slice not the typed `slice`.

make_slice #

Source
@(require_results)
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> ($$deferred_return, Allocator_Error) {…}

Allocate a new slice. This procedure allocates a new slice of type `T` with length `len`, from an allocator specified by `allocator`, and returns the allocated slice.

make_soa_dynamic_array #

Source
@(require_results)
make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

Allocate an SoA dynamic array. This procedure creates an SoA dynamic array of type `T`, with `allocator` as its backing allocator, and initial length and capacity of `0`.

make_soa_dynamic_array_len #

Source
@(require_results)
make_soa_dynamic_array_len :: proc($T: typeid/#soa[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

Allocate an SoA dynamic array with initial length. This procedure creates an SoA dynamic array of type `T`, with `allocator` as its backing allocator, and initial capacity and length specified by `len`.

make_soa_dynamic_array_len_cap #

Source
@(require_results)
make_soa_dynamic_array_len_cap :: proc($T: typeid/#soa[dynamic]$E, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

Allocate an SoA dynamic array with initial length and capacity. This procedure creates an SoA dynamic array of type `T`, with `allocator` as its backing allocator, and initial capacity specified by `cap`, and initial length specified by `len`.

make_soa_slice #

Source
@(require_results)
make_soa_slice :: proc($T: typeid/#soa[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (array: $$deferred_return, err: Allocator_Error) {…}

Allocate an SoA slice. This procedure allocates an SoA slice of type `T` with length `len`, from an allocator specified by `allocator`, and returns the allocated SoA slice.

mutex_allocator #

Source
@(require_results)
mutex_allocator :: proc(m: ^Mutex_Allocator) -> Allocator {…}

Mutex allocator. The mutex allocator is a wrapper for allocators that is used to serialize all allocator requests across multiple threads.

mutex_allocator_init #

Source
mutex_allocator_init :: proc(m: ^Mutex_Allocator, backing_allocator: Allocator) {…}

Initialize the mutex allocator. This procedure initializes the mutex allocator using `backin_allocator` as the allocator that will be used to pass all allocation requests through.

new #

Source
@(require_results)
new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> (^typeid, Allocator_Error) {…}

Allocate a new object. This procedure allocates a new object of type `T` using an allocator specified by `allocator`, and returns a pointer to the allocated object, if allocated successfully, or `nil` otherwise.

new_aligned #

Source
@(require_results)
new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> (t: ^typeid, err: Allocator_Error) {…}

Allocate a new object with alignment. This procedure allocates a new object of type `T` using an allocator specified by `allocator`, and returns a pointer, aligned on a boundary specified by `alignment` to the allocated object, if allocated successfully, or `nil` otherwise.

new_clone #

Source
@(require_results)
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: $$deferred_return, err: Allocator_Error) {…}

Allocate a new object and initialize it with a value. This procedure allocates a new object of type `T` using an allocator specified by `allocator`, and returns a pointer, aligned on a boundary specified by `alignment` to the allocated object, if allocated successfully, or `nil` otherwise. The allocated object is initialized with `data`.

nil_allocator #

Source
@(require_results)
nil_allocator :: proc() -> Allocator {…}

Nil allocator. The `nil` allocator returns `nil` on every allocation attempt. This type of allocator can be used in scenarios where memory doesn't need to be allocated, but an attempt to allocate memory is not an error.

panic_allocator #

Source
@(require_results)
panic_allocator :: proc() -> Allocator {…}

Panic allocator. The panic allocator is a type of allocator that panics on any allocation attempt. This type of allocator can be used in scenarios where memory should not be allocated, and an attempt to allocate memory is an error.

ptr_offset #

Source
ptr_offset :: invalid type {…}

Offset a given pointer by a given amount. This procedure offsets the pointer `ptr` to an object of type `T`, by the amount of bytes specified by `offset * size_of(T)`, and returns the pointer `ptr`. **Note**: Prefer to use multipointer types, if possible.

ptr_sub #

Source
ptr_sub :: invalid type {…}

Subtract two pointers of the same type, and return the number of `T` between them. This procedure subtracts pointer `b` from pointer `a`, both of type `^T`, and returns an integer count of the `T` between them. **Inputs** - `a`: A pointer to a type T - `b`: A pointer to a type T **Returns** - `a` - `b` in items of T as an `int`. Example: import "core:mem" import "core:fmt" ptr_sub_example :: proc() { arr: [2]int fmt.println(mem.ptr_sub(&arr[1], &arr[0])) } Output: 1

ptr_to_bytes #

Source
@(require_results)
ptr_to_bytes :: proc "contextless" (ptr: ^$T, len: int = 1) -> []u8 {…}

Create a byte slice from pointer and length. This procedure creates a byte slice, pointing to `len` objects, starting from the address specified by `ptr`.

raw_data #

Source
raw_data :: invalid type {…}

Obtain pointer to the data. This procedure returns the pointer to the data of a slice, string, or a dynamic array.

rb_alloc_bytes #

Source
@(require_results)
@(no_sanitize_address)
rb_alloc_bytes :: proc(stack: ^Rollback_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory using the rollback stack allocator.

rb_alloc_bytes_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
rb_alloc_bytes_non_zeroed :: proc(stack: ^Rollback_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (result: []u8, err: Allocator_Error) {…}

Allocate non-initialized memory using the rollback stack allocator.

rb_alloc_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
rb_alloc_non_zeroed :: proc(stack: ^Rollback_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate non-initialized memory using the rollback stack allocator.

rb_resize_bytes #

Source
@(require_results)
@(no_sanitize_address)
rb_resize_bytes :: proc(stack: ^Rollback_Stack, old_memory: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by rollback stack allocator.

rb_resize_bytes_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
rb_resize_bytes_non_zeroed :: proc(stack: ^Rollback_Stack, old_memory: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (result: []u8, err: Allocator_Error) {…}

Resize an allocation owned by rollback stack allocator without explicit zero-initialization.

rb_resize_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
rb_resize_non_zeroed :: proc(
	stack:     ^Rollback_Stack, 
	old_ptr:   rawptr, 
	old_size:  int, 
	size:      int, 
	alignment: int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by rollback stack allocator without explicit zero-initialization.

reinterpret_copy #

Source
@(require_results)
reinterpret_copy :: proc "contextless" ($T: typeid, ptr: rawptr) -> (value: typeid) {…}

Copy the value from a pointer into a value. This procedure copies the object of type `T` pointed to by the pointer `ptr` into a new stack-allocated value and returns that value.

resize #

Source
@(require_results)
resize :: proc(
	ptr:       rawptr, 
	old_size:  int, 
	new_size:  int, 
	alignment: int = DEFAULT_ALIGNMENT, 
	allocator := context.allocator, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize a memory region. This procedure resizes a memory region, `old_size` bytes in size, located at the address specified by `ptr`, such that it has a new size, specified by `new_size` and and is aligned on a boundary specified by `alignment`. If the `ptr` parameter is `nil`, `resize()` acts just like `alloc()`, allocating `new_size` bytes, aligned on a boundary specified by `alignment`. If the `new_size` parameter is `0`, `resize()` acts just like `free()`, freeing the memory region `old_size` bytes in length, located at the address specified by `ptr`. If the `old_memory` pointer is not aligned to the boundary specified by `alignment`, the procedure relocates the buffer such that the reallocated buffer is aligned to the boundary specified by `alignment`. **Inputs**: - `ptr`: Pointer to the memory region to resize. - `old_size`: Size of the memory region to resize. - `new_size`: The desired size of the resized memory region. - `alignment`: The desired alignment of the resized memory region. - `allocator`: The owner of the memory region to resize. **Returns**: 1. The pointer to the resized memory region, if successfull, `nil` otherwise. 2. Error, if resize failed. **Errors**: - `None`: No error. - `Out_Of_Memory`: When the allocator's backing buffer or it's backing allocator does not have enough space to fit in an allocation with the new size, or an operating system failure occurs. - `Invalid_Pointer`: The pointer referring to a memory region does not belong to any of the allocators backing buffers or does not point to a valid start of an allocation made in that allocator. - `Invalid_Argument`: When `size` is negative, alignment is not a power of two, or the `old_size` argument is incorrect. - `Mode_Not_Implemented`: The allocator does not support the `.Realloc` mode. **Note**: if `old_size` is `0` and `old_memory` is `nil`, this operation is a no-op, and should not return errors.

resize_bytes #

Source
@(require_results)
resize_bytes :: proc(old_data: []u8, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize a memory region. This procedure resizes a memory region, specified by `old_data`, such that it has a new size, specified by `new_size` and and is aligned on a boundary specified by `alignment`. If the `old_data` parameter is `nil`, `resize_bytes()` acts just like `alloc_bytes()`, allocating `new_size` bytes, aligned on a boundary specified by `alignment`. If the `new_size` parameter is `0`, `resize_bytes()` acts just like `free_bytes()`, freeing the memory region specified by `old_data`. If the `old_memory` pointer is not aligned to the boundary specified by `alignment`, the procedure relocates the buffer such that the reallocated buffer is aligned to the boundary specified by `alignment`. **Inputs**: - `old_data`: Pointer to the memory region to resize. - `new_size`: The desired size of the resized memory region. - `alignment`: The desired alignment of the resized memory region. - `allocator`: The owner of the memory region to resize. **Returns**: 1. The resized memory region, if successfull, `nil` otherwise. 2. Error, if resize failed. **Errors**: - `None`: No error. - `Out_Of_Memory`: When the allocator's backing buffer or it's backing allocator does not have enough space to fit in an allocation with the new size, or an operating system failure occurs. - `Invalid_Pointer`: The pointer referring to a memory region does not belong to any of the allocators backing buffers or does not point to a valid start of an allocation made in that allocator. - `Invalid_Argument`: When `size` is negative, alignment is not a power of two, or the `old_size` argument is incorrect. - `Mode_Not_Implemented`: The allocator does not support the `.Realloc` mode. **Note**: if `old_size` is `0` and `old_memory` is `nil`, this operation is a no-op, and should not return errors.

resize_bytes_non_zeroed #

Source
@(require_results)
resize_bytes_non_zeroed :: proc(old_data: []u8, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize a memory region. This procedure resizes a memory region, specified by `old_data`, such that it has a new size, specified by `new_size` and and is aligned on a boundary specified by `alignment`. If the `old_data` parameter is `nil`, `resize_bytes()` acts just like `alloc_bytes()`, allocating `new_size` bytes, aligned on a boundary specified by `alignment`. If the `new_size` parameter is `0`, `resize_bytes()` acts just like `free_bytes()`, freeing the memory region specified by `old_data`. If the `old_memory` pointer is not aligned to the boundary specified by `alignment`, the procedure relocates the buffer such that the reallocated buffer is aligned to the boundary specified by `alignment`. Unlike `resize_bytes()`, this procedure does not explicitly zero-initialize any new memory. **Inputs**: - `old_data`: Pointer to the memory region to resize. - `new_size`: The desired size of the resized memory region. - `alignment`: The desired alignment of the resized memory region. - `allocator`: The owner of the memory region to resize. **Returns**: 1. The resized memory region, if successfull, `nil` otherwise. 2. Error, if resize failed. **Errors**: - `None`: No error. - `Out_Of_Memory`: When the allocator's backing buffer or it's backing allocator does not have enough space to fit in an allocation with the new size, or an operating system failure occurs. - `Invalid_Pointer`: The pointer referring to a memory region does not belong to any of the allocators backing buffers or does not point to a valid start of an allocation made in that allocator. - `Invalid_Argument`: When `size` is negative, alignment is not a power of two, or the `old_size` argument is incorrect. - `Mode_Not_Implemented`: The allocator does not support the `.Realloc` mode. **Note**: if `old_size` is `0` and `old_memory` is `nil`, this operation is a no-op, and should not return errors.

resize_non_zeroed #

Source
@(require_results)
resize_non_zeroed :: proc(
	ptr:       rawptr, 
	old_size:  int, 
	new_size:  int, 
	alignment: int = DEFAULT_ALIGNMENT, 
	allocator := context.allocator, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize a memory region without zero-initialization. This procedure resizes a memory region, `old_size` bytes in size, located at the address specified by `ptr`, such that it has a new size, specified by `new_size` and and is aligned on a boundary specified by `alignment`. If the `ptr` parameter is `nil`, `resize()` acts just like `alloc()`, allocating `new_size` bytes, aligned on a boundary specified by `alignment`. If the `new_size` parameter is `0`, `resize()` acts just like `free()`, freeing the memory region `old_size` bytes in length, located at the address specified by `ptr`. If the `old_memory` pointer is not aligned to the boundary specified by `alignment`, the procedure relocates the buffer such that the reallocated buffer is aligned to the boundary specified by `alignment`. Unlike `resize()`, this procedure does not explicitly zero-initialize any new memory. **Inputs**: - `ptr`: Pointer to the memory region to resize. - `old_size`: Size of the memory region to resize. - `new_size`: The desired size of the resized memory region. - `alignment`: The desired alignment of the resized memory region. - `allocator`: The owner of the memory region to resize. **Returns**: 1. The pointer to the resized memory region, if successfull, `nil` otherwise. 2. Error, if resize failed. **Errors**: - `None`: No error. - `Out_Of_Memory`: When the allocator's backing buffer or it's backing allocator does not have enough space to fit in an allocation with the new size, or an operating system failure occurs. - `Invalid_Pointer`: The pointer referring to a memory region does not belong to any of the allocators backing buffers or does not point to a valid start of an allocation made in that allocator. - `Invalid_Argument`: When `size` is negative, alignment is not a power of two, or the `old_size` argument is incorrect. - `Mode_Not_Implemented`: The allocator does not support the `.Realloc` mode. **Note**: if `old_size` is `0` and `old_memory` is `nil`, this operation is a no-op, and should not return errors.

rollback_stack_allocator #

Source
@(require_results)
@(no_sanitize_address)
rollback_stack_allocator :: proc(stack: ^Rollback_Stack) -> Allocator {…}

Rollback stack allocator. The Rollback Stack Allocator was designed for the test runner to be fast, able to grow, and respect the Tracking Allocator's requirement for individual frees. It is not overly concerned with fragmentation, however. It has support for expansion when configured with a block allocator and limited support for out-of-order frees. Allocation has constant-time best and usual case performance. At worst, it is linear according to the number of memory blocks. Allocation follows a first-fit strategy when there are multiple memory blocks. Freeing has constant-time best and usual case performance. At worst, it is linear according to the number of memory blocks and number of freed items preceding the last item in a block. Resizing has constant-time performance, if it's the last item in a block, or the new size is smaller. Naturally, this becomes linear-time if there are multiple blocks to search for the pointer's owning block. Otherwise, the allocator defaults to a combined alloc & free operation internally. Out-of-order freeing is accomplished by collapsing a run of freed items from the last allocation backwards. Each allocation has an overhead of 8 bytes and any extra bytes to satisfy the requested alignment.

rollback_stack_destroy #

Source
@(no_sanitize_address)
rollback_stack_destroy :: proc(stack: ^Rollback_Stack) {…}

Destroy a rollback stack.

rollback_stack_init_buffered #

Source
@(no_sanitize_address)
rollback_stack_init_buffered :: proc(stack: ^Rollback_Stack, buffer: []u8, location := #caller_location) {…}

Initialize the rollback stack allocator using a fixed backing buffer.

rollback_stack_init_dynamic #

Source
@(no_sanitize_address)
rollback_stack_init_dynamic :: proc(stack: ^Rollback_Stack, block_size: int = ROLLBACK_STACK_DEFAULT_BLOCK_SIZE, block_allocator := context.allocator, location := #caller_location) -> Allocator_Error {…}

Initialize the rollback stack alocator using a backing block allocator.

scratch_alloc #

Source
@(require_results)
scratch_alloc :: proc(s: ^Scratch, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a scratch allocator. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment`. The allocated memory region is zero-initialized. This procedure returns a pointer to the allocated memory region.

scratch_alloc_bytes #

Source
@(require_results)
scratch_alloc_bytes :: proc(s: ^Scratch, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a scratch allocator. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment`. The allocated memory region is zero-initialized. This procedure returns a slice of the allocated memory region.

scratch_alloc_bytes_non_zeroed #

Source
@(require_results)
scratch_alloc_bytes_non_zeroed :: proc(s: ^Scratch, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate non-initialized memory from a scratch allocator. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment`. The allocated memory region is not explicitly zero-initialized. This procedure returns a slice of the allocated memory region.

scratch_alloc_non_zeroed #

Source
@(require_results)
scratch_alloc_non_zeroed :: proc(s: ^Scratch, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate non-initialized memory from a scratch allocator. This procedure allocates `size` bytes of memory aligned on a boundary specified by `alignment`. The allocated memory region is not explicitly zero-initialized. This procedure returns a pointer to the allocated memory region.

scratch_allocator #

Source
@(require_results)
scratch_allocator :: proc(allocator: ^Scratch) -> Allocator {…}

Scratch allocator. The scratch allocator works in a similar way to the `Arena` allocator. The scratch allocator has a backing buffer that is allocated in contiguous regions, from start to end. Each subsequent allocation will be the next adjacent region of memory in the backing buffer. If the allocation doesn't fit into the remaining space of the backing buffer, this allocation is put at the start of the buffer, and all previous allocations will become invalidated. If the allocation doesn't fit into the backing buffer as a whole, it will be allocated using a backing allocator, and the pointer to the allocated memory region will be put into the `leaked_allocations` array. A `Warning`-level log message will be sent as well. Allocations which are resized will be resized in-place if they were the last allocation. Otherwise, they are re-allocated to avoid overwriting previous allocations. The `leaked_allocations` array is managed by the `context` allocator if no `backup_allocator` is specified in `scratch_init`.

scratch_allocator_destroy #

Source
scratch_allocator_destroy :: proc(s: ^Scratch) {…}

Free all data associated with a scratch allocator. This is distinct from `scratch_free_all` in that it deallocates all memory used to setup the allocator, as opposed to all allocations made from that space.

scratch_destroy #

Source
scratch_destroy :: proc(s: ^Scratch) {…}

Free all data associated with a scratch allocator. This is distinct from `scratch_free_all` in that it deallocates all memory used to setup the allocator, as opposed to all allocations made from that space.

scratch_free #

Source
scratch_free :: proc(s: ^Scratch, ptr: rawptr, loc := #caller_location) -> Allocator_Error {…}

Free memory back to the scratch allocator. This procedure frees the memory region allocated at pointer `ptr`. If `ptr` is not the latest allocation and is not a leaked allocation, this operation is a no-op.

scratch_free_all #

Source
scratch_free_all :: proc(s: ^Scratch, loc := #caller_location) {…}

Free all memory back to the scratch allocator.

scratch_resize #

Source
@(require_results)
scratch_resize :: proc(
	s:          ^Scratch, 
	old_memory: rawptr, 
	old_size:   int, 
	size:       int, 
	alignment:  int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a scratch allocator. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `scratch_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `scratch_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the pointer to the resized memory region.

scratch_resize_bytes #

Source
@(require_results)
scratch_resize_bytes :: proc(s: ^Scratch, old_data: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a scratch allocator. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `scratch_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `scratch_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the slice of the resized memory region.

scratch_resize_bytes_non_zeroed #

Source
@(require_results)
scratch_resize_bytes_non_zeroed :: proc(s: ^Scratch, old_data: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a scratch allocator. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `scratch_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `scratch_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the slice of the resized memory region.

scratch_resize_non_zeroed #

Source
@(require_results)
scratch_resize_non_zeroed :: proc(
	s:          ^Scratch, 
	old_memory: rawptr, 
	old_size:   int, 
	size:       int, 
	alignment:  int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a scratch allocator, without zero-initialization. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `scratch_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `scratch_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the pointer to the resized memory region.

set #

Source
set :: proc "contextless" (data: rawptr, value: u8, len: int) -> rawptr {…}

Set each byte of a memory range to a specific value. This procedure copies value specified by the `value` parameter into each of the `len` bytes of a memory range, located at address `data`. This procedure returns the pointer to `data`.

simple_equal #

Source
@(require_results)
simple_equal :: proc "contextless" (a, b: $T) -> bool {…}

Check whether two objects are equal on binary level. This procedure checks whether the memory ranges occupied by objects `a` and `b` are equal. See `compare_byte_ptrs()` for how this comparison is done.

slice_data_cast #

Source
@(require_results)
slice_data_cast :: proc "contextless" ($T: typeid/[]$A, slice: $S/[]$B) -> $$deferred_return {…}

Transmute slice to a different type. This procedure performs an operation similar to transmute, returning a slice of type `T` that points to the same bytes as the slice specified by `slice` parameter. Unlike plain transmute operation, this procedure adjusts the length of the resulting slice, such that the resulting slice points to the correct amount of objects to cover the memory region pointed to by `slice`.

slice_ptr #

Source
@(require_results)
slice_ptr :: proc "contextless" (ptr: ^$T, len: int) -> $$deferred_return {…}

Construct a slice from pointer and length. This procedure creates a slice, that points to `len` amount of objects located at an address, specified by `ptr`.

slice_to_bytes #

Source
@(require_results)
slice_to_bytes :: proc "contextless" (slice: $E/[]$T) -> []u8 {…}

Obtain a byte slice from any slice. This procedure returns a slice, that points to the same bytes as the slice, specified by `slice` and returns the resulting byte slice.

slice_to_components #

Source
@(require_results)
slice_to_components :: proc "contextless" (slice: $E/[]$T) -> (data: $$deferred_return, len: int) {…}

Obtain data and length of a slice. This procedure returns the pointer to the start of the memory region pointed to by slice `slice` and the length of the slice.

small_stack_alloc #

Source
@(require_results)
small_stack_alloc :: proc(s: ^Small_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a small stack allocator. This procedure allocates `size` bytes of memory aligned to a boundary specified by `alignment`. The allocated memory is zero-initialized. This procedure returns a pointer to the allocated memory region.

small_stack_alloc_bytes #

Source
@(require_results)
small_stack_alloc_bytes :: proc(s: ^Small_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a small stack allocator. This procedure allocates `size` bytes of memory aligned to a boundary specified by `alignment`. The allocated memory is zero-initialized. This procedure returns a slice of the allocated memory region.

small_stack_alloc_bytes_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
small_stack_alloc_bytes_non_zeroed :: proc(s: ^Small_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a small stack allocator. This procedure allocates `size` bytes of memory aligned to a boundary specified by `alignment`. The allocated memory is not explicitly zero-initialized. This procedure returns a slice of the allocated memory region.

small_stack_alloc_non_zeroed #

Source
@(require_results)
small_stack_alloc_non_zeroed :: proc(s: ^Small_Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a small stack allocator. This procedure allocates `size` bytes of memory aligned to a boundary specified by `alignment`. The allocated memory is not explicitly zero-initialized. This procedure returns a pointer to the allocated memory region.

small_stack_allocator #

Source
@(require_results)
small_stack_allocator :: proc(stack: ^Small_Stack) -> Allocator {…}

Small stack allocator. The small stack allocator is just like a `Stack` allocator, with the only difference being an extremely small header size. Unlike the stack allocator, the small stack allows out-of order freeing of memory, with the stipulation that all allocations made after the freed allocation will become invalidated upon following allocations as they will begin to overwrite the memory formerly used by the freed allocation. The memory is allocated in the backing buffer linearly, from start to end. Each subsequent allocation will get the next adjacent memory region. The metadata is stored in the allocation headers, that are located before the start of each allocated memory region. Each header contains the amount of padding bytes between that header and end of the previous allocation.

small_stack_free #

Source
small_stack_free :: proc(s: ^Small_Stack, old_memory: rawptr, loc := #caller_location) -> Allocator_Error {…}

Allocate memory from a small stack allocator. This procedure allocates `size` bytes of memory aligned to a boundary specified by `alignment`. The allocated memory is not explicitly zero-initialized. This procedure returns a slice of the allocated memory region.

small_stack_free_all #

Source
small_stack_free_all :: proc(s: ^Small_Stack) {…}

Free all memory back to the small stack allocator.

small_stack_init #

Source
small_stack_init :: proc(s: ^Small_Stack, data: []u8) {…}

Initialize a small stack allocator. This procedure initializes the small stack allocator with `data` as its backing buffer.

small_stack_resize #

Source
@(require_results)
small_stack_resize :: proc(
	s:          ^Small_Stack, 
	old_memory: rawptr, 
	old_size:   int, 
	size:       int, 
	alignment:  int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a small stack allocator. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `small_stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `small_stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the pointer to the resized memory region.

small_stack_resize_bytes #

Source
@(require_results)
small_stack_resize_bytes :: proc(s: ^Small_Stack, old_data: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a small stack allocator. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `small_stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `small_stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the slice of the resized memory region.

small_stack_resize_bytes_non_zeroed #

Source
@(require_results)
small_stack_resize_bytes_non_zeroed :: proc(s: ^Small_Stack, old_data: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a small stack allocator, without zero-initialization. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `small_stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `small_stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the slice of the resized memory region.

small_stack_resize_non_zeroed #

Source
@(require_results)
small_stack_resize_non_zeroed :: proc(
	s:          ^Small_Stack, 
	old_memory: rawptr, 
	old_size:   int, 
	size:       int, 
	alignment:  int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a small stack allocator, without zero-initialization. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `small_stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `small_stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the pointer to the resized memory region.

stack_alloc #

Source
@(require_results)
stack_alloc :: proc(s: ^Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a stack allocator. This procedure allocates `size` bytes of memory, aligned to the boundary specified by `alignment`. The allocated memory is zero-initialized. This procedure returns the pointer to the allocated memory.

stack_alloc_bytes #

Source
@(require_results)
stack_alloc_bytes :: proc(s: ^Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a stack allocator. This procedure allocates `size` bytes of memory, aligned to the boundary specified by `alignment`. The allocated memory is zero-initialized. This procedure returns the slice of the allocated memory.

stack_alloc_bytes_non_zeroed #

Source
@(require_results)
@(no_sanitize_address)
stack_alloc_bytes_non_zeroed :: proc(s: ^Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Allocate memory from a stack allocator. This procedure allocates `size` bytes of memory, aligned to the boundary specified by `alignment`. The allocated memory is not explicitly zero-initialized. This procedure returns the slice of the allocated memory.

stack_alloc_non_zeroed #

Source
@(require_results)
stack_alloc_non_zeroed :: proc(s: ^Stack, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> (rawptr, Allocator_Error) {…}

Allocate memory from a stack allocator. This procedure allocates `size` bytes of memory, aligned to the boundary specified by `alignment`. The allocated memory is not explicitly zero-initialized. This procedure returns the pointer to the allocated memory.

stack_allocator #

Source
@(require_results)
stack_allocator :: proc(stack: ^Stack) -> Allocator {…}

Stack allocator. The stack allocator is an allocator that allocates data in the backing buffer linearly, from start to end. Each subsequent allocation will get the next adjacent memory region. Unlike arena allocator, the stack allocator saves allocation metadata and has a strict freeing order. Only the last allocated element can be freed. After the last allocated element is freed, the next previous allocated element becomes available for freeing. The metadata is stored in the allocation headers, that are located before the start of each allocated memory region. Each header points to the start of the previous allocation header.

stack_free #

Source
stack_free :: proc(s: ^Stack, old_memory: rawptr, loc := #caller_location) -> Allocator_Error {…}

Free memory back to the stack allocator. This procedure frees the memory region starting at `old_memory` to the stack. If the freeing is an out of order freeing, the `.Invalid_Pointer` error is returned.

stack_free_all #

Source
stack_free_all :: proc(s: ^Stack, loc := #caller_location) {…}

Free all memory back to the stack allocator.

stack_init #

Source
stack_init :: proc(s: ^Stack, data: []u8) {…}

Initialize a stack allocator. This procedure initializes the stack allocator with a backing buffer specified by `data` parameter.

stack_resize #

Source
@(require_results)
stack_resize :: proc(
	s:          ^Stack, 
	old_memory: rawptr, 
	old_size:   int, 
	size:       int, 
	alignment:  int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a stack allocator. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the pointer to the resized memory region.

stack_resize_bytes #

Source
@(require_results)
stack_resize_bytes :: proc(s: ^Stack, old_data: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a stack allocator. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is zero-initialized. If `old_memory` is `nil`, this procedure acts just like `stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the slice of the resized memory region.

stack_resize_bytes_non_zeroed #

Source
@(require_results)
stack_resize_bytes_non_zeroed :: proc(s: ^Stack, old_data: []u8, size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> ([]u8, Allocator_Error) {…}

Resize an allocation owned by a stack allocator, without zero-initialization. This procedure resizes a memory region specified by `old_data` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the slice of the resized memory region.

stack_resize_non_zeroed #

Source
@(require_results)
stack_resize_non_zeroed :: proc(
	s:          ^Stack, 
	old_memory: rawptr, 
	old_size:   int, 
	size:       int, 
	alignment:  int = DEFAULT_ALIGNMENT, 
	loc := #caller_location, 
) -> (rawptr, Allocator_Error) {…}

Resize an allocation owned by a stack allocator, without zero-initialization. This procedure resizes a memory region defined by its location `old_memory` and its size `old_size` to have a size `size` and alignment `alignment`. The newly allocated memory, if any, is not explicitly zero-initialized. If `old_memory` is `nil`, this procedure acts just like `stack_alloc()`, allocating a memory region `size` bytes in size, aligned on a boundary specified by `alignment`. If `size` is 0, this procedure acts just like `stack_free()`, freeing the memory region located at an address specified by `old_memory`. This procedure returns the pointer to the resized memory region.

tracking_allocator #

Source
@(require_results)
@(no_sanitize_address)
tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {…}

Tracking allocator. The tracking allocator is an allocator wrapper that tracks memory allocations. This allocator stores all the allocations in a map. Whenever a pointer that's not inside of the map is freed, the `bad_free_array` entry is added. Here follows an example of how to use the `Tracking_Allocator` to track subsequent allocations in your program and report leaks. By default, the tracking allocator will crash on bad frees. You can override that behavior by overriding `track.bad_free_callback`. Example: package foo import "core:mem" import "core:fmt" main :: proc() { track: mem.Tracking_Allocator mem.tracking_allocator_init(&track, context.allocator) defer mem.tracking_allocator_destroy(&track) context.allocator = mem.tracking_allocator(&track) do_stuff() for _, leak in track.allocation_map { fmt.printf("%v leaked %m\n", leak.location, leak.size) } }

tracking_allocator_bad_free_callback_add_to_array #

Source
@(no_sanitize_address)
tracking_allocator_bad_free_callback_add_to_array :: proc(t: ^Tracking_Allocator, memory: rawptr, location: Source_Code_Location) {…}

Alternative behavior for a bad free: Store in `bad_free_array`. If you use this, then you must make sure to check Tracking_Allocator.bad_free_array at some point.

tracking_allocator_bad_free_callback_panic #

Source
@(no_sanitize_address)
tracking_allocator_bad_free_callback_panic :: proc(t: ^Tracking_Allocator, memory: rawptr, location: Source_Code_Location) {…}

Default behavior for a bad free: Crash with error message that says where the bad free happened. Override Tracking_Allocator.bad_free_callback to have something else happen. For example, you can use tracking_allocator_bad_free_callback_add_to_array to return the tracking allocator to the old behavior, where the bad_free_array was used.

tracking_allocator_clear #

Source
@(no_sanitize_address)
tracking_allocator_clear :: proc(t: ^Tracking_Allocator) {…}

Clear the tracking allocator. This procedure clears the tracked data from a tracking allocator. **Note**: This procedure clears only the current allocation data while keeping the totals intact.

tracking_allocator_init #

Source
@(no_sanitize_address)
tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Allocator, internals_allocator := context.allocator) {…}

Initialize the tracking allocator. This procedure initializes the tracking allocator `t` with a backing allocator specified with `backing_allocator`. The `internals_allocator` will used to allocate the tracked data.

tracking_allocator_reset #

Source
@(no_sanitize_address)
tracking_allocator_reset :: proc(t: ^Tracking_Allocator) {…}

Reset the tracking allocator. Reset all of a Tracking Allocator's allocation data back to zero.

zero #

Source
zero :: proc "contextless" (data: rawptr, len: int) -> rawptr {…}

Set each byte of a memory range to zero. This procedure copies the value `0` into the `len` bytes of a memory range, starting at address `data`. This procedure returns the pointer to `data`.

zero_explicit #

Source
zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr {…}

Set each byte of a memory range to zero. This procedure copies the value `0` into the `len` bytes of a memory range, starting at address `data`. This procedure returns the pointer to `data`. Unlike the `zero()` procedure, which can be optimized away or reordered by the compiler under certain circumstances, `zero_explicit()` procedure can not be optimized away or reordered with other memory access operations, and the compiler assumes volatile semantics of the memory.

zero_item #

Source
zero_item :: proc "contextless" (item: $P/^$T) -> $$deferred_return {…}

Zero-fill the memory of an object. This procedure sets each byte of the object pointed to by the pointer `item` to zero, and returns the pointer to `item`.

zero_slice #

Source
zero_slice :: proc "contextless" (data: $T/[]$E) -> $$deferred_return {…}

Zero-fill the memory of the slice. This procedure sets each byte of the slice pointed to by the slice `data` to zero, and returns the slice `data`.

Procedure Groups

3