v1.2.2
This commit is contained in:
40
arena.h
40
arena.h
@@ -1,4 +1,4 @@
|
||||
// arena.h - v1.2.1 - MIT License
|
||||
// arena.h - v1.2.2 - MIT License
|
||||
// single header library for region-based memory management.
|
||||
//
|
||||
// [License and changelog]
|
||||
@@ -21,18 +21,19 @@
|
||||
// Note: every compile-time option listed here should be configured before
|
||||
// the #include "arena.h"
|
||||
//
|
||||
// #define ARENA_REGION_CAPACITY new_region_capacity_in_bytes (4096)
|
||||
// #define ARENA_REGION_CAPACITY new_region_capacity_in_bytes (8*1024)
|
||||
//
|
||||
// This macro defines the default capacity for arena regions.
|
||||
//
|
||||
// #define ARENA_REGION_GROWTH_FACTOR new_region_growth_factor (1.5f)
|
||||
// #define ARENA_REGION_GROWTH_FACTOR new_region_growth_factor (2)
|
||||
//
|
||||
// This macro defines the growth factor of the capacity for every
|
||||
// subsequent region in all arenas.
|
||||
//
|
||||
// #define ARENA_ALIGNMENT alignment (8)
|
||||
// #define ARENA_ALIGNMENT alignment (alignof(max_align_t))
|
||||
//
|
||||
// This macro defines the memory alignment used for allocations.
|
||||
// Must be a power of two.
|
||||
//
|
||||
// #define ARENA_NO_ASSERT
|
||||
//
|
||||
@@ -159,7 +160,7 @@ int main(void)
|
||||
#endif // ARENA_REGION_CAPACITY
|
||||
|
||||
#ifndef ARENA_REGION_GROWTH_FACTOR
|
||||
# define ARENA_REGION_GROWTH_FACTOR 1.5f
|
||||
# define ARENA_REGION_GROWTH_FACTOR 2
|
||||
#endif // ARENA_REGION_GROWTH_FACTOR
|
||||
|
||||
#ifndef ARENA_ALIGNMENT
|
||||
@@ -300,23 +301,29 @@ void *arena_alloc(Arena *a, size_t size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ensure memory alignment of requested size
|
||||
size = arena__align(size);
|
||||
|
||||
// Check for overflow
|
||||
if (size > SIZE_MAX - sizeof(Arena_Region)) {
|
||||
ARENA_ASSERT(false && "Requested size too large");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ensure memory alignment of requested size
|
||||
size = arena__align(size);
|
||||
|
||||
// Get the next region capacity multiplied by the growth factor
|
||||
size_t region_capacity = (a->region_capacity == 0
|
||||
? ARENA_REGION_CAPACITY : a->region_capacity);
|
||||
if (a->tail != NULL) {
|
||||
region_capacity = a->tail->capacity * ARENA_REGION_GROWTH_FACTOR;
|
||||
size_t max_cap = (SIZE_MAX / 2) - sizeof(Arena_Region);
|
||||
|
||||
if (a->tail->capacity >= max_cap / (ARENA_REGION_GROWTH_FACTOR)) {
|
||||
region_capacity = max_cap;
|
||||
} else {
|
||||
region_capacity = a->tail->capacity * (ARENA_REGION_GROWTH_FACTOR);
|
||||
// Edge case for small growth factors
|
||||
if (region_capacity <= a->tail->capacity) {
|
||||
region_capacity = a->tail->capacity + 1;
|
||||
region_capacity = a->tail->capacity + (4 * 1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +351,9 @@ void *arena_alloc(Arena *a, size_t size)
|
||||
|
||||
// Find first suitable region
|
||||
Arena_Region *r = a->tail;
|
||||
Arena_Region *last = r;
|
||||
while (r != NULL && size > r->capacity - r->count) {
|
||||
last = r;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
@@ -354,18 +363,19 @@ void *arena_alloc(Arena *a, size_t size)
|
||||
ARENA_ASSERT(false && "Region count overflow");
|
||||
return NULL;
|
||||
}
|
||||
a->tail = r;
|
||||
r->count += size;
|
||||
return r->data + r->count - size;
|
||||
}
|
||||
|
||||
// If not found append a new region
|
||||
a->tail->next = (Arena_Region*)ARENA_MALLOC(sizeof(*a->tail) + alloc_size);
|
||||
if (a->tail->next == NULL) {
|
||||
last->next = (Arena_Region*)ARENA_MALLOC(sizeof(*a->tail) + alloc_size);
|
||||
if (last->next == NULL) {
|
||||
ARENA_ASSERT(false && "Allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
a->tail = a->tail->next;
|
||||
a->tail = last->next;
|
||||
a->tail->next = NULL;
|
||||
a->tail->count = size;
|
||||
a->tail->capacity = alloc_size;
|
||||
@@ -434,7 +444,7 @@ char *arena_sprintf(Arena *a, const char *fmt, ...)
|
||||
size_t needed = (size_t)n + 1;
|
||||
|
||||
// If it fits commit and return
|
||||
if (needed <= available) {
|
||||
if (arena__align(needed) <= available) {
|
||||
r->count += arena__align(needed);
|
||||
va_end(args);
|
||||
return result;
|
||||
@@ -508,6 +518,8 @@ size_t arena__align(size_t n)
|
||||
/*
|
||||
* Revision history:
|
||||
*
|
||||
* 1.2.2 (2026-07-07) Fix various memory problems;
|
||||
* make ARENA_REGION_GROWTH_FACTOR an integer
|
||||
* 1.2.1 (2026-04-08) Region growth factor handling with new
|
||||
* ARENA_REGION_GROWTH_FACTOR macro
|
||||
* 1.2.0 (2026-04-08) New functions: arena_sprintf(), arena_snapshot(),
|
||||
|
||||
Reference in New Issue
Block a user