agrego practicas
This commit is contained in:
+178
@@ -0,0 +1,178 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ARENA_MEMORY_ALIGN 8
|
||||
|
||||
typedef struct Chunk{
|
||||
size_t size;
|
||||
size_t offset;
|
||||
unsigned char *buffer;
|
||||
struct Chunk *next;
|
||||
}Chunk;
|
||||
|
||||
typedef struct{
|
||||
Chunk *current;
|
||||
Chunk *first;
|
||||
}Arena;
|
||||
|
||||
Arena arena_create(size_t);
|
||||
void* arena_alloc(Arena*, size_t);
|
||||
void arena_free(Arena*);
|
||||
void arena_print(Arena*);
|
||||
|
||||
Chunk* arena_chunk_create(size_t);
|
||||
void arena_chunk_free(Chunk*);
|
||||
void* arena_chunk_alloc(Arena*, Chunk*, size_t);
|
||||
|
||||
int main(void){
|
||||
|
||||
Arena arena = arena_create(32);
|
||||
|
||||
arena_print(&arena);
|
||||
|
||||
arena_alloc(&arena, 100);
|
||||
|
||||
arena_print(&arena);
|
||||
|
||||
arena_alloc(&arena, 40);
|
||||
|
||||
arena_print(&arena);
|
||||
|
||||
arena_free(&arena);
|
||||
|
||||
arena_print(&arena);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* arena_chunk_alloc(Arena* ref_arena, Chunk* chunk, size_t s){
|
||||
size_t aligned = (chunk->offset + (ARENA_MEMORY_ALIGN - 1)) & ~(ARENA_MEMORY_ALIGN -1);
|
||||
if ((aligned + s <= chunk->size)){
|
||||
chunk->offset = aligned;
|
||||
void* start = (void *)(chunk->buffer + chunk->offset);
|
||||
chunk->offset = aligned + s;
|
||||
return start;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Chunk* arena_chunk_create(size_t s){
|
||||
printf("Creating a new chunk of %zu bytes\n", s);
|
||||
Chunk* chunk1 = (Chunk*)malloc(sizeof(Chunk));
|
||||
|
||||
if(chunk1 == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chunk1->size = s;
|
||||
chunk1->offset = 0;
|
||||
chunk1->next = NULL;
|
||||
|
||||
chunk1->buffer = (unsigned char *)malloc(s);
|
||||
|
||||
if(chunk1->buffer == NULL){
|
||||
perror("Error creando chunk...\n");
|
||||
free(chunk1);
|
||||
chunk1 = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("Chunk creado correctamente\n");
|
||||
|
||||
return chunk1;
|
||||
|
||||
}
|
||||
|
||||
void arena_chunk_free(Chunk* chunk){
|
||||
printf("Liberando %zu bytes de memoria\n", chunk->size);
|
||||
if(chunk->buffer != NULL){
|
||||
free(chunk->buffer);
|
||||
chunk->buffer = NULL;
|
||||
}
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
void* arena_alloc(Arena* ref_arena, size_t s){
|
||||
if(ref_arena == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ref_arena->current == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Chunk* current_chunk = ref_arena->current;
|
||||
|
||||
void* ptr = arena_chunk_alloc(ref_arena, current_chunk, s);
|
||||
|
||||
if(ptr == NULL){
|
||||
|
||||
size_t new_size = current_chunk->size * 2;
|
||||
|
||||
if(new_size < s){
|
||||
new_size = s;
|
||||
}
|
||||
|
||||
Chunk *new_chunk = arena_chunk_create(new_size);
|
||||
if(new_chunk == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_chunk->next = new_chunk;
|
||||
new_chunk->next = NULL;
|
||||
ref_arena->current = new_chunk;
|
||||
|
||||
return arena_alloc(ref_arena, s);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Arena arena_create(size_t s){
|
||||
Arena new_arena = {
|
||||
.current = NULL,
|
||||
.first = NULL
|
||||
};
|
||||
|
||||
Chunk* chunk1 = arena_chunk_create(s);
|
||||
|
||||
if(chunk1 == NULL){
|
||||
perror("Error creando arena\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
new_arena.current = chunk1;
|
||||
new_arena.first = chunk1;
|
||||
|
||||
printf("Arena creada correctamente\n");
|
||||
|
||||
return new_arena;
|
||||
|
||||
}
|
||||
|
||||
void arena_free(Arena* ref_arena){
|
||||
Chunk* item = ref_arena->first;
|
||||
while (item != NULL) {
|
||||
Chunk *next = item->next;
|
||||
arena_chunk_free(item);
|
||||
item = next;
|
||||
}
|
||||
|
||||
ref_arena->first = NULL;
|
||||
ref_arena->current = NULL;
|
||||
|
||||
printf("Arena liberada\n");
|
||||
}
|
||||
|
||||
void arena_print(Arena* ref_arena){
|
||||
printf("ARENA INFO\n");
|
||||
printf("==========\n");
|
||||
|
||||
printf("first: %p\n", ref_arena->first);
|
||||
printf("next: %p\n", ref_arena->current);
|
||||
|
||||
printf("==========\n");
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user