core/mem

mem

Types

20

Arena_Temp_Memory

Arena_Temp_Memory :: struct { arena: ^Arena, prev_offset: int, }Source

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

Compat_Allocator :: struct { parent: Allocator, }Source

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.

Constants

43

Allocator

Allocator :: runtime.AllocatorSource

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

Allocator_Error :: runtime.Allocator_ErrorSource

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

Allocator_Mode :: runtime.Allocator_ModeSource

NOTE(bill, 2019-12-31): These are defined in package runtime as they are used in the context. This is to prevent an import definition cycle. 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_Proc

Allocator_Proc :: runtime.Allocator_ProcSource

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.

Byte

Byte :: runtime.ByteSource

The size, in bytes, of a single byte.

This constant is equal to the value of 1.

Exabyte

Exabyte :: runtime.ExabyteSource

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

Gigabyte :: runtime.GigabyteSource

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

Kilobyte :: runtime.KilobyteSource

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

Megabyte :: runtime.MegabyteSource

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

Petabyte :: runtime.PetabyteSource

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_MAX_HEAD_BLOCK_SIZE

ROLLBACK_STACK_MAX_HEAD_BLOCK_SIZE :: _ = 2 * GigabyteSource

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

Terabyte :: runtime.TerabyteSource

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.

align_forward_int

align_forward_int :: runtime.align_forward_intSource

Align int 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.

align_forward_uint

align_forward_uint :: runtime.align_forward_uintSource

Align uint 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.

ptr_offset

ptr_offset :: intrinsics.ptr_offsetSource

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

ptr_sub :: intrinsics.ptr_subSource

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

raw_data

raw_data :: builtin.raw_dataSource

Obtain pointer to the data.

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

Variables

1

PAGE_SIZE

PAGE_SIZE :: _ = = .Darwin && ODIN_ARCH == .arm64 else 4 * 1024Source

On platforms where we were able to query a configurable size, we use that value instead. See query_page_size_init()

Procedures

183

align_backward

align_backward :: proc(ptr: rawptr, align: uintptr) -> (rawptr)Source

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

align_backward_int :: proc(ptr: int, align: int) -> (int)Source

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

align_backward_uint :: proc(ptr: uint, align: uint) -> (uint)Source

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_forward

align_forward :: proc(ptr: rawptr, align: uintptr) -> (rawptr)Source

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

