Update sarena.h, header only now
This commit is contained in:
+67
-12
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#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
|
||||
|
||||
Reference in New Issue
Block a user