diff options
Diffstat (limited to 'project-base/src/memory_bucket.c')
| -rw-r--r-- | project-base/src/memory_bucket.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/project-base/src/memory_bucket.c b/project-base/src/memory_bucket.c new file mode 100644 index 0000000..8839a4a --- /dev/null +++ b/project-base/src/memory_bucket.c @@ -0,0 +1,75 @@ +/* +* BSD 2-Clause “Simplified” License +* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com +* All rights reserved. +*/ + +inline memory_bucket memory_bucket_init(s32 bucket_size) +{ + // @Hardcoded why is this necessary? + log_assert(bucket_size >= MAX_INPUT_LENGTH, "bucket_size should be larger than MAX_INPUT_LENGTH"); + + memory_bucket collection; + collection.bucket_mutex = mutex_create(); + collection.buckets = array_create(sizeof(memory_bucket_entry)); + + memory_bucket_entry bucket; + bucket.data = mem_alloc(bucket_size); + bucket.length = bucket_size; + bucket.cursor = 0; + array_push(&collection.buckets, (uint8_t *)&bucket); + return collection; +} + +void* memory_bucket_reserve(memory_bucket *bucket, s32 reserve_length) +{ + mutex_lock(&bucket->bucket_mutex); + memory_bucket_entry *bucket_entry = 0; + for (s32 i = 0; i < bucket->buckets.length; i++) + { + bucket_entry = array_at(&bucket->buckets, i); + + if (bucket_entry->length - bucket_entry->cursor < reserve_length) continue; + + void *space = bucket_entry->data+bucket_entry->cursor; + bucket_entry->cursor += reserve_length; + mutex_unlock(&bucket->bucket_mutex); + + return space; + } + + // failed to find suitable space, allocate new bucket + memory_bucket_entry new_bucket; + new_bucket.data = mem_alloc(bucket_entry->length); + new_bucket.length = bucket_entry->length; + new_bucket.cursor = 0; + array_push(&bucket->buckets, (uint8_t *)&new_bucket); + mutex_unlock(&bucket->bucket_mutex); + + return new_bucket.data; +} + +inline void memory_bucket_reset(memory_bucket *bucket) +{ + mutex_lock(&bucket->bucket_mutex); + for (s32 i = 0; i < bucket->buckets.length; i++) + { + memory_bucket_entry *bucket_entry = array_at(&bucket->buckets, i); + bucket_entry->cursor = 0; + } + mutex_unlock(&bucket->bucket_mutex); +} + +inline void memory_bucket_destroy(memory_bucket *bucket) +{ + mutex_lock(&bucket->bucket_mutex); + for (s32 i = 0; i < bucket->buckets.length; i++) + { + memory_bucket_entry *bucket_entry = array_at(&bucket->buckets, i); + mem_free(bucket_entry->data); + } + array_destroy(&bucket->buckets); + mutex_unlock(&bucket->bucket_mutex); + + mutex_destroy(&bucket->bucket_mutex); +}
\ No newline at end of file |
