Veritable Lasagna
An Allocator & Data Structure Library for C.
Loading...
Searching...
No Matches
vl_memory.h File Reference
#include <stdalign.h>
#include <malloc.h>
#include "vl_numtypes.h"
#include "vl_compare.h"
+ 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_DEFAULT_MEMORY_ALIGN   alignof(vl_ularge_t)
 Default memory alignment. Defaults to maximum system word size.
 
#define VL_MEMORY_PAD_UP(len, pad)   (vl_ularge_t)((len) + ((len) % (pad)))
 Calculate the next offset such that it is a multiple of an alignment.
 
#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_SIZE_T vl_memsize_t
 
typedef VL_MEMORY_T vl_memory
 
typedef VL_MEMORY_T vl_transient
 

Functions

vl_memoryvlMemAlloc (vl_memsize_t allocSize)
 Attempts to allocate a block of memory.
 
vl_memoryvlMemRealloc (vl_memory *mem, vl_memsize_t allocSize)
 Reallocates the specified block of memory to hold the specified total number of bytes.
 
vl_memoryvlMemAllocAligned (vl_memsize_t allocSize, vl_uint_t align)
 Allocates a block of memory with an alignment.
 
vl_memoryvlMemClone (vl_memory *mem)
 Clones the specified block of memory, returning a pointer to its new clone.
 
vl_memsize_t vlMemSize (vl_memory *mem)
 Returns the size (in total number of bytes) of the specified block of vl_memory.
 
vl_uint_t vlMemAlignment (vl_memory *mem)
 Returns the alignment of the specified block of memory.
 
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.
 
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.
 
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.
 
void vlMemFree (vl_memory *mem)
 Frees the specified block of memory.
 

Detailed Description

The vl_alloc header defines an interface to allocate and delete blocks of memory allocated on the system heap. The purpose behind this is three fold:

  • To provide a consistent, in-library, and well-documented facility to almost all memory allocation within the library.
  • To provide a way to track all functions which might eventually allocate, reallocate, or delete memory.
  • To provide metadata regarding size and explicit alignment of these allocations.

Macro Definition Documentation

◆ VL_DEFAULT_MEMORY_ALIGN

#define VL_DEFAULT_MEMORY_ALIGN   alignof(vl_ularge_t)

Default memory alignment. Defaults to maximum system word size.

◆ VL_DEFAULT_MEMORY_SIZE

#define VL_DEFAULT_MEMORY_SIZE   VL_KB(1)

Default 1kb allocation size.

◆ VL_KB

#define VL_KB ( x)    ((vl_memsize_t) (x) << 10)

Convenience macro to define blocks of memory which contain a multiple of X-many kilobytes.

Parameters
xtotal kilobytes.

◆ VL_MB

#define VL_MB ( x)    ((vl_memsize_t) (x) << 20)

Convenience macro to define blocks of memory which contain a multiple of X-many megabytes.

Parameters
xtotal megabytes.

◆ VL_MEMORY_PAD_UP

#define VL_MEMORY_PAD_UP ( len,
pad )   (vl_ularge_t)((len) + ((len) % (pad)))

Calculate the next offset such that it is a multiple of an alignment.

This will return len when already a multiple of pad.

len size of the memory block
pad bytes to pad it to.
Returns
len

◆ vlMemReverse

#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].

See also
vlMemReverseSubArraysStride
Parameters
srcmemory block pointer
numBytestotal number of bytes to reverse
Complexity of O(n) linear.

◆ vlMemReverseSubArrays

#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].

See also
vlMemReverseSubArraysStride
Parameters
srcmemory block pointer
elementSizesize of each sub array, or element, in bytes
numElementstotal number of sub arrays, or elements
Complexity of O(n) linear.

Typedef Documentation

◆ vl_memory

typedef VL_MEMORY_T vl_memory

The typedef for vl_memory is simply void. This is intended to improve code readability and intent.

This is used only to indicate blocks of memory allocated through vlMemAlloc(/Aligned) and vlMemRealloc.

See also
vlMemAlloc
vlMemAllocAligned
vlMemRealloc

vl_memory pointers have a header associated with them. This allows for implicit size tracking, among other things.

◆ vl_memsize_t

typedef VL_MEMORY_SIZE_T vl_memsize_t

◆ vl_transient

typedef VL_MEMORY_T vl_transient

The typedef for vl_transient is, similarly, void. 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 or allocator.

Function Documentation

◆ vlMemAlignment()

vl_uint_t vlMemAlignment ( vl_memory * mem)

Returns the alignment of the specified block of memory.

Minimum alignment is defined as VL_DEFAULT_MEMORY_ALIGN, or the largest available word size.

Parameters
mempointer to memory block
Returns
alignment

◆ vlMemAlloc()

vl_memory * vlMemAlloc ( vl_memsize_t allocSize)

Attempts to allocate a block of memory.

Returns NULL on failure.

Parameters
allocSizesize of the allocation, in bytes.
Returns
pointer to allocated block, or NULL.
+ Here is the caller graph for this function:

◆ vlMemAllocAligned()

vl_memory * vlMemAllocAligned ( vl_memsize_t allocSize,
vl_uint_t align )

Allocates a block of memory with an alignment.

allocSize must be >= align or align must be < sizeof(uintptr_t), or this will return NULL. The alignment must be a power of 2 (16, 32, 64, etc), otherwise the behavior is undefined.

Guarantees that the returned pointer will have an 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.

See also
VL_MEMORY_PAD_UP
Parameters
allocSizesize of the allocation, in bytes.
align
Returns
pointer to the aligned block
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ vlMemClone()

vl_memory * vlMemClone ( vl_memory * mem)

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.

Parameters
mempointer
Returns
cloned memory pointer
+ Here is the call graph for this function:

◆ vlMemCopyStride()

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.

Parameters
srcmemory block pointer
srcStridetotal number of bytes between each element in "src"
destmemory block pointer
dstStridetotal number of bytes between each element in "dest"
elementSizetotal number of bytes wide of each element
numElementstotal number of elements
Complexity of O(n) linear.

◆ vlMemFree()

void vlMemFree ( vl_memory * mem)

Frees the specified block of memory.

Parameters
mempointer to block.
+ Here is the caller graph for this function:

◆ vlMemRealloc()

vl_memory * vlMemRealloc ( vl_memory * mem,
vl_memsize_t allocSize )

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.

Parameters
mempointer to block
allocSizenew size of the allocation.
Returns
pointer to reallocated memory
+ Here is the caller graph for this function:

◆ vlMemReverseSubArraysStride()

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.

Parameters
srcmemory block pointer. The base address of the memory containing the elements to be reversed.
srcStridetotal number of bytes between each sub-array (or element). This defines the gap between consecutive elements.
elementSizesize of each sub-array (or element) in bytes. This is the number of bytes that constitute one element.
numElementstotal number of sub-arrays (or elements). This is the number of individual elements to process.
Complexity of O(n) linear.

◆ vlMemSize()

vl_memsize_t vlMemSize ( vl_memory * mem)

Returns the size (in total number of bytes) of the specified block of vl_memory.

mem pointer to memory block
Returns
size of the specified memory block, in bytes.
+ Here is the caller graph for this function:

◆ vlMemSort()

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, allocating a temporary workspace on either the stack or the heap depending on the size of the data being sorted.

Parameters
buffer
elementSize
numElements
comparator
Complexity of O(n log(n)) (space complexity of O(n)).
+ Here is the call graph for this function: