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