Add an arena out-of-memory handler
This commit is contained in:
@ -9,7 +9,8 @@ typedef struct {
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Arena arena = gebs_arena_get(4*1024);
|
||||
/* Arena arena = gebs_arena_get(512); */
|
||||
Arena arena = gebs_arena_get(128);
|
||||
defer { arena_destroy(&arena); }
|
||||
|
||||
Ints ints = {0};
|
||||
|
25
gebs.h
25
gebs.h
@ -169,7 +169,7 @@ void gebs_default_allocator_free(void *self, void *memory);
|
||||
void *gebs_default_allocator_realloc(void *self, void *memory,
|
||||
size_t prev_size, size_t new_size);
|
||||
|
||||
typedef struct {
|
||||
typedef struct Gebs_Arena {
|
||||
void *(*malloc)(void *self, size_t size);
|
||||
void (*free)(void *self, void *memory);
|
||||
void *(*realloc)(void *self, void *memory, size_t prev_size, size_t new_size);
|
||||
@ -177,6 +177,8 @@ typedef struct {
|
||||
void *buffer;
|
||||
void *end;
|
||||
size_t capacity;
|
||||
|
||||
void (*out_of_memory_handler)(struct Gebs_Arena *self, size_t requested);
|
||||
} Gebs_Arena;
|
||||
|
||||
void gebs_arena_reset(Gebs_Arena *a);
|
||||
@ -184,6 +186,7 @@ void gebs_arena_destroy(Gebs_Arena *a);
|
||||
void *gebs_arena_malloc(void *self, size_t size);
|
||||
void gebs_arena_free(void *self, void *memory);
|
||||
void *gebs_arena_realloc(void *self, void *memory, size_t prev_size, size_t new_size);
|
||||
void gebs_arena_out_of_memory_handler(Gebs_Arena *self, size_t requested);
|
||||
|
||||
#define gebs_arena_get(cap) \
|
||||
({ \
|
||||
@ -192,6 +195,7 @@ void *gebs_arena_realloc(void *self, void *memory, size_t prev_size, size_t new_
|
||||
__arena.realloc = &gebs_arena_realloc; \
|
||||
__arena.free = &gebs_arena_free; \
|
||||
__arena.capacity = (cap); \
|
||||
__arena.out_of_memory_handler = &gebs_arena_out_of_memory_handler; \
|
||||
__arena; \
|
||||
})
|
||||
|
||||
@ -541,6 +545,15 @@ void *gebs_arena_malloc(void *self, size_t size)
|
||||
}
|
||||
void *p = a->end;
|
||||
a->end = (void *)((uintptr_t)a->end + size);
|
||||
|
||||
size_t requested = (uintptr_t)a->end - (uintptr_t)a->buffer;
|
||||
if (requested > a->capacity) {
|
||||
if (a->out_of_memory_handler == NULL) {
|
||||
abort();
|
||||
}
|
||||
a->out_of_memory_handler(a, requested);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -572,6 +585,16 @@ void gebs_arena_destroy(Gebs_Arena *a)
|
||||
#endif
|
||||
}
|
||||
|
||||
void gebs_arena_out_of_memory_handler(Gebs_Arena *self, size_t requested)
|
||||
{
|
||||
GEBS_LOGE("Arena ran out of memory. capacity = %zu, requested %zu\n",
|
||||
self->capacity, requested);
|
||||
GEBS_LOGI("Arena: buffer %p, end %p, diff %zu\n",
|
||||
self->buffer, self->end,
|
||||
(size_t)((uintptr_t)self->end - (uintptr_t)self->buffer));
|
||||
abort();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Scratch arena
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user