libdiscord

libdiscord.git
git clone git://git.lenczewski.org/libdiscord.git
Log | Files | Refs | README | LICENSE

arena.h (1060B)


      1 #ifndef ARENA_H
      2 #define ARENA_H
      3 
      4 #include <assert.h>
      5 #include <stdalign.h>
      6 #include <stddef.h>
      7 #include <stdint.h>
      8 
      9 #define IS_POW2(v) (((v) & ((v) - 1)) == 0)
     10 
     11 #define IS_ALIGNED(v, align) (((v) & ((align) - 1)) == 0)
     12 #define ALIGN_PREV(v, align) ((v) & ~((align) - 1))
     13 #define ALIGN_NEXT(v, align) ALIGN_PREV((v) + ((align) - 1), (align))
     14 
     15 struct arena {
     16 	void *ptr;
     17 	size_t cap, len;
     18 };
     19 
     20 inline void
     21 arena_reset(struct arena *arena)
     22 {
     23 	arena->len = 0;
     24 }
     25 
     26 inline void *
     27 arena_alloc(struct arena *arena, size_t size, size_t alignment)
     28 {
     29 	assert(size);
     30 	assert(alignment);
     31 	assert(IS_POW2(alignment));
     32 
     33 	uintptr_t base = (uintptr_t) arena->ptr;
     34 	uintptr_t end = base + arena->cap;
     35 
     36 	uintptr_t aligned_ptr = ALIGN_NEXT(base + arena->len, alignment);
     37 	if (end < aligned_ptr + size)
     38 		return NULL;
     39 
     40 	arena->len = (aligned_ptr + size) - base;
     41 
     42 	return (void *) aligned_ptr;
     43 }
     44 
     45 #define ARENA_ALLOC_ARRAY(arena, T, n) \
     46 	arena_alloc((arena), sizeof(T) * (n), alignof(T))
     47 
     48 #define ARENA_ALLOC_SIZED(arena, T) \
     49 	ARENA_ALLOC_ARRAY((arena), T, 1)
     50 
     51 #endif /* ARENA_H */