diff --git a/include/ucore/sarena.h b/include/ucore/sarena.h index 29f7188..4303eee 100644 --- a/include/ucore/sarena.h +++ b/include/ucore/sarena.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif @@ -82,8 +83,8 @@ struct UCSTmpAlloc { #define UC_SAR_ALLOC_DEF(var_name, size_) \ struct { \ _Alignas(16) char memory[size_]; \ - } var_name##_memory; \ - UCSArena var_name = UC_SAR_STATIC_INITIALIZER(var_name##_memory.memory) + } var_name##_arena_memory; \ + UCSArena var_name = UC_SAR_STATIC_INITIALIZER(var_name##_arena_memory.memory) /** Allocate space for @type_ , returned memory is aligned to requirements * of @type. @@ -99,29 +100,83 @@ struct UCSTmpAlloc { #define UC_SAR_ALLOC_ALIGNED(allocator, type_) uc_sar_alloc_aligned((allocator), sizeof(type_), _Alignof(type_)) // Initialize an UCSArena to allocate from @mem which is @sz bytes -static inline void uc_sar_init(UCSArena *a, void *mem, size_t sz) +static inline void uc_sar_init(UCSArena *arena, void *memory, size_t sz) { - a->start = a->curr = mem; - a->end = a->start + sz; + arena->start = arena->curr = (unsigned char *)memory; + arena->end = arena->start + sz; } // begin temporary allocation. All allocations afterwards will be released in uc_sar_tmp_end -UCSTmpAlloc uc_sar_tmp_begin(UCSArena *a); +static inline UCSTmpAlloc uc_sar_tmp_begin(UCSArena *arena) +{ + UCSTmpAlloc state = {.alloc_point = arena->curr, .arena = arena}; + arena->tmp_allocs++; + return state; +} // end temporary allocations, releaseing all allocations since the most recent uc_sar_tmp_begin -void uc_sar_tmp_end(const UCSTmpAlloc *state); +static inline void uc_sar_tmp_end(const UCSTmpAlloc *state) +{ + UCSArena *arena = state->arena; + assert(arena->tmp_allocs > 0); + arena->curr = state->alloc_point; + arena->tmp_allocs--; +} // Allocate @sz bytes from the UCSArena. Returns NULL if not enough space -void *uc_sar_alloc(UCSArena *a, size_t sz); +void *uc_sar_alloc(UCSArena *arena, size_t sz) +{ + if (arena->curr + sz > arena->end) { + return NULL; + } + void *start = arena->curr; + arena->curr += sz; + return start; +} // Allocate @sz bytes from the UCSArena, returned pointer is aligned to @align // Returns NULL if not enough space -void *uc_sar_alloc_aligned(UCSArena *a, size_t sz, unsigned int align) [[gnu::alloc_align(2)]]; - -static inline void uc_sar_reset(UCSArena *a) +void *uc_sar_alloc_aligned(UCSArena *arena, size_t sz, unsigned int align) [[gnu::alloc_align(3)]] { - a->curr = a->start; + assert(align != 0); + assert((align & (align - 1)) == 0); // power of 2 + + uintptr_t curr = (uintptr_t)arena->curr; + uintptr_t aligned = (curr + (align - (uintptr_t)1)) & ~(align - (uintptr_t)1); + unsigned char *start = (unsigned char *)aligned; + + if (start + sz > arena->end) { + return NULL; + } + + arena->curr = start + sz; + + return start; } + +static inline void uc_sar_reset(UCSArena *arena) +{ + arena->curr = arena->start; +} + +// Arena size in bytes +static inline size_t uc_sar_size(const UCSArena *arena) +{ + return (size_t)(arena->end - arena->start); +} + +// Used bytes of the arena +static inline size_t uc_sar_used(const UCSArena *arena) +{ + return (size_t)(arena->curr - arena->start); +} + +// Available unused bytes in the arena +static inline size_t uc_sar_available(const UCSArena *arena) +{ + return uc_sar_size(arena) - uc_sar_used(arena); +} + #ifdef __cplusplus } #endif diff --git a/src/sarena.c b/src/sarena.c deleted file mode 100644 index 77782a0..0000000 --- a/src/sarena.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include "ucore/sarena.h" - -void *uc_sar_alloc(UCSArena *a, size_t sz) -{ - if (a->curr + sz > a->end) { - return NULL; - } - void *start = a->curr; - a->curr += sz; - return start; -} - -void *uc_sar_alloc_aligned(UCSArena *a, size_t sz, unsigned int align) -{ - assert(align != 0); - assert((align & (align - 1)) == 0); // power of 2 - - uintptr_t curr = (uintptr_t)a->curr; - uintptr_t aligned = (curr + (align - (uintptr_t)1)) & ~(align - (uintptr_t)1); - unsigned char *start = (unsigned char *)aligned; - - if (start + sz > a->end) { - return NULL; - } - - a->curr = start + sz; - - return start; -} - -UCSTmpAlloc uc_sar_tmp_begin(UCSArena *a) -{ - UCSTmpAlloc state = {.alloc_point = a->curr, .arena = a}; - a->tmp_allocs++; - return state; -} - -void uc_sar_tmp_end(const UCSTmpAlloc *state) -{ - UCSArena *a = state->arena; - assert(a->tmp_allocs > 0); - a->curr = state->alloc_point; - a->tmp_allocs--; -}