Added arena library
This commit is contained in:
parent
4c73ae4f20
commit
7ebd70c59c
|
@ -0,0 +1,96 @@
|
|||
// UFN Arena library. MIT-Licensed (c) Eric-Paul Ickhorn (epickh)
|
||||
|
||||
#ifndef UFN_ARENA_H
|
||||
#define UFN_ARENA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define UFN_UNLIMITED_ARENA 0xffffffff
|
||||
|
||||
typedef struct ufn_arena ufn_arena_s;
|
||||
|
||||
struct ufn_arena
|
||||
{
|
||||
uint32_t capacity;
|
||||
uint32_t usage;
|
||||
char *allocation;
|
||||
|
||||
uint32_t maximum;
|
||||
ufn_arena_s *continuation;
|
||||
};
|
||||
|
||||
ufn_arena_s * ufn_new_dynamic_arena(uint32_t capacity, uint32_t max_tree_size);
|
||||
ufn_arena_s * ufn_new_static_arena(uint32_t capacity);
|
||||
void ufn_free_arena(ufn_arena_s *arena);
|
||||
|
||||
void * ufn_arena_alloc(ufn_arena_s *arena, uint32_t size);
|
||||
|
||||
|
||||
|
||||
#ifdef UFN_IMPLEMENTATION
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
ufn_arena_s * ufn_new_dynamic_arena(uint32_t capacity, uint32_t max_tree_size)
|
||||
{
|
||||
ufn_arena_s *arena = malloc(sizeof(ufn_arena_s));
|
||||
arena->capacity = capacity;
|
||||
arena->usage = 0;
|
||||
arena->allocation = malloc(capacity);
|
||||
arena->maximum = max_tree_size;
|
||||
arena->continuation = NULL;
|
||||
return arena;
|
||||
}
|
||||
ufn_arena_s * ufn_new_static_arena(uint32_t capacity)
|
||||
{
|
||||
return ufn_new_dynamic_arena(capacity, 0);
|
||||
}
|
||||
|
||||
void ufn_free_arena(ufn_arena_s *arena)
|
||||
{
|
||||
if(arena->continuation != NULL)
|
||||
{
|
||||
ufn_free_arena(arena->continuation);
|
||||
}
|
||||
free(arena->allocation);
|
||||
free(arena);
|
||||
}
|
||||
|
||||
void * ufn_arena_alloc(ufn_arena_s *arena, uint32_t size)
|
||||
{
|
||||
if((arena->usage = size) >= arena->capacity)
|
||||
{
|
||||
if(arena->continuation == NULL)
|
||||
{
|
||||
uint32_t continuation_size = arena->capacity * 2;
|
||||
// Clamp the continuation's size to the maximum allowed one.
|
||||
if(continuation_size > (arena->maximum))
|
||||
{
|
||||
continuation_size = arena->maximum;
|
||||
}
|
||||
uint32_t continued_maximum = continuation_size - arena->maximum;
|
||||
// If no continuation of this arena tree can fulfill
|
||||
// a request of this size,
|
||||
// -> Deny the request and return NULL.
|
||||
if(size > arena->maximum)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// If no more arena can be allocated (The tree has its maximum size)
|
||||
// -> return NULL.
|
||||
if(continuation_size == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
arena->continuation = ufn_new_dynamic_arena(continuation_size, continued_maximum);
|
||||
}
|
||||
ufn_arena_alloc(arena->continuation, size);
|
||||
}
|
||||
void *block = arena->allocation + arena->usage;
|
||||
arena->usage += size;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
#endif // UFN_IMPLEMENTATION
|
||||
#endif // UFN_ARENA_H
|
Loading…
Reference in New Issue