From 64ad489b90cb5956887eaa1cfabe2c2cdff0af80 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Wed, 30 Aug 2023 22:49:43 -0500 Subject: [PATCH] Added new list-based memory allocator --- include/Makefile.am | 2 +- include/libmalloc/list_alloc.h | 27 +++++++ src/Makefile.am | 2 +- src/list_alloc.c | 134 +++++++++++++++++++++++++++++++++ tests/Makefile.am | 5 +- tests/test_listalloc | Bin 0 -> 29504 bytes tests/test_listalloc.c | 109 +++++++++++++++++++++++++++ 7 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 include/libmalloc/list_alloc.h create mode 100644 src/list_alloc.c create mode 100755 tests/test_listalloc create mode 100644 tests/test_listalloc.c diff --git a/include/Makefile.am b/include/Makefile.am index 9d6bc93..3e004a9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,2 +1,2 @@ nobase_include_HEADERS = libmalloc/bitmap_alloc.h libmalloc/buddy_alloc.h \ - libmalloc/memmap.h libmalloc/common.h \ No newline at end of file + libmalloc/list_alloc.h libmalloc/memmap.h libmalloc/common.h \ No newline at end of file diff --git a/include/libmalloc/list_alloc.h b/include/libmalloc/list_alloc.h new file mode 100644 index 0000000..1b7bb08 --- /dev/null +++ b/include/libmalloc/list_alloc.h @@ -0,0 +1,27 @@ +#ifndef _LIBMALLOC_LISTALLOC_H +#define _LIBMALLOC_LISTALLOC_H + +#include "memmap.h" +#include "common.h" + +typedef struct list_block_t +{ + unsigned long free; + unsigned long size; + struct list_block_t *prev; + struct list_block_t *next; +} list_block_t; + +typedef struct list_alloc_descriptor_t +{ + list_block_t head; + list_block_t *current_block; +} list_alloc_descriptor_t; + +void *list_alloc_reserve(list_alloc_descriptor_t *heap, unsigned long size); + +void list_alloc_free(list_alloc_descriptor_t *heap, void *p); + +int list_alloc_init(list_alloc_descriptor_t *heap, memory_map_t *map); + +#endif \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 43ed361..bea103e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ lib_LIBRARIES = libmalloc.a -libmalloc_a_SOURCES = buddy_alloc.c bitmap_alloc.c memmap.c +libmalloc_a_SOURCES = buddy_alloc.c bitmap_alloc.c list_alloc.c memmap.c libmalloc_a_CFLAGS = -I$(prefix)/include \ No newline at end of file diff --git a/src/list_alloc.c b/src/list_alloc.c new file mode 100644 index 0000000..84e6bd4 --- /dev/null +++ b/src/list_alloc.c @@ -0,0 +1,134 @@ +#include "libmalloc/list_alloc.h" +#include +#include + +#define MIN_BLOCK_SIZE (4 * sizeof(list_block_t)) + +static list_block_t *block_end_ptr(list_block_t *p) +{ + return (list_block_t*)((void*)p + p->size - sizeof(list_block_t)); +} + +static list_block_t *block_start_ptr(list_block_t *p) +{ + return (list_block_t*)((void*)p - p->size + sizeof(list_block_t)); +} + +static void set_block_tag(list_block_t *p, unsigned long free) +{ + p->free = free; + block_end_ptr(p)->free = free; +} + +static void set_block_size(list_block_t *p, unsigned long size) +{ + p->size = size; + block_end_ptr(p)->size = size; +} + +static void set_block_next(list_block_t *p, list_block_t *next) +{ + p->next = next; + block_end_ptr(p)->next = next; +} + +static void set_block_prev(list_block_t *p, list_block_t *prev) +{ + p->prev = prev; + block_end_ptr(p)->prev = prev; +} + +static void set_block(list_block_t *p, unsigned long tag, unsigned long size, + list_block_t *next, list_block_t *prev) +{ + set_block_size(p, size); + set_block_tag(p, tag); + set_block_next(p, next); + set_block_prev(p, prev); +} + +void *list_alloc_reserve(list_alloc_descriptor_t *heap, unsigned long size) +{ + size += sizeof(unsigned long) - 1; + size -= size % sizeof(unsigned long); + list_block_t *p = heap->current_block; + do + { + if(p->size >= (size + 2 * sizeof(list_block_t) + MIN_BLOCK_SIZE)) + { + printf("Reserving partial block.\n"); + unsigned long new_size = p->size - size - (2 * sizeof(list_block_t)); + list_block_t *new_block = (void*)p + new_size; + set_block(new_block, 0, size + 2 * sizeof(list_block_t), 0, 0); + set_block_tag(p, 1); + set_block_size(p, new_size); + heap->current_block = p; + return (void*)new_block + sizeof(list_block_t); + } + else if(p->size >= (size + 2 * sizeof(list_block_t))) + { + printf("Reserving whole block.\n"); + set_block_next(p->prev, p->next); + set_block_prev(p->next, p->prev); + heap->current_block = p->next; + set_block(p, 0, p->size, 0, 0); + return (void*)p + sizeof(list_block_t); + } + p = p->next; + } while(p != heap->current_block); + return NOMEM; +} + +void list_alloc_free(list_alloc_descriptor_t *heap, void *p) +{ + list_block_t *block = (list_block_t*)(p - sizeof(list_block_t)); + + list_block_t *lhs = block_start_ptr(block - 1); + if(lhs->free == 1) + { + printf("Merging left.\n"); + set_block_next(lhs->prev, lhs->next); + set_block_prev(lhs->next, lhs->prev); + unsigned long new_size = block->size + lhs->size; + block = (void*)block - lhs->size; + block->size = new_size; + } + + list_block_t *rhs = (block_end_ptr(block) + 1); + if(rhs->free == 1) + { + printf("Merging right.\n"); + set_block_next(rhs->prev, rhs->next); + set_block_prev(rhs->next, rhs->prev); + block->size += rhs->size; + } + + set_block(block, 1, block->size, &heap->head, heap->head.prev); + set_block_next(heap->head.prev, block); + set_block_prev(&heap->head, block); + heap->current_block = block; +} + +int list_alloc_init(list_alloc_descriptor_t *heap, memory_map_t *map) +{ + heap->head.free = 0; + heap->head.size = sizeof(heap->head); + heap->head.prev = &heap->head; + heap->head.next = &heap->head; + heap->current_block = &heap->head; + for(int i = 0; i < map->size; i++) + { + if(map->array[i].type != M_AVAILABLE + || map->array[i].size < MIN_BLOCK_SIZE) + { + continue; + } + list_block_t *new_block = ((list_block_t*)map->array[i].location) + 1; + set_block(new_block, 1, map->array[i].size - sizeof(list_block_t) * 2, &heap->head, heap->head.prev); + set_block_next(heap->head.prev, new_block); + set_block_prev(&heap->head, new_block); + (new_block - 1)->free = 0; + (block_end_ptr(new_block) + 1)->free = 0; + } + return 0; +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 492e40c..3bb0510 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,9 +1,12 @@ if BUILD_TESTS - noinst_PROGRAMS = test_bitmapalloc test_buddyalloc + noinst_PROGRAMS = test_bitmapalloc test_buddyalloc test_listalloc test_bitmapalloc_SOURCES = test_bitmapalloc.c test_bitmapalloc_LDADD = ../src/libmalloc.a test_buddyalloc_SOURCES = test_buddyalloc.c test_buddyalloc_LDADD = ../src/libmalloc.a + + test_listalloc_SOURCES = test_listalloc.c + test_listalloc_LDADD = ../src/libmalloc.a endif \ No newline at end of file diff --git a/tests/test_listalloc b/tests/test_listalloc new file mode 100755 index 0000000000000000000000000000000000000000..ec9b75579bf89135b5203b27a021d4238ca3c33f GIT binary patch literal 29504 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 +#include +#include +#include + +typedef struct memblock_t +{ + unsigned long size; + void *p; +} memblock_t; + +void check_block_list(void *heap, unsigned long heap_size, memblock_t *blocks, unsigned long count) +{ + for (int j = 0; j < count; j++) + { + if (blocks[j].size > 0) + { + assert(blocks[j].p >= heap); + assert(blocks[j].p + blocks[j].size <= heap + heap_size); + for (int k = j + 1; k < count; k++) + { + if (blocks[k].size > 0) + { + // printf("j = (%p, %lu), k = (%p, %lu)\n", blocks[j].p, blocks[j].size, blocks[k].p, blocks[k].size); + assert(blocks[k].p < blocks[j].p || blocks[k].p >= blocks[j].p + blocks[j].size); + assert(blocks[j].p < blocks[k].p || blocks[j].p >= blocks[k].p + blocks[k].size); + } + } + } + } +} + +int main(int argc, char** argv) +{ + unsigned int max_block_count = 0; + unsigned int heap_size = 0; + unsigned int passes = 0; + + char c; + while((c = getopt(argc, argv, "m:b:c:")) != -1) + { + if(c == 'm') + { + sscanf(optarg, "%i", &heap_size); + heap_size *= 1024; + } + else if(c == 'b') + { + sscanf(optarg, "%i", &max_block_count); + } + else if(c == 'c') + { + sscanf(optarg, "%i", &passes); + } + } + + printf("Running test with %i byte heap, %i blocks, %i passes.\n", + heap_size, max_block_count, passes); + + void *heap = malloc(heap_size); + memory_map_t map = { + .array = malloc(sizeof(unsigned long) * 16), + .capacity = 16, + .size = 0 + }; + memmap_insert_region(&map, heap, heap_size, M_AVAILABLE); + + list_alloc_descriptor_t desc; + list_alloc_init(&desc, &map); + memblock_t *blocks = calloc(max_block_count, sizeof(memblock_t)); + + for(int i = 0; i < passes; i++) + { + int index = rand() % max_block_count; + if(blocks[index].size == 0) + { + unsigned long size = rand() % 65536 + 1; + blocks[index].p = list_alloc_reserve(&desc, size); + //printf("Reserved %lu bytes.\n", size); + if(blocks[index].p != NOMEM) + { + blocks[index].size = size; + } + else + { + printf("Out of memory trying to reserve %lu bytes\n", size); + } + } + else + { + list_alloc_free(&desc, blocks[index].p); + //printf("Freed %p\n", blocks[index].p); + blocks[index].size = 0; + } + check_block_list(heap, heap_size, blocks, max_block_count); + } + + for(int i = 0; i < max_block_count; i++) + { + if(blocks[i].size != 0) + { + list_alloc_free(&desc, blocks[i].p); + blocks[i].size = 0; + } + } + + return 0; +} \ No newline at end of file