feature: implement memory allocation functions
This commit is contained in:
parent
29e8753d1f
commit
13cc25860e
2 changed files with 318 additions and 0 deletions
277
Source/DrangPlatform/Include/drang/alloc.h
Normal file
277
Source/DrangPlatform/Include/drang/alloc.h
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
#pragma once
|
||||
#include "error.h"
|
||||
#include "platform.h"
|
||||
#include <stdalign.h>
|
||||
#include <stddef.h>
|
||||
|
||||
DRANG_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* @brief Allocates memory of the specified size.
|
||||
*
|
||||
* @param[in] size Size in bytes to allocate.
|
||||
* @return Pointer to the allocated memory, or NULL if allocation fails.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_ATTR(1)
|
||||
DRANG_MALLOC_ATTR
|
||||
DRANG_API void *drang_alloc(size_t size);
|
||||
|
||||
/**
|
||||
* @brief Allocates aligned memory of the specified size.
|
||||
*
|
||||
* @param[in] size Size in bytes to allocate.
|
||||
* @param[in] alignment Required alignment in bytes. Must be a power of 2.
|
||||
* @return Pointer to the allocated aligned memory, or NULL if allocation fails.
|
||||
* @remarks The alignment must be a power of 2 and greater than 0.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_ATTR(1)
|
||||
DRANG_ALLOC_ALIGN_ATTR(2)
|
||||
DRANG_MALLOC_ATTR
|
||||
DRANG_API void *drang_alloc_aligned(size_t size, size_t alignment);
|
||||
|
||||
/**
|
||||
* @brief Allocates zero-initialized memory for an array of elements.
|
||||
*
|
||||
* @param[in] num Number of elements to allocate.
|
||||
* @param[in] size Size of each element in bytes.
|
||||
* @return Pointer to the allocated zero-initialized memory, or NULL if allocation fails.
|
||||
* @remarks Similar to standard calloc(), all bytes are initialized to zero.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_COUNT_ATTR(1, 2)
|
||||
DRANG_MALLOC_ATTR
|
||||
DRANG_API void *drang_calloc(size_t num, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Allocates zero-initialized aligned memory for an array of elements.
|
||||
*
|
||||
* @param[in] num Number of elements to allocate.
|
||||
* @param[in] size Size of each element in bytes.
|
||||
* @param[in] alignment Required alignment in bytes. Must be a power of 2.
|
||||
* @return Pointer to the allocated zero-initialized aligned memory, or NULL if allocation fails.
|
||||
* @remarks Combines calloc and alignment functionality. All bytes are initialized to zero.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_COUNT_ATTR(1, 2)
|
||||
DRANG_ALLOC_ALIGN_ATTR(3)
|
||||
DRANG_MALLOC_ATTR
|
||||
DRANG_API void *drang_calloc_aligned(size_t num, size_t size, size_t alignment);
|
||||
|
||||
/**
|
||||
* @brief Reallocates memory to a new size.
|
||||
*
|
||||
* @param[in] ptr Pointer to previously allocated memory, or NULL.
|
||||
* @param[in] size New size in bytes.
|
||||
* @return Pointer to the reallocated memory, or NULL if allocation fails.
|
||||
* @remarks If ptr is NULL, behaves like drang_alloc().
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_ATTR(2)
|
||||
DRANG_API void *drang_realloc(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Reallocates aligned memory to a new size.
|
||||
*
|
||||
* @param[in] ptr Pointer to previously allocated memory, or NULL.
|
||||
* @param[in] size New size in bytes.
|
||||
* @param[in] alignment Required alignment in bytes. Must be a power of 2.
|
||||
* @return Pointer to the reallocated aligned memory, or NULL if allocation fails.
|
||||
* @remarks Maintains alignment during reallocation. The original alignment must match the new alignment.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_ATTR(2)
|
||||
DRANG_ALLOC_ALIGN_ATTR(3)
|
||||
DRANG_API void *drang_realloc_aligned(void *ptr, size_t size, size_t alignment);
|
||||
|
||||
/**
|
||||
* @brief Reallocates memory for an array and initializes new elements to zero.
|
||||
*
|
||||
* @param[in] ptr Pointer to previously allocated memory, or NULL.
|
||||
* @param[in] new_num New number of elements.
|
||||
* @param[in] size Size of each element in bytes.
|
||||
* @return Pointer to the reallocated memory, or NULL if allocation fails.
|
||||
* @remarks If the array grows, new elements are zero-initialized. Similar to _recalloc() on Windows.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_COUNT_ATTR(2, 3)
|
||||
DRANG_API void *drang_recalloc(
|
||||
void *ptr, size_t new_num, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Reallocates aligned memory for an array and initializes new elements to zero.
|
||||
*
|
||||
* @param[in] ptr Pointer to previously allocated memory, or NULL.
|
||||
* @param[in] new_num New number of elements.
|
||||
* @param[in] size Size of each element in bytes.
|
||||
* @param[in] alignment Required alignment in bytes. Must be a power of 2.
|
||||
* @return Pointer to the reallocated aligned memory, or NULL if allocation fails.
|
||||
* @remarks Combines recalloc and alignment functionality. New elements are zero-initialized.
|
||||
*/
|
||||
DRANG_ALLOC_SIZE_COUNT_ATTR(2, 3)
|
||||
DRANG_ALLOC_ALIGN_ATTR(4)
|
||||
DRANG_API void *drang_recalloc_aligned(
|
||||
void *ptr, size_t new_num, size_t size, size_t alignment);
|
||||
|
||||
/**
|
||||
* @brief Frees previously allocated memory.
|
||||
*
|
||||
* @param[in] ptr Pointer to memory to free, or NULL.
|
||||
* @remarks Safe to call with NULL pointer. Works with memory allocated by any drang allocation function.
|
||||
*/
|
||||
DRANG_API void drang_free(void *ptr);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Internal implementation macro for allocation with error handling.
|
||||
*
|
||||
* @param _Func_ Allocation function call to execute.
|
||||
* @return Pointer to allocated memory.
|
||||
* @remarks This macro calls the allocation function and automatically handles NULL return
|
||||
* by triggering DRANG error handling with DRANG_ENOMEM. Uses GCC statement expressions.
|
||||
*/
|
||||
#define DRANG_ALLOC_TRY_IMPL(_Func_) ({void* _tmp_ptr = (_Func_); DRANG_FAIL_IF_NULL_OOM(_tmp_ptr); _tmp_ptr; })
|
||||
|
||||
/**
|
||||
* @brief Allocates memory for a single object of the specified type with proper alignment.
|
||||
*
|
||||
* @param _Type_ The type to allocate memory for.
|
||||
* @return Pointer to allocated memory cast to the appropriate type.
|
||||
* @remarks Automatically uses sizeof() and alignof() for the type. More type-safe than raw allocation.
|
||||
*/
|
||||
#define DRANG_ALLOC_T(_Type_) ((_Type_ *) drang_alloc_aligned(sizeof(_Type_), alignof(_Type_)))
|
||||
|
||||
/**
|
||||
* @brief Allocates memory for an array of objects of the specified type with proper alignment.
|
||||
*
|
||||
* @param _Type_ The type to allocate memory for.
|
||||
* @param _Num_ Number of objects to allocate.
|
||||
* @return Pointer to allocated memory cast to the appropriate type.
|
||||
* @remarks Automatically calculates total size and uses proper alignment for the type.
|
||||
*/
|
||||
#define DRANG_ALLOC_T_N(_Type_, _Num_) ((_Type_ *) drang_alloc_aligned(sizeof(_Type_) * (_Num_), alignof(_Type_)))
|
||||
|
||||
/**
|
||||
* @brief Reallocates memory for an array of objects of the specified type with proper alignment.
|
||||
*
|
||||
* @param _Ptr_ Pointer to previously allocated memory.
|
||||
* @param _Type_ The type to reallocate memory for.
|
||||
* @param _Num_ New number of objects to allocate.
|
||||
* @return Pointer to reallocated memory cast to the appropriate type.
|
||||
* @remarks Maintains proper alignment during reallocation.
|
||||
*/
|
||||
#define DRANG_REALLOC_T(_Ptr_, _Type_, _Num_) ((_Type_ *) drang_realloc_aligned((_Ptr_), sizeof(_Type_) * (_Num_), alignof(_Type_)))
|
||||
|
||||
/**
|
||||
* @brief Allocates memory with automatic error handling.
|
||||
*
|
||||
* @param _Size_ Size in bytes to allocate.
|
||||
* @return Pointer to allocated memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails.
|
||||
*/
|
||||
#define DRANG_TRY_ALLOC(_Size_) DRANG_ALLOC_TRY_IMPL(drang_alloc((_Size_)))
|
||||
|
||||
/**
|
||||
* @brief Allocates aligned memory with automatic error handling.
|
||||
*
|
||||
* @param _Size_ Size in bytes to allocate.
|
||||
* @param _Alignment_ Required alignment in bytes.
|
||||
* @return Pointer to allocated aligned memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails.
|
||||
*/
|
||||
#define DRANG_TRY_ALLOC_ALIGNED(_Size_, _Alignment_) DRANG_ALLOC_TRY_IMPL(drang_alloc_aligned((_Size_), (_Alignment_)))
|
||||
|
||||
/**
|
||||
* @brief Allocates zero-initialized memory with automatic error handling.
|
||||
*
|
||||
* @param _Num_ Number of elements to allocate.
|
||||
* @param _Size_ Size of each element in bytes.
|
||||
* @return Pointer to allocated zero-initialized memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails.
|
||||
*/
|
||||
#define DRANG_TRY_CALLOC(_Num_, _Size_) DRANG_ALLOC_TRY_IMPL(drang_calloc((_Num_), (_Size_)))
|
||||
|
||||
/**
|
||||
* @brief Allocates zero-initialized aligned memory with automatic error handling.
|
||||
*
|
||||
* @param _Num_ Number of elements to allocate.
|
||||
* @param _Size_ Size of each element in bytes.
|
||||
* @param _Alignment_ Required alignment in bytes.
|
||||
* @return Pointer to allocated zero-initialized aligned memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails.
|
||||
*/
|
||||
#define DRANG_TRY_CALLOC_ALIGNED(_Num_, _Size_, _Alignment_) DRANG_ALLOC_TRY_IMPL(drang_calloc_aligned((_Num_), (_Size_), (_Alignment_)))
|
||||
|
||||
/**
|
||||
* @brief Reallocates memory with automatic error handling.
|
||||
*
|
||||
* @param _Ptr_ Pointer to previously allocated memory.
|
||||
* @param _Size_ New size in bytes.
|
||||
* @return Pointer to reallocated memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails.
|
||||
*/
|
||||
#define DRANG_TRY_REALLOC(_Ptr_, _Size_) DRANG_ALLOC_TRY_IMPL(drang_realloc((_Ptr_), (_Size_)))
|
||||
|
||||
/**
|
||||
* @brief Reallocates aligned memory with automatic error handling.
|
||||
*
|
||||
* @param _Ptr_ Pointer to previously allocated memory.
|
||||
* @param _Size_ New size in bytes.
|
||||
* @param _Alignment_ Required alignment in bytes.
|
||||
* @return Pointer to reallocated aligned memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails.
|
||||
*/
|
||||
#define DRANG_TRY_REALLOC_ALIGNED(_Ptr_, _Size_, _Alignment_) DRANG_ALLOC_TRY_IMPL(drang_realloc_aligned((_Ptr_), (_Size_), (_Alignment_)))
|
||||
|
||||
/**
|
||||
* @brief Reallocates memory for an array with zero-initialization and automatic error handling.
|
||||
*
|
||||
* @param _Ptr_ Pointer to previously allocated memory.
|
||||
* @param _New_Num_ New number of elements.
|
||||
* @param _Size_ Size of each element in bytes.
|
||||
* @return Pointer to reallocated memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails. New elements are zero-initialized.
|
||||
*/
|
||||
#define DRANG_TRY_RECALLOC(_Ptr_, _New_Num_, _Size_) DRANG_ALLOC_TRY_IMPL(drang_recalloc((_Ptr_), (_New_Num_), (_Size_)))
|
||||
|
||||
/**
|
||||
* @brief Reallocates aligned memory for an array with zero-initialization and automatic error handling.
|
||||
*
|
||||
* @param _Ptr_ Pointer to previously allocated memory.
|
||||
* @param _New_Num_ New number of elements.
|
||||
* @param _Size_ Size of each element in bytes.
|
||||
* @param _Alignment_ Required alignment in bytes.
|
||||
* @return Pointer to reallocated aligned memory.
|
||||
* @remarks Automatically triggers DRANG error handling if allocation fails. New elements are zero-initialized.
|
||||
*/
|
||||
#define DRANG_TRY_RECALLOC_ALIGNED(_Ptr_, _New_Num_, _Size_, _Alignment_) DRANG_ALLOC_TRY_IMPL(drang_recalloc_aligned((_Ptr_), (_New_Num_), (_Size_), (_Alignment_)))
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Allocates memory for a single typed object with automatic error handling.
|
||||
*
|
||||
* @param _Type_ The type to allocate memory for.
|
||||
* @return Pointer to allocated memory cast to the appropriate type.
|
||||
* @remarks Combines type-safe allocation with automatic error handling. Preferred for single object allocation.
|
||||
*/
|
||||
#define DRANG_TRY_ALLOC_T(_Type_) DRANG_ALLOC_TRY_IMPL(DRANG_ALLOC_T(_Type_))
|
||||
|
||||
/**
|
||||
* @brief Allocates memory for a typed array with automatic error handling.
|
||||
*
|
||||
* @param _Type_ The type to allocate memory for.
|
||||
* @param _Num_ Number of objects to allocate.
|
||||
* @return Pointer to allocated memory cast to the appropriate type.
|
||||
* @remarks Combines type-safe array allocation with automatic error handling. Preferred for array allocation.
|
||||
*/
|
||||
#define DRANG_TRY_ALLOC_T_N(_Type_, _Num_) DRANG_ALLOC_TRY_IMPL(DRANG_ALLOC_T_N(_Type_, (_Num_)))
|
||||
|
||||
/**
|
||||
* @brief Reallocates memory for a typed array with automatic error handling.
|
||||
*
|
||||
* @param _Ptr_ Pointer to previously allocated memory.
|
||||
* @param _Type_ The type to reallocate memory for.
|
||||
* @param _Num_ New number of objects to allocate.
|
||||
* @return Pointer to reallocated memory cast to the appropriate type.
|
||||
* @remarks Combines type-safe array reallocation with automatic error handling. Preferred for array reallocation.
|
||||
*/
|
||||
#define DRANG_TRY_REALLOC_T(_Ptr_, _Type_, _Num_) DRANG_ALLOC_TRY_IMPL(DRANG_REALLOC_T((_Ptr_), (_Type_), (_Num_)))
|
||||
|
||||
DRANG_END_DECLS
|
||||
41
Source/DrangPlatform/Source/alloc.c
Normal file
41
Source/DrangPlatform/Source/alloc.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include <drang/alloc.h>
|
||||
#include <mimalloc.h>
|
||||
|
||||
|
||||
void *drang_alloc(size_t size)
|
||||
{
|
||||
return mi_malloc(size);
|
||||
}
|
||||
void *drang_alloc_aligned(size_t size, size_t alignment)
|
||||
{
|
||||
return mi_malloc_aligned(size, alignment);
|
||||
}
|
||||
void *drang_calloc(size_t num, size_t size)
|
||||
{
|
||||
return mi_calloc(num, size);
|
||||
}
|
||||
void *drang_calloc_aligned(size_t num, size_t size, size_t alignment)
|
||||
{
|
||||
return mi_calloc_aligned(num, size, alignment);
|
||||
}
|
||||
void *drang_realloc(void *ptr, size_t size)
|
||||
{
|
||||
return mi_realloc(ptr, size);
|
||||
}
|
||||
void *drang_realloc_aligned(void *ptr, size_t size, size_t alignment)
|
||||
{
|
||||
return mi_realloc_aligned(ptr, size, alignment);
|
||||
}
|
||||
void *drang_recalloc(void *ptr, size_t new_num, size_t size)
|
||||
{
|
||||
return mi_recalloc(ptr, new_num, size);
|
||||
}
|
||||
void *drang_recalloc_aligned(
|
||||
void *ptr, size_t new_num, size_t size, size_t alignment)
|
||||
{
|
||||
return mi_recalloc_aligned(ptr, new_num, size, alignment);
|
||||
}
|
||||
void drang_free(void *ptr)
|
||||
{
|
||||
mi_free(ptr);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue