121 lines
2.4 KiB
C
121 lines
2.4 KiB
C
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
#define ARENA_ALIGN 8
|
|
|
|
typedef struct{
|
|
unsigned char *buffer;
|
|
size_t size;
|
|
size_t offset;
|
|
}Arena;
|
|
|
|
Arena arena_create(size_t);
|
|
void* arena_alloc(Arena *, size_t);
|
|
void arena_reset(Arena *);
|
|
void arena_destroy(Arena *);
|
|
bool arena_is_aligned(size_t);
|
|
size_t arena_checkpoint(Arena*);
|
|
void arena_restore(Arena*, size_t);
|
|
|
|
int main(void){
|
|
Arena arena = arena_create(32);
|
|
|
|
size_t cp0 = arena_checkpoint(&arena);
|
|
int* x = (int*)arena_alloc(&arena, 8);
|
|
|
|
*x = 21;
|
|
|
|
arena_alloc(&arena, 8);
|
|
size_t cp1 = arena_checkpoint(&arena);
|
|
int* tmp = (int*)arena_alloc(&arena, 8);
|
|
|
|
arena_restore(&arena, cp1);
|
|
|
|
printf("x:%d\n", *x);
|
|
|
|
arena_alloc(&arena, 16);
|
|
|
|
arena_restore(&arena, cp0);
|
|
|
|
arena_alloc(&arena, 32);
|
|
|
|
arena_destroy(&arena);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void arena_restore(Arena* ref_arena, size_t chk){
|
|
ref_arena->offset = chk;
|
|
}
|
|
|
|
size_t arena_checkpoint(Arena* ref_arena){
|
|
return ref_arena->offset;
|
|
}
|
|
|
|
bool arena_is_aligned(size_t pos){
|
|
size_t mask = 7;
|
|
return (pos & mask) == 0;
|
|
}
|
|
|
|
Arena arena_create( size_t bytes){
|
|
Arena new_arena = {
|
|
.buffer = NULL,
|
|
.size = bytes,
|
|
.offset = 0
|
|
};
|
|
|
|
new_arena.buffer = (unsigned char *)malloc(bytes);
|
|
|
|
if(new_arena.buffer == NULL){
|
|
perror("Error asignando memoria");
|
|
exit(1);
|
|
}
|
|
|
|
return new_arena;
|
|
|
|
}
|
|
void* arena_alloc(Arena *ref_arena, size_t bytes){
|
|
|
|
if(ref_arena->buffer == NULL){
|
|
return NULL;
|
|
}
|
|
|
|
size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1));
|
|
|
|
if(aligned + bytes > ref_arena->size){
|
|
printf("arena_alloc(%d): NULL \n", (int) bytes);
|
|
return NULL;
|
|
}
|
|
void* ptr_ref = ref_arena->buffer + aligned;
|
|
|
|
printf("arena_alloc(%d) ", (int) bytes);
|
|
|
|
if(arena_is_aligned((size_t)ptr_ref)){
|
|
printf("aligned: true ");
|
|
}else{
|
|
printf("aligned: false ");
|
|
}
|
|
|
|
printf(" base + %d", (int)aligned);
|
|
printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned);
|
|
|
|
ref_arena->offset = aligned + bytes;
|
|
|
|
return ptr_ref;
|
|
}
|
|
|
|
void arena_reset(Arena *ref_arena){
|
|
ref_arena->offset = 0;
|
|
}
|
|
|
|
void arena_destroy(Arena *ref_arena){
|
|
if(ref_arena->buffer != NULL){
|
|
free(ref_arena->buffer);
|
|
ref_arena->buffer = NULL;
|
|
}
|
|
}
|
|
|