diff options
| author | LLLL Colonq <llll@colonq> | 2026-03-03 14:20:26 -0500 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-03-03 14:20:26 -0500 |
| commit | 3707dfaa64715c8fb1ba8a23f9762fef174538d8 (patch) | |
| tree | 539ae38f4cde9d6f8ffa5eb5f9a8a32c203a0942 /src/utils.c | |
| parent | fae5921bfcbf9f0c8c138dd13aa9c8822a75a316 (diff) | |
Collect more garbage!
Diffstat (limited to 'src/utils.c')
| -rw-r--r-- | src/utils.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c index ebff4a7..5f9d49e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -18,3 +18,66 @@ void pit_debug(const char *format, ...) { vfprintf(stderr, format, vargs); va_end(vargs); } + +static uintptr_t pit_align_down(uintptr_t addr, uintptr_t align) { + return addr & ~(align - 1); /* easy! just zero the low bits */ +} +static uintptr_t pit_align_up(uintptr_t addr, uintptr_t align) { + return (addr + align - 1) /* increment past the next aligned address... */ + & ~(align - 1); /* ...and then zero the low bits */ +} + +pit_arena *pit_arena_new(i64 capacity, i64 elem_size) { + i64 byte_len = 0; + pit_mul(&byte_len, elem_size, capacity); + pit_arena *a = (pit_arena *) malloc(sizeof(pit_arena) + (size_t) byte_len); + if (!a || byte_len <= 0) return NULL; + a->elem_size = elem_size; + a->capacity = byte_len / elem_size; + a->next = 0; + a->back = byte_len; + return a; +} +void pit_arena_reset(pit_arena *a) { + a->next = 0; + pit_mul(&a->back, a->elem_size, a->capacity); +} +static i64 pit_arena_byte_idx(pit_arena *a, i64 idx) { + i64 byte_idx = 0; pit_mul(&byte_idx, a->elem_size, idx); + return byte_idx; +} +i64 pit_arena_alloc_idx(pit_arena *a) { + i64 ret = a->next; + i64 byte_idx = pit_arena_byte_idx(a, ret); + if (byte_idx + a->elem_size >= a->back) { return -1; } + a->next += 1; + return ret; +} +i64 pit_arena_alloc_bulk_idx(pit_arena *a, i64 num) { + i64 ret = a->next; + i64 byte_idx = pit_arena_byte_idx(a, ret); + i64 byte_len = 0; pit_mul(&byte_len, a->elem_size, num); + if (byte_idx + byte_len > a->back) { return -1; } + a->next += num; + return ret; +} +void *pit_arena_get(pit_arena *a, i64 idx) { + i64 byte_idx = pit_arena_byte_idx(a, idx); + if (byte_idx < 0 || byte_idx + a->elem_size >= a->back) { return NULL; } + return &a->data[byte_idx]; +} +void *pit_arena_alloc(pit_arena *a) { + i64 idx = pit_arena_alloc_idx(a); + return pit_arena_get(a, idx); +} +void *pit_arena_alloc_bulk(pit_arena *a, i64 num) { + i64 idx = pit_arena_alloc_bulk_idx(a, num); + return pit_arena_get(a, idx); +} +void *pit_arena_alloc_back(pit_arena *a, i64 sz) { + i64 next_byte = pit_arena_byte_idx(a, a->next); + i64 back_byte = (i64) pit_align_down((uintptr_t) (a->back - sz), sizeof(void *)); + if (back_byte < next_byte) return NULL; + a->back = back_byte; + return &a->data[a->back]; +} |
