Update sarena.h, header only now
This commit is contained in:
+67
-12
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -82,8 +83,8 @@ struct UCSTmpAlloc {
|
|||||||
#define UC_SAR_ALLOC_DEF(var_name, size_) \
|
#define UC_SAR_ALLOC_DEF(var_name, size_) \
|
||||||
struct { \
|
struct { \
|
||||||
_Alignas(16) char memory[size_]; \
|
_Alignas(16) char memory[size_]; \
|
||||||
} var_name##_memory; \
|
} var_name##_arena_memory; \
|
||||||
UCSArena var_name = UC_SAR_STATIC_INITIALIZER(var_name##_memory.memory)
|
UCSArena var_name = UC_SAR_STATIC_INITIALIZER(var_name##_arena_memory.memory)
|
||||||
|
|
||||||
/** Allocate space for @type_ , returned memory is aligned to requirements
|
/** Allocate space for @type_ , returned memory is aligned to requirements
|
||||||
* of @type.
|
* of @type.
|
||||||
@@ -99,29 +100,83 @@ struct UCSTmpAlloc {
|
|||||||
#define UC_SAR_ALLOC_ALIGNED(allocator, type_) uc_sar_alloc_aligned((allocator), sizeof(type_), _Alignof(type_))
|
#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
|
// 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;
|
arena->start = arena->curr = (unsigned char *)memory;
|
||||||
a->end = a->start + sz;
|
arena->end = arena->start + sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin temporary allocation. All allocations afterwards will be released in uc_sar_tmp_end
|
// 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
|
// 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
|
// 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
|
// 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 *a, size_t sz, unsigned int align) [[gnu::alloc_align(2)]];
|
void *uc_sar_alloc_aligned(UCSArena *arena, size_t sz, unsigned int align) [[gnu::alloc_align(3)]]
|
||||||
|
|
||||||
static inline void uc_sar_reset(UCSArena *a)
|
|
||||||
{
|
{
|
||||||
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#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--;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user