various fixes for arena allocator
This commit is contained in:
parent
c0afc54ca1
commit
2f8a8ed763
2 changed files with 40 additions and 63 deletions
59
core/arena.c
59
core/arena.c
|
|
@ -3,54 +3,39 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct arena_allocator *arena_init(usize size)
|
arena arena_init(usize size)
|
||||||
{
|
{
|
||||||
struct arena_allocator *allocator =
|
return (arena){
|
||||||
(struct arena_allocator *)malloc(sizeof(struct arena_allocator));
|
.capacity = size,
|
||||||
allocator->size = size;
|
.position = 0,
|
||||||
allocator->base = (usize) malloc(size);
|
.memory = malloc(size),
|
||||||
allocator->position = 0;
|
};
|
||||||
|
|
||||||
return allocator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void arena_deinit(struct arena_allocator *allocator)
|
void *arena_alloc(arena *a, usize size)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
if (a->position + size > a->capacity) return NULL;
|
||||||
if (!allocator) {
|
void *ret = (void *)((usize)a->memory + (usize)a->position);
|
||||||
log_error("attempt to free NULL arena\n");
|
a->position += size;
|
||||||
return;
|
return ret;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
free((void *)allocator->base);
|
|
||||||
free((void *)allocator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *arena_alloc(struct arena_allocator *allocator, usize size)
|
snapshot arena_snapshot(arena a)
|
||||||
{
|
{
|
||||||
if (allocator->position + size >= allocator->size) {
|
return a.position;
|
||||||
allocator->size = allocator->position + size;
|
|
||||||
allocator->base =
|
|
||||||
(usize) realloc((void *)allocator->base,
|
|
||||||
allocator->size + allocator->size / 2);
|
|
||||||
}
|
|
||||||
void *ptr = (void *)(allocator->base + allocator->position);
|
|
||||||
allocator->position += size;
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *arena_zalloc(struct arena_allocator *allocator, usize size)
|
void arena_reset_to_snapshot(arena *a, snapshot s)
|
||||||
{
|
{
|
||||||
void *ptr = arena_alloc(allocator, size);
|
a->position = s;
|
||||||
for (usize i = 0; i < size; i++) {
|
|
||||||
((u8 *) ptr)[i] = 0x0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
void arena_reset(arena *a)
|
||||||
}
|
|
||||||
|
|
||||||
void arena_bump(struct arena_allocator *allocator)
|
|
||||||
{
|
{
|
||||||
allocator->position = 0;
|
arena_reset_to_snapshot(a, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arena_deinit(arena a)
|
||||||
|
{
|
||||||
|
free(a.memory);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
core/arena.h
44
core/arena.h
|
|
@ -1,39 +1,31 @@
|
||||||
/* SPDX-License-Identifier:BSD-3-Clause */
|
/* SPDX-License-Identifier:BSD-3-Clause */
|
||||||
#ifndef ARENA_H
|
#ifndef ARENA_H
|
||||||
#define ARENA_H
|
#define ARENA_H
|
||||||
|
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
|
||||||
/*
|
typedef struct {
|
||||||
* An arena is a fast allocator that just keeps everything in a contiguous
|
usize capacity;
|
||||||
* chunk of memory and moves a "pointer" when allocating new memory. The
|
|
||||||
* allocated memory is then free'd all at once.
|
|
||||||
*/
|
|
||||||
struct arena_allocator {
|
|
||||||
usize size;
|
|
||||||
usize base;
|
|
||||||
usize position;
|
usize position;
|
||||||
};
|
void* memory;
|
||||||
|
} arena;
|
||||||
|
|
||||||
extern struct arena_allocator *global_arena;
|
typedef usize snapshot;
|
||||||
|
|
||||||
/* Create a new arena allocator of size `size` */
|
|
||||||
struct arena_allocator *arena_init(usize size);
|
|
||||||
/* Destroy the allocator and */
|
|
||||||
void arena_deinit(struct arena_allocator *allocator);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a chunk of memory of size `size` on the arena.
|
* NOTE(ernesto): faulty initialization is signalided by the arena.memory
|
||||||
|
* being null. It is the responsability of the caller to check for fulty
|
||||||
|
* initialization.
|
||||||
*/
|
*/
|
||||||
void *arena_alloc(struct arena_allocator *allocator, usize size);
|
arena arena_init(usize size);
|
||||||
/*
|
/*
|
||||||
* Same as `arena_alloc()` but also set all the allocated memory to zero.
|
* Returns null on unsuccessfull allocation.
|
||||||
|
* In this implemention an allocation is only unsuccessfull if the arena
|
||||||
|
* does not have enough memory to allocate the requested space
|
||||||
*/
|
*/
|
||||||
void *arena_zalloc(struct arena_allocator *allocator, usize size);
|
void *arena_alloc(arena *a, usize size);
|
||||||
/*
|
snapshot arena_snapshot(arena a);
|
||||||
* Free all the allocated memory at once. This just sets the allocator cursor
|
void arena_reset_to_snapshot(arena *a, snapshot s);
|
||||||
* to its starting position.
|
void arena_reset(arena *a);
|
||||||
*/
|
/* This call should never fail, also, do we even care if it does? */
|
||||||
void arena_bump(struct arena_allocator *allocator);
|
void arena_deinit(arena a);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue