|
Veritable Lasagna
An Allocator & Data Structure Library for C.
|
Include dependency graph for vl_memory.h:
This graph shows which files directly or indirectly include this file:Go to the source code of this file.
Macros | |
| #define | VL_KB(x) ((vl_memsize_t)(x) << 10) |
| #define | VL_MB(x) ((vl_memsize_t)(x) << 20) |
| #define | VL_DEFAULT_MEMORY_SIZE VL_KB(1) |
| Default 1kb allocation size. | |
| #define | VL_ALIGNOF(T) __alignof__(T) |
| #define | VL_DEFAULT_MEMORY_ALIGN VL_ALIGNOF(vl_ularge_t) |
| Default memory alignment. Defaults to maximum system word size. | |
| #define | VL_MEMORY_PAD_UP(len, pad) (((len) + (pad) - 1) & ~((pad) - 1)) |
| Calculate the next offset such that it is a multiple of an alignment. | |
| #define | VL_ALIGN_HINT(x) |
| Structure alignment hint. | |
| #define | vlMemAllocType(element_type) ((element_type*)vlMemAllocAligned(sizeof(element_type), VL_ALIGNOF(element_type))) |
| Type-safe heap allocation for a single element. | |
| #define | vlMemAllocTypeArray(element_type, count) ((element_type*)vlMemAllocAligned(sizeof(element_type) * (count), VL_ALIGNOF(element_type))) |
| Type-safe heap allocation for an array of elements. | |
| #define | vlMemAllocStackType(element_type) ((element_type*)vlMemAllocStackAligned(sizeof(element_type), VL_ALIGNOF(element_type))) |
| Type-safe stack allocation for a single element. | |
| #define | vlMemAllocStackTypeArray(element_type, count) ((element_type*)vlMemAllocStackAligned((count) * sizeof(element_type), VL_ALIGNOF(element_type))) |
| Type-safe stack allocation for an array of elements. | |
| #define | vlMemReverse(src, numBytes) vlMemReverseSubArraysStride(src, 1, numBytes, 1) |
| Reverses the order of bytes in the specified block of memory. | |
| #define | vlMemReverseSubArrays(src, elementSize, numElements) vlMemReverseSubArraysStride(src, elementSize, elementSize, numElements) |
| Reverses the bytes in a tightly packed series of elements of a defined length. | |
Typedefs | |
| typedef VL_MEMORY_T | vl_memory |
| typedef VL_MEMORY_T | vl_transient |
Functions | |
| VL_API vl_memory * | vlMemAlloc (vl_memsize_t allocSize) |
| Attempts to allocate a block of memory. | |
| VL_API vl_memory * | vlMemRealloc (vl_memory *mem, vl_memsize_t allocSize) |
| Reallocates the specified block of memory to hold the specified total number of bytes. | |
| VL_API vl_memory * | vlMemAllocAligned (vl_memsize_t allocSize, vl_uint_t align) |
| Allocates a block of memory with an alignment. | |
| vl_transient * | vlMemAllocStack (vl_memsize_t allocSize) |
| Allocate memory on the stack (automatic storage). | |
| vl_transient * | vlMemAllocStackAligned (vl_memsize_t allocSize, vl_uint16_t align) |
| Allocate aligned memory on the stack (automatic storage). | |
| VL_API vl_memory * | vlMemClone (vl_memory *mem) |
| Clones the specified block of memory, returning a pointer to its new clone. | |
| VL_API vl_memsize_t | vlMemSize (vl_memory *mem) |
| Returns the size (in total number of bytes) of the specified block of vl_memory. | |
| VL_API vl_uint_t | vlMemAlignment (vl_memory *mem) |
| Returns the alignment of the specified block of memory. | |
| VL_API void | vlMemSort (void *buffer, vl_memsize_t elementSize, vl_dsidx_t numElements, vl_compare_function comparator) |
| Sorts the specified buffer in-place according to the specified element and comparator function. | |
| VL_API void | vlMemCopyStride (const void *src, vl_dsoffs_t srcStride, void *dest, vl_dsoffs_t dstStride, vl_memsize_t elementSize, vl_dsidx_t numElements) |
| Copies data from one buffer to another, with a stride applied to both. | |
| VL_API void | vlMemReverseSubArraysStride (void *src, vl_dsoffs_t srcStride, vl_memsize_t elementSize, vl_dsidx_t numElements) |
| Reverses the bytes in a series of elements of a defined length and stride between them. | |
| VL_API void | vlMemFree (vl_memory *mem) |
| Frees the specified block of memory. | |
| #define VL_ALIGN_HINT | ( | x | ) |
Structure alignment hint.
Hints to the compiler that the declared structure should be aligned to the specified value.
| #define VL_ALIGNOF | ( | T | ) | __alignof__(T) |
| #define VL_DEFAULT_MEMORY_ALIGN VL_ALIGNOF(vl_ularge_t) |
Default memory alignment. Defaults to maximum system word size.
| #define VL_DEFAULT_MEMORY_SIZE VL_KB(1) |
Default 1kb allocation size.
| #define VL_KB | ( | x | ) | ((vl_memsize_t)(x) << 10) |
Convenience macro to define blocks of memory which contain a multiple of X-many kilobytes.
| x | total kilobytes. |
| #define VL_MB | ( | x | ) | ((vl_memsize_t)(x) << 20) |
Convenience macro to define blocks of memory which contain a multiple of X-many megabytes.
| x | total megabytes. |
| #define VL_MEMORY_PAD_UP | ( | len, | |
| pad | |||
| ) | (((len) + (pad) - 1) & ~((pad) - 1)) |
Calculate the next offset such that it is a multiple of an alignment.
This will return len when already a multiple of pad.
| #define vlMemAllocStackType | ( | element_type | ) | ((element_type*)vlMemAllocStackAligned(sizeof(element_type), VL_ALIGNOF(element_type))) |
Type-safe stack allocation for a single element.
Allocates memory on the stack for a single object of the specified type. The allocated memory is automatically aligned to the type's natural alignment requirement and automatically freed when the enclosing scope exits.
This macro combines type safety with automatic alignment, ensuring the allocation is properly sized and aligned for the type without manual alignment calculations.
| element_type | The type to allocate (e.g., int, struct foo, MyType) |
| #define vlMemAllocStackTypeArray | ( | element_type, | |
| count | |||
| ) | ((element_type*)vlMemAllocStackAligned((count) * sizeof(element_type), VL_ALIGNOF(element_type))) |
Type-safe stack allocation for an array of elements.
Allocates memory on the stack for an array of the specified type and count. The allocated memory is automatically aligned to the type's natural alignment requirement and automatically freed when the enclosing scope exits.
This macro combines type safety, proper sizing, and automatic alignment, eliminating manual calculations and reducing errors.
| element_type | The element type in the array (e.g., int, struct foo) |
| count | Number of elements to allocate space for |
| #define vlMemAllocType | ( | element_type | ) | ((element_type*)vlMemAllocAligned(sizeof(element_type), VL_ALIGNOF(element_type))) |
Type-safe heap allocation for a single element.
Allocates memory on the heap for a single object of the specified type. The allocated memory is properly sized and return type is cast to the desired type.
This macro provides a convenient, type-safe alternative to manual vlMemAlloc(sizeof(type)) calls, reducing the risk of size mismatches.
| element_type | The type to allocate (e.g., int, struct foo, MyType) |
| #define vlMemAllocTypeArray | ( | element_type, | |
| count | |||
| ) | ((element_type*)vlMemAllocAligned(sizeof(element_type) * (count), VL_ALIGNOF(element_type))) |
Type-safe heap allocation for an array of elements.
Allocates memory on the heap for an array of the specified type and count. The allocated memory is properly sized and the return type is cast to the desired type.
This macro provides a convenient, type-safe alternative to manual vlMemAlloc(count * sizeof(type)) calls, eliminating manual size calculations and reducing overflow risks.
| element_type | The element type in the array (e.g., int, struct foo) |
| count | Number of elements to allocate space for |
| #define vlMemReverse | ( | src, | |
| numBytes | |||
| ) | vlMemReverseSubArraysStride(src, 1, numBytes, 1) |
Reverses the order of bytes in the specified block of memory.
This is to be used on tightly packed sequences of bytes. Attempting to blindly reverse the memory of a structure can result in unexpected results due to padding inserted by the compiler.
Assuming the input is of the sequence [0x0A, 0x0B, 0x0C, 0x0D, 0x0E], the expected output would be [0x0E, 0x0D, 0x0C, 0x0B, 0x0A].
| src | memory block pointer |
| numBytes | total number of bytes to reverse |
| #define vlMemReverseSubArrays | ( | src, | |
| elementSize, | |||
| numElements | |||
| ) | vlMemReverseSubArraysStride(src, elementSize, elementSize, numElements) |
Reverses the bytes in a tightly packed series of elements of a defined length.
This is to be used on tightly packed sequences of elements. An element is defined as a discrete sub-array of bytes in a larger sequence.
Assuming you have the following input: [0xAABBCCDD, 0x11223344, 0x55667788], the expected output would be: [0xDDCCBBAA, 0x44332211, 0x88776655].
This differs from the vlMemReverse function, where given that input the expected output would be: [0x88776655, 0x44332211, 0xDDCCBBAA].
| src | memory block pointer |
| elementSize | size of each sub array, or element, in bytes |
| numElements | total number of sub arrays, or elements |
| typedef VL_MEMORY_T vl_memory |
The typedef for vl_memory is defined as the smallest possible word size. This is intended to improve code readability and intent.
This is used only to indicate blocks of memory allocated through vlMemAlloc(/Aligned) and vlMemRealloc.
vl_memory pointers have a header associated with them.
| typedef VL_MEMORY_T vl_transient |
The typedef for vl_transient is, similarly, the smallest possible word size. This is intended to improve code readability and intent.
This is used to indicate pointers to blocks of memory which that might be moved, deleted, or erased through some operation on a data structure, allocator, or stack scope.
Returns the alignment of the specified block of memory.
Minimum alignment is defined as VL_DEFAULT_MEMORY_ALIGN, or the largest available word size.
mem pointer must be valid at the time of the call.VL_DEFAULT_MEMORY_ALIGN if mem is NULL.vlMemAlloc or vlMemAllocAligned.| mem | pointer to memory block |
Here is the caller graph for this function:| VL_API vl_memory * vlMemAlloc | ( | vl_memsize_t | allocSize | ) |
Attempts to allocate a block of memory.
Returns NULL on failure.
vlMemFree.vlMemFree or vlMemRealloc.malloc.NULL on allocation failure. allocSize is not checked for zero, but malloc(0) is implementation-defined.NULL if the underlying malloc fails.free function instead of vlMemFree.allocSize plus the size of an internal header (vl_memory_header).NULL if allocation failed.| allocSize | size of the allocation, in bytes. |
Here is the caller graph for this function:Allocates a block of memory with an alignment.
Guarantees that the returned pointer will have a value that is a multiple of the specified alignment.
The VL_MEMORY_PAD_UP macro may be used to ensure that the actual length of the memory block is also a multiple of the alignment.
vlMemFree.vlMemFree or vlMemRealloc.malloc.NULL on allocation failure.NULL if the underlying malloc fails.align is not a power of 2.allocSize + align + sizeof(vl_memory_header) to guarantee alignment.NULL if allocation failed.| allocSize | size of the allocation, in bytes. |
| align |
Here is the call graph for this function:
Here is the caller graph for this function:
|
inline |
Allocate memory on the stack (automatic storage).
Allocates memory from the stack for the specified size. The allocated memory is automatically freed when the enclosing scope exits. Stack allocation is very fast but is limited by stack size (typically a few MB on most systems).
NULL.allocSize is too large for the remaining stack space (leads to process crash).allocSize bytes directly on the stack via alloca or equivalent.| allocSize | Number of bytes to allocate |
Here is the caller graph for this function:
|
inline |
Allocate aligned memory on the stack (automatic storage).
Allocates memory from the stack with custom alignment requirements. The allocated memory is automatically freed when the enclosing scope exits.
The alignment must be a power of 2 (16, 32, 64, 128, etc.). Passing a non-power-of-2 alignment will produce undefined behavior.
NULL.align is not a power of 2.allocSize + align - 1 bytes on the stack and returns an aligned pointer.| allocSize | Number of bytes to allocate |
| align | Required byte alignment (must be a power of 2) |
Here is the call graph for this function:Clones the specified block of memory, returning a pointer to its new clone.
Returns NULL on failure.
If the source block has an alignment, the result will also have an alignment.
vlMemFree.vlMemFree or vlMemRealloc.NULL if mem is NULL or if allocation fails.NULL on allocation failure.vlMemAlloc or vlMemAllocAligned.NULL if cloning failed.| mem | pointer |
Here is the call graph for this function:
Here is the caller graph for this function:| VL_API void vlMemCopyStride | ( | const void * | src, |
| vl_dsoffs_t | srcStride, | ||
| void * | dest, | ||
| vl_dsoffs_t | dstStride, | ||
| vl_memsize_t | elementSize, | ||
| vl_dsidx_t | numElements | ||
| ) |
Copies data from one buffer to another, with a stride applied to both.
Stride is the amount of space (in bytes) between each element.
src and dest buffers must remain valid for the duration of the copy.src or dest concurrently where at least one thread is writing.src and dest should not be NULL.srcStride or dstStride allow it, as memcpy is used for individual elements.| src | memory block pointer |
| srcStride | total number of bytes between each element in "src" |
| dest | memory block pointer |
| dstStride | total number of bytes between each element in "dest" |
| elementSize | total number of bytes wide of each element |
| numElements | total number of elements |
| VL_API void vlMemFree | ( | vl_memory * | mem | ) |
Frees the specified block of memory.
free.NULL (no-op).vlMemAlloc or vlMemAllocAligned, or double-freeing the same pointer.| mem | pointer to block. |
Here is the caller graph for this function:Reallocates the specified block of memory to hold the specified total number of bytes.
If the specified memory block is explicitly aligned, its alignment is preserved.
mem pointer may become invalid upon success.vlMemFree or another vlMemRealloc.realloc.mem is NULL, this function behaves like vlMemAlloc. If allocSize is zero, behavior is realloc-dependent.NULL if the underlying realloc fails. In this case, the original mem pointer remains valid and its memory is not leaked.vlMemAlloc or vlMemAllocAligned.NULL if reallocation failed.| mem | pointer to block |
| allocSize | new size of the allocation. |
Here is the call graph for this function:
Here is the caller graph for this function:| VL_API void vlMemReverseSubArraysStride | ( | void * | src, |
| vl_dsoffs_t | srcStride, | ||
| vl_memsize_t | elementSize, | ||
| vl_dsidx_t | numElements | ||
| ) |
Reverses the bytes in a series of elements of a defined length and stride between them.
This function operates on a sequence of elements (or sub-arrays) within a memory block, where each element is separated by a defined stride. It reverses the bytes of each individual element but does not alter the overall structure of the memory. The elements are processed sequentially, one by one, with each element's bytes reversed in-place.
This is useful when you need to reverse the bytes in each element of a collection of data structures that are tightly packed but may have a varying stride (i.e., distance between consecutive elements in memory).
Example: Suppose we have an array of 32-bit integers, each 4 bytes, with a stride of 8 bytes:
Input (elements of size 4 bytes, stride of 8 bytes): [0xAABBCCDD, 0x11223344, 0x55667788] Memory block: [0xAABBCCDD, pad, 0x11223344, pad, 0x55667788, pad] (Where 'pad' represents the unused memory between elements, i.e., stride.)
Output (each element reversed): [0xDDCCBBAA, 0x44332211, 0x88776655] Memory block: [0xDDCCBBAA, pad, 0x44332211, pad, 0x88776655, pad]
The bytes within each element are reversed, but the stride between elements is respected.
src.src buffer must remain valid for the duration of the operation.src concurrently.src should not be NULL.srcStride or elementSize that leads to out-of-bounds memory access.| src | memory block pointer. The base address of the memory containing the elements to be reversed. |
| srcStride | total number of bytes between each sub-array (or element). This defines the gap between consecutive elements. |
| elementSize | size of each sub-array (or element) in bytes. This is the number of bytes that constitute one element. |
| numElements | total number of sub-arrays (or elements). This is the number of individual elements to process. |
| VL_API vl_memsize_t vlMemSize | ( | vl_memory * | mem | ) |
Returns the size (in total number of bytes) of the specified block of vl_memory.
mem pointer must be valid at the time of the call.mem is NULL.vlMemAlloc or vlMemAllocAligned.
Here is the caller graph for this function:| VL_API void vlMemSort | ( | void * | buffer, |
| vl_memsize_t | elementSize, | ||
| vl_dsidx_t | numElements, | ||
| vl_compare_function | comparator | ||
| ) |
Sorts the specified buffer in-place according to the specified element and comparator function.
This function implements an iterative Quicksort.
buffer.buffer must remain valid for the duration of the sort.buffer concurrently.buffer must not be NULL. comparator must not be NULL.NULL buffer or comparator. Overlapping memory regions during sort operations.numElements and elementSize.| buffer | |
| elementSize | |
| numElements | |
| comparator |
Here is the call graph for this function: