diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /malloc/block_allocator/allocator.c | |
Diffstat (limited to 'malloc/block_allocator/allocator.c')
| -rw-r--r-- | malloc/block_allocator/allocator.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/malloc/block_allocator/allocator.c b/malloc/block_allocator/allocator.c new file mode 100644 index 0000000..0cf9af6 --- /dev/null +++ b/malloc/block_allocator/allocator.c @@ -0,0 +1,61 @@ +#include "allocator.h" + +#include <stdlib.h> +#include <sys/mman.h> +#include <unistd.h> + +size_t align(size_t size, size_t al) +{ + size_t padding = size % al; + if (padding) + padding = al - padding; + size_t res; + if (__builtin_uaddl_overflow(size, padding, &res)) + return 0; + return res; +} + +struct blk_allocator *blka_new(void) +{ + struct blk_allocator *new = malloc(sizeof(struct blk_allocator)); + new->meta = NULL; + return new; +} + +struct blk_meta *blka_alloc(struct blk_allocator *blka, size_t size) +{ + long page_size = sysconf(_SC_PAGESIZE); + size_t aligned_size = align(size + sizeof(struct blk_meta), page_size); + struct blk_meta *meta = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (meta == MAP_FAILED) + return NULL; + meta->size = aligned_size - sizeof(struct blk_meta); + meta->next = blka->meta; + blka->meta = meta; + return meta; +} + +void blka_free(struct blk_meta *blk) +{ + munmap(blk, blk->size + sizeof(struct blk_meta)); +} + +void blka_pop(struct blk_allocator *blka) +{ + if (blka->meta == NULL) + return; + + struct blk_meta *meta = blka->meta; + blka->meta = blka->meta->next; + blka_free(meta); +} + +void blka_delete(struct blk_allocator *blka) +{ + while (blka->meta) + { + blka_pop(blka); + } + free(blka); +} |
