From 457bc24019e206518636d51ae5133132e4d5de8f Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Sat, 20 Apr 2024 20:41:06 +0200 Subject: [PATCH] Add test and remove code comments --- .gitignore | 4 ++- buddy.c | 88 ++++-------------------------------------------------- buddy.h | 32 ++++++++++---------- makefile | 3 +- test2.c | 63 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 99 deletions(-) create mode 100644 test2.c diff --git a/.gitignore b/.gitignore index a0ed3d4..62f902f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ test -test.exe \ No newline at end of file +test.exe +test2 +test2.exe \ No newline at end of file diff --git a/buddy.c b/buddy.c index 9f270f3..85ba591 100644 --- a/buddy.c +++ b/buddy.c @@ -547,8 +547,12 @@ void *buddy_malloc(struct buddy_alloc *alloc, size_t len) void buddy_free(struct buddy_alloc *alloc, size_t len, void *ptr) { - if (ptr == NULL || len == 0) return; - if (len > MAX_BLOCK_SIZE) return; + if (ptr == NULL || len == 0) + return; + + if (len > MAX_BLOCK_SIZE) + return; + len = normalize_len(len); if (!is_allocated(alloc, ptr, len)) @@ -571,83 +575,3 @@ void buddy_free(struct buddy_alloc *alloc, len <<= 1; } } - -/* -#define ANSI_COLOR_RED "\x1b[31m" -#define ANSI_COLOR_GREEN "\x1b[32m" -#define ANSI_COLOR_YELLOW "\x1b[33m" -#define ANSI_COLOR_BLUE "\x1b[34m" -#define ANSI_COLOR_MAGENTA "\x1b[35m" -#define ANSI_COLOR_CYAN "\x1b[36m" -#define ANSI_COLOR_RESET "\x1b[0m" - -static const char *block_size_label(size_t len) -{ - const char *label = "???"; - switch (len) { - case 1<<12: label = "4K"; break; - case 1<<11: label = "2K"; break; - case 1<<10: label = "1K"; break; - case 1<<9 : label = "512B"; break; - case 1<<8 : label = "256B"; break; - } - return label; -} - -void print_lists(struct buddy_alloc *alloc) -{ - for (int i = MIN_BLOCK_LOG2; i <= MAX_BLOCK_LOG2; i++) { - fprintf(stderr, "%s = {", block_size_label(1U<lists[i - MIN_BLOCK_LOG2]; - while (p) { - assert((uintptr_t) p >= (uintptr_t) alloc->base); - fprintf(stderr, "%lu", (uintptr_t) p - (uintptr_t) alloc->base); - p = p->next; - if (p) - fprintf(stderr, ", "); - } - fprintf(stderr, "}\n"); - } -} - -void buddy_dump(struct buddy_alloc *alloc, FILE *out) -{ - fprintf(out, "\n"); - - for (int i = 0; i < alloc->num_info; i++) { - for (int j = 0; j < 32; j++) { - if (alloc->info[i].bits[0] & (1U << j)) - fprintf(stderr, "1"); - else - fprintf(stderr, "0"); - } - fprintf(stderr, " "); - } - fprintf(stderr, "\n"); - - for (int i = 0; i < alloc->num_info; i++) { - char *page = alloc->base + i * MAX_BLOCK_SIZE; - for (int j = MAX_BLOCK_LOG2; j >= MIN_BLOCK_LOG2; j--) { - - size_t len = 1U << j; - - const char *label = block_size_label(len); - - for (size_t k = 0; k < MAX_BLOCK_SIZE / len; k++) { - - char *ptr = page + k * len; - - fprintf(out, "%-4lX ", (uintptr_t) ptr - (uintptr_t) alloc->base); - - for (int q = 0; q < MAX_BLOCK_LOG2 - j; q++) - fprintf(out, " "); - - if (is_allocated(alloc, ptr, len)) - fprintf(out, ANSI_COLOR_GREEN "%s - allocated\n" ANSI_COLOR_RESET, label); - else - fprintf(out, "%s - free\n", label); - } - } - } -} -*/ \ No newline at end of file diff --git a/buddy.h b/buddy.h index 50a430a..586f079 100644 --- a/buddy.h +++ b/buddy.h @@ -1,23 +1,25 @@ #include #include -#define BUDDY_ALLOC_MAX_BLOCK_LOG2 12 -#define BUDDY_ALLOC_MIN_BLOCK_LOG2 8 +#define BUDDY_ALLOC_MAX_BLOCK_LOG2 13 +#define BUDDY_ALLOC_MIN_BLOCK_LOG2 3 + +_Static_assert(BUDDY_ALLOC_MIN_BLOCK_LOG2 <= BUDDY_ALLOC_MAX_BLOCK_LOG2); +_Static_assert(BUDDY_ALLOC_MIN_BLOCK_LOG2 > 2); + #define BUDDY_ALLOC_NUM_LISTS (BUDDY_ALLOC_MAX_BLOCK_LOG2 - BUDDY_ALLOC_MIN_BLOCK_LOG2 + 1) -/* - * To keep track of the allocation state of a page, - * we need one bit for each possible block that can - * be made out of it. For instance, if the page can - * only be allocated in its entirety, 1 bit is required. - * If the blocks halfs can be allocated too, 3 bits - * are required: 1 for the page, 1 for the frist half - * and 1 for the second half. Allowing the allocation - * of page quarters requires 4 more bits, for a total - * of 7. In general, if we allow splitting a page N - * times (N=0 means only the entire page can be allocated), - * then 2^(N+1)-1 bits are necessary. - */ +// To keep track of the allocation state of a page, +// we need one bit for each possible block that can +// be made out of it. For instance, if the page can +// only be allocated in its entirety, 1 bit is required. +// If the blocks halfs can be allocated too, 3 bits +// are required: 1 for the page, 1 for the frist half +// and 1 for the second half. Allowing the allocation +// of page quarters requires 4 more bits, for a total +// of 7. In general, if we allow splitting a page N +// times (N=0 means only the entire page can be allocated), +// then 2^(N+1)-1 bits are necessary. #define BUDDY_ALLOC_BITS_PER_PAGE ((1U << (BUDDY_ALLOC_NUM_LISTS)) - 1) #define BUDDY_ALLOC_WORDS_PER_PAGE ((BUDDY_ALLOC_BITS_PER_PAGE + 31) / 32) diff --git a/makefile b/makefile index 310df35..4f2b688 100644 --- a/makefile +++ b/makefile @@ -1,3 +1,4 @@ all: - gcc test.c buddy.c -o test -Wall -Wextra -ggdb #-fsanitize=address,undefined \ No newline at end of file + gcc test.c buddy.c -o test -Wall -Wextra -ggdb #-fsanitize=address,undefined + gcc test2.c buddy.c -o test2 -Wall -Wextra -ggdb \ No newline at end of file diff --git a/test2.c b/test2.c new file mode 100644 index 0000000..0c73607 --- /dev/null +++ b/test2.c @@ -0,0 +1,63 @@ +#include +#include "buddy.h" + +#define NUM_PAGES 16 + +#define MIN_ALLOC_SIZE (1U << BUDDY_ALLOC_MIN_BLOCK_LOG2) +#define PAGE_SIZE (1U << BUDDY_ALLOC_MAX_BLOCK_LOG2) +#define POOL_SIZE (NUM_PAGES * PAGE_SIZE) +#define MAX_ALLOCS (POOL_SIZE / MIN_ALLOC_SIZE) + +int main(void) +{ + _Alignas(PAGE_SIZE) char mem[POOL_SIZE]; + struct page_info info[NUM_PAGES]; + struct buddy_alloc alloc = buddy_startup(mem, POOL_SIZE, info, NUM_PAGES); + + void *allocs[MAX_ALLOCS]; + + size_t performed = 0; + for (size_t i = 0; i < MAX_ALLOCS; i++) { + void *ptr = buddy_malloc(&alloc, MIN_ALLOC_SIZE); + if (ptr == NULL) + break; + + performed++; + + allocs[i] = ptr; + + *(size_t*) ptr = i; + } + + if (performed == MAX_ALLOCS) { + + for (size_t i = 0; i < MAX_ALLOCS; i++) { + if (*(size_t*) allocs[i] != i) + fprintf(stderr, "%p allocated twice!\n", allocs[i]); + } + + for (size_t i = 0; i < MAX_ALLOCS; i++) { + buddy_free(&alloc, MIN_ALLOC_SIZE, allocs[MAX_ALLOCS-i-1]); + } + + performed = 0; + for (size_t i = 0; i < MAX_ALLOCS; i++) { + void *ptr = buddy_malloc(&alloc, MIN_ALLOC_SIZE); + performed++; + + allocs[i] = ptr; + + *(size_t*) ptr = i + MAX_ALLOCS; + } + + for (size_t i = 0; i < MAX_ALLOCS; i++) { + if (*(size_t*) allocs[i] != MAX_ALLOCS + i) + fprintf(stderr, "%p reallocation error!\n", allocs[i]); + } + } + + fprintf(stderr, "performed=%lu, expected=%u\n", performed, MAX_ALLOCS); + + buddy_cleanup(&alloc); + return 0; +}