alloc :: proc(size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (Allocator_Error, rawptr)Source

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

alloc_bytes :: proc(size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

alloc_bytes_non_zeroed :: proc(size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

any_to_bytes :: proc(val: any) -> ([]u8)Source

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

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

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_allocator

arena_allocator :: proc(arena: ^Arena) -> (Allocator)Source

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.

buddy_allocator

buddy_allocator :: proc(b: ^Buddy_Allocator) -> (Allocator)Source

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.

buffer_from_slice

buffer_from_slice :: proc(backing: T) -> ([dynamic]E)Source

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

byte_slice :: proc(data: rawptr, len: int) -> ([]u8)Source

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

calc_padding_with_header :: proc(ptr: uintptr, align: uintptr, header_size: int) -> (int)Source

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

check_zero :: proc(data: []u8) -> (bool)Source

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

check_zero_ptr :: proc(ptr: rawptr, len: int) -> (bool)Source

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

compare :: proc(a: []u8, b: []u8) -> (int)Source

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

compare_byte_ptrs :: proc(a: ^u8, b: ^u8, n: int) -> (int)Source

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

compare_ptrs :: proc(a: rawptr, b: rawptr, n: int) -> (int)Source

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`.

copy

copy :: proc(dst: rawptr, src: rawptr, len: int) -> (rawptr)Source

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

copy_non_overlapping :: proc(dst: rawptr, src: rawptr, len: int) -> (rawptr)Source

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

default_resize_align :: proc( old_memory: rawptr, old_size: int, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc: _ = #caller_location, ) -> (res: rawptr, err: Allocator_Error)Source

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

default_resize_bytes_align :: proc(old_data: []u8, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

default_resize_bytes_align_non_zeroed :: proc(old_data: []u8, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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.

dynamic_arena_allocator

dynamic_arena_allocator :: proc(a: ^Dynamic_Arena) -> (Allocator)Source

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_init

dynamic_arena_init :: proc( arena: ^Dynamic_Arena, block_allocator: mem.Allocator = context.allocator, array_allocator: mem.Allocator = context.allocator, block_size: _ = DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT, out_band_size: _ = DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT, minimum_alignment: _ = DEFAULT_ALIGNMENT, )Source

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 at a minimum to a boundary specified by minimum_alignment.

dynamic_arena_resize

dynamic_arena_resize :: proc( a: ^Dynamic_Arena, old_memory: rawptr, old_size: int, size: int, alignment: int, loc: _ = #caller_location, ) -> (Allocator_Error, rawptr)Source

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

dynamic_arena_resize_bytes :: proc(a: ^Dynamic_Arena, old_data: []u8, size: int, alignment: int, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

dynamic_arena_resize_bytes_non_zeroed :: proc(a: ^Dynamic_Arena, old_data: []u8, size: int, alignment: int, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

dynamic_arena_resize_non_zeroed :: proc( a: ^Dynamic_Arena, old_memory: rawptr, old_size: int, size: int, alignment: int, loc: _ = #caller_location, ) -> (Allocator_Error, rawptr)Source

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.

free

free :: proc(ptr: rawptr, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (Allocator_Error)Source

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

free_all :: proc(allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (Allocator_Error)Source

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

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

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

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

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

is_aligned :: proc(x: rawptr, align: int) -> (bool)Source

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

make_aligned :: proc(T: typeid, len: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (slice: T, err: Allocator_Error)Source

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

make_any :: proc(data: rawptr, id: typeid) -> (any)Source

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

make_dynamic_array :: proc(T: typeid, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (Allocator_Error, T)Source

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

make_dynamic_array_len :: proc(T: typeid, len: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (Allocator_Error, T)Source

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

make_dynamic_array_len_cap :: proc(T: typeid, len: int, cap: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (array: T, err: Allocator_Error)Source

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

make_map :: proc(T: typeid, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (m: T)Source

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

make_map_cap :: proc(T: typeid, cap: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (m: T, err: Allocator_Error)Source

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

make_multi_pointer :: proc(T: typeid, len: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (mp: T, err: Allocator_Error)Source

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

make_over_aligned :: proc(T: typeid, len: int, alignment: int, allocator: runtime.Allocator, loc = #caller_location) -> (slice: T, original_data: []u8, err: Allocator_Error)Source

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

make_slice :: proc(T: typeid, len: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (Allocator_Error, T)Source

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

make_soa_dynamic_array :: proc(T: typeid, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (array: T, err: Allocator_Error)Source

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

make_soa_dynamic_array_len :: proc(T: typeid, len: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (array: T, err: Allocator_Error)Source

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

make_soa_dynamic_array_len_cap :: proc(T: typeid, len: int, cap: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (array: T, err: Allocator_Error)Source

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

make_soa_slice :: proc(T: typeid, len: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (array: T, err: Allocator_Error)Source

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.

new

new :: proc(T: typeid, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (^T, Allocator_Error)Source

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

new_aligned :: proc(T: typeid, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (t: ^T, err: Allocator_Error)Source

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

new_clone :: proc(data: T, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> (t: ^T, err: Allocator_Error)Source

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

nil_allocator :: proc() -> (Allocator)Source

This procedure checks if a byte slice range is poisoned and makes sure the root address of the poison range is the base pointer of range.

This can help guard against buggy allocators returning memory that they already returned.

This has no effect if -sanitize:address is not enabled. @(disabled=.Address not_in ODIN_SANITIZER_FLAGS, private) ensure_poisoned :: proc(range: []u8, loc := #caller_location) {

cond := sanitizer.address_region_is_poisoned(range) == raw_data(range)
	// If this fails, we've overlapped an allocation and it's our fault.
	ensure(cond, `This allocator has sliced a block of memory of which some part is not poisoned before returning.
This is a bug in the core library and should be reported to the Odin developers with a stack trace and minimal example code if possible.`, loc)
}
This procedure checks if a byte slice `range` is not poisoned.

This can help guard against buggy allocators resizing memory that they should not.

This has no effect if `-sanitize:address` is not enabled.
@(disabled=.Address not_in ODIN_SANITIZER_FLAGS, private)
ensure_not_poisoned :: proc(range: []u8, loc := #caller_location) {
	cond := sanitizer.address_region_is_poisoned(range) == nil
	// If this fails, we've tried to resize memory that is poisoned, which
	// could be user error caused by an incorrect `old_memory` pointer.
	ensure(cond, `This allocator has sliced a block of memory of which some part is poisoned before returning.
This may be a bug in the core library, or it could be user error due to an invalid pointer passed to a resize operation.
If after ensuring your own code is not responsible, report the problem to the Odin developers with a stack trace and minimal example code if possible.`, loc)
}
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

panic_allocator :: proc() -> (Allocator)Source

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_to_bytes

ptr_to_bytes :: proc(ptr: ^T, len: untyped integer = 1) -> ([]u8)Source

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.

reinterpret_copy

reinterpret_copy :: proc(T: typeid, ptr: rawptr) -> (value: T)Source

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

resize :: proc( ptr: rawptr, old_size: int, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc: _ = #caller_location, ) -> (Allocator_Error, rawptr)Source

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

resize_bytes :: proc(old_data: []u8, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

resize_bytes_non_zeroed :: proc(old_data: []u8, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc = #caller_location) -> ([]u8, Allocator_Error)Source

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

resize_non_zeroed :: proc( ptr: rawptr, old_size: int, new_size: int, alignment: int, allocator: mem.Allocator = context.allocator, loc: _ = #caller_location, ) -> (Allocator_Error, rawptr)Source

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

rollback_stack_allocator :: proc(stack: ^Rollback_Stack) -> (Allocator)Source

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.

scratch_allocator

scratch_allocator :: proc(allocator: ^Scratch) -> (Allocator)Source

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_free

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

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_resize

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

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

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

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

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

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

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

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

set :: proc(data: rawptr, value: u8, len: int) -> (rawptr)Source

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

simple_equal :: proc(a: T, b: T) -> (bool)Source

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

slice_data_cast :: proc(T: typeid, slice: S) -> (T)Source

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

slice_ptr :: proc(ptr: ^T, len: int) -> ([]T)Source

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

slice_to_bytes :: proc(slice: E) -> ([]u8)Source

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

slice_to_components :: proc(slice: E) -> (data: ^T, len: int)Source

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_allocator

small_stack_allocator :: proc(stack: ^Small_Stack) -> (Allocator)Source

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

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

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_resize

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

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

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

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

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

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

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

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

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

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_allocator

stack_allocator :: proc(stack: ^Stack) -> (Allocator)Source

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

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

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_init

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

Initialize a stack allocator.

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

stack_resize

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

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

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

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

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

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

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

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

tracking_allocator :: proc(data: ^Tracking_Allocator) -> (Allocator)Source

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_panic

tracking_allocator_bad_free_callback_panic :: proc(t: ^Tracking_Allocator, memory: rawptr, location: runtime.Source_Code_Location)Source

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.

zero

zero :: proc(data: rawptr, len: int) -> (rawptr)Source

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

zero_explicit :: proc(data: rawptr, len: int) -> (rawptr)Source

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

zero_item :: proc(item: P) -> (P)Source

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

zero_slice :: proc(data: T) -> (T)Source

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

Reference search

Find anything

Documentation preferences

Settings

System theme variants

Used only while Theme is set to System.