#include #include #include #include #include #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; } }