Improve sarena.h

This commit is contained in:
Nils O. Selåsdal
2026-04-21 13:20:07 +02:00
parent afc3148de3
commit 36457f775f
+17 -9
View File
@@ -40,7 +40,7 @@ struct UCSTmpAlloc {
* Use as * Use as
* @code * @code
* _Alignas(16) char v[128]; * _Alignas(16) char v[128];
* UCSArena a = UC_BV_STATIC_INITIALIZER(v); * UCSArena a = UC_SAR_STATIC_INITIALIZER(v);
* @endcode * @endcode
*/ */
#define UC_SAR_STATIC_INITIALIZER(data) UC_SAR_INITIALIZER((data), sizeof(data)) #define UC_SAR_STATIC_INITIALIZER(data) UC_SAR_INITIALIZER((data), sizeof(data))
@@ -49,15 +49,20 @@ struct UCSTmpAlloc {
* Use as * Use as
* @code * @code
* char v[128]; * char v[128];
* UCSArena a = UC_BV_STATIC_INITIALIZER(v, sizeof v); * UCSArena a = UC_SAR_INITIALIZER(v, sizeof v);
* @endcode * @endcode
* or * or
* @code * @code
* char *m = malloc(128); * char *m = malloc(128);
* UCSArena a = UC_BV_INIT(m, 128); * UCSArena a = UC_SAR_INITIALIZER(m, 128);
* @endcode * @endcode
*/ */
#define UC_SAR_INITIALIZER(data, sz) {(data), (data), (data) + sz} #define UC_SAR_INITIALIZER(data, sz) {\
.start = (data),\
.curr = (data),\
.end=(data) + sz,\
.tmp_allocs = 0\
}
/** Initialize a UCSArena with an array as the backing memory to allocate from. /** Initialize a UCSArena with an array as the backing memory to allocate from.
* The macro can be used at local scope to allocate memory automatic on the stack, * The macro can be used at local scope to allocate memory automatic on the stack,
@@ -111,7 +116,7 @@ static inline UCSTmpAlloc uc_sar_tmp_begin(UCSArena *arena)
return state; return state;
} }
// end temporary allocations, releaseing all allocations since the most recent uc_sar_tmp_begin // end temporary allocations, releasing all allocations since the most recent uc_sar_tmp_begin
static inline void uc_sar_tmp_end(const UCSTmpAlloc *state) static inline void uc_sar_tmp_end(const UCSTmpAlloc *state)
{ {
UCSArena *arena = state->arena; UCSArena *arena = state->arena;
@@ -121,9 +126,9 @@ static inline void uc_sar_tmp_end(const UCSTmpAlloc *state)
} }
// Allocate @sz bytes from the UCSArena. Returns NULL if not enough space // Allocate @sz bytes from the UCSArena. Returns NULL if not enough space
void *uc_sar_alloc(UCSArena *arena, size_t sz) static inline void *uc_sar_alloc(UCSArena *arena, size_t sz)
{ {
if (arena->curr + sz > arena->end) { if (sz > (arena->curr - arena->end)) {
return NULL; return NULL;
} }
void *start = arena->curr; void *start = arena->curr;
@@ -133,7 +138,7 @@ void *uc_sar_alloc(UCSArena *arena, size_t sz)
// Allocate @sz bytes from the UCSArena, returned pointer is aligned to @align // Allocate @sz bytes from the UCSArena, returned pointer is aligned to @align
// Returns NULL if not enough space // Returns NULL if not enough space
void *uc_sar_alloc_aligned(UCSArena *arena, size_t sz, unsigned int align) [[gnu::alloc_align(3)]] static inline void *uc_sar_alloc_aligned(UCSArena *arena, size_t sz, unsigned int align) [[gnu::alloc_align(3)]]
{ {
assert(align != 0); assert(align != 0);
assert((align & (align - 1)) == 0); // power of 2 assert((align & (align - 1)) == 0); // power of 2
@@ -142,7 +147,8 @@ void *uc_sar_alloc_aligned(UCSArena *arena, size_t sz, unsigned int align) [[gnu
uintptr_t aligned = (curr + (align - (uintptr_t)1)) & ~(align - (uintptr_t)1); uintptr_t aligned = (curr + (align - (uintptr_t)1)) & ~(align - (uintptr_t)1);
unsigned char *start = (unsigned char *)aligned; unsigned char *start = (unsigned char *)aligned;
if (start + sz > arena->end) { if (sz > (arena->curr - arena->end)) {
return NULL; return NULL;
} }
@@ -151,6 +157,8 @@ void *uc_sar_alloc_aligned(UCSArena *arena, size_t sz, unsigned int align) [[gnu
return start; return start;
} }
// reset arena, making all memory available for allocation
// also invalidates any UCSTmpAlloc instances.
static inline void uc_sar_reset(UCSArena *arena) static inline void uc_sar_reset(UCSArena *arena)
{ {
arena->curr = arena->start; arena->curr = arena->start;