diff --git a/.clang-format b/.clang-format index fc9422d..1edc97c 100644 --- a/.clang-format +++ b/.clang-format @@ -16,4 +16,3 @@ AlignConsecutiveDeclarations: PadOperators: false AlignConsecutiveMacros: true AllowShortCaseLabelsOnASingleLine: true -SeparateDefinitionBlocks: Always diff --git a/freelist/Makefile b/freelist/Makefile deleted file mode 100644 index 7f6d8a6..0000000 --- a/freelist/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CC = gcc -CFLAGS = -Wall -O2 - -TARGET = main.elf -SRC = main.c freelist.c - -#LDFLAGS = - -$(TARGET): $(SRC) - @echo CC $@ - @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) - -clean: - rm -f $(TARGET) diff --git a/freelist/freelist.c b/freelist/freelist.c deleted file mode 100644 index 107dd63..0000000 --- a/freelist/freelist.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "freelist.h" -#include "stdbool.h" -#include "stddef.h" -#include -#include -#include -#include -#include - -/* Fiddle these around according to your need. */ -#ifdef FREELIST_NOALIGN -#define ALIGN(x) (x) -#else // FREELIST_NOALIGN - -/* Align to nearest multiple of sizeof(void*) */ -static inline size_t align_up(size_t n) { - return (n + sizeof(void *) - 1) & ~(sizeof(void *) - 1); -} - -#define ALIGN(x) (align_up(x)) -#endif // FREELIST_NOALIGN - -/* Initialize the FreeList */ -int fl_init(FreeList *fl, uintptr_t start, uintptr_t end, size_t itemsize) { - size_t size = ALIGN(itemsize + sizeof(FreeListBlock)); - - if (!fl || end <= start) - return EXIT_FAILURE; - - fl->start = start; - fl->end = end; - fl->size = size; - fl->allocated = 0; - - FreeListBlock *block = (FreeListBlock *)start; - for (size_t i = 0; i < fl_capacity(fl); i++) { - block->next = (FreeListBlock *)((void *)block + size); - block->block_state = FL_FREE; - block = block->next; - } - - block->next = NULL; - - fl->free = (FreeListBlock *)start; - return EXIT_SUCCESS; -} - -/* Allocate some memory from the FreeList */ -void *fl_alloc(FreeList *fl) { - if (!fl->free || fl->free->block_state != FL_FREE) - return NULL; - - FreeListBlock *m = fl->free; - m->block_state = FL_USED; - - fl->free = fl->free->next; - fl->allocated++; - - return ((void *)m) + sizeof(FreeListBlock); -} - -/* Return some memory to the FreeList */ -int fl_free(FreeList *fl, void *ptr) { - if (!fl_is_managed(fl, ptr)) { - return EXIT_FAILURE; /* We cant free memory we do not own */ - } - - FreeListBlock *block = (FreeListBlock *)((uintptr_t)ptr - sizeof(FreeListBlock)); - - if (block->block_state != FL_USED) { - return EXIT_FAILURE; /* Block must be used */ - } - - block->block_state = FL_FREE; - block->next = fl->free; - fl->free = block; - fl->allocated--; - - return EXIT_SUCCESS; -} - -/* Returns how many slots are occupied */ -size_t fl_allocated(FreeList *fl) { - return fl->allocated; -} - -/* Returns how many free slots are available (O(1)) */ -size_t fl_available(FreeList *fl) { - return fl_capacity(fl) - fl->allocated; -} - -/* Returns the total amount of items the freelist will hold */ -size_t fl_capacity(FreeList *fl) { - return (fl->end - fl->start) / fl->size; -} - -/* Check if a piece of memory is managed by the FreeList */ -int fl_is_managed(FreeList *fl, void *ptr) { - return ((uintptr_t)ptr >= fl->start && (uintptr_t)ptr < fl->end); -} - -/* Returns the ratio of metadata versus data as a scalar in range 0..1 */ -float fl_utilization(FreeList *fl, size_t itemsize) { - return (float)itemsize / fl->size; -} - -/* Walks the free pages/slots, returns total count (O(n), given no cycles) */ -size_t fl_check(FreeList *fl) { - int avail = 0; - FreeListBlock *cursor = fl->free; - - while (cursor->next != NULL) { - avail++; - assert(cursor->block_state == FL_FREE); - cursor = cursor->next; - } - - return avail; -} diff --git a/freelist/freelist.h b/freelist/freelist.h deleted file mode 100644 index 885b58a..0000000 --- a/freelist/freelist.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef FREELIST_H -#define FREELIST_H - -#include -#include -#include - -#define FL_FREE ((uint8_t)0x00) -#define FL_USED ((uint8_t)0x01) - -typedef struct FreeListBlock { - struct FreeListBlock *next; - uint8_t block_state; -} FreeListBlock; - -typedef struct { - uintptr_t start; - uintptr_t end; - FreeListBlock *free; - size_t size; - size_t allocated; -} FreeList; - -int fl_init(FreeList *fl, uintptr_t start, uintptr_t end, size_t itemsize); -int fl_free(FreeList *fl, void *ptr); -int fl_is_managed(FreeList *fl, void *ptr); -void *fl_alloc(FreeList *fl); -size_t fl_check(FreeList *fl); -size_t fl_allocated(FreeList *fl); -size_t fl_available(FreeList *fl); -size_t fl_capacity(FreeList *fl); -float fl_utilization(FreeList *fl, size_t itemsize); - -#endif // FREELIST_H diff --git a/freelist/main.c b/freelist/main.c deleted file mode 100644 index 9d18438..0000000 --- a/freelist/main.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "freelist.h" -#include -#include -#include -#include - -typedef struct { - int x, y, z; -} Vec3; - -Vec3 vec3_new(int a, int b, int c) { - return (Vec3){a, b, c}; -} - -// Print function -void printvec(const Vec3 *v) { - printf("Vec3: (%d, %d, %d)\n", v->x, v->y, v->z); -} - -int main() { - FreeList fl; - char *mem = malloc(4096); - - fl_init(&fl, (uintptr_t)mem, (uintptr_t)mem + 4096, sizeof(Vec3)); - size_t cap = fl_capacity(&fl); - assert(fl_available(&fl) == cap); - - printf("Space utilization: %.2f%%\n", 100.0 * fl_utilization(&fl, sizeof(Vec3))); - - Vec3 *a = fl_alloc(&fl); - Vec3 *b = fl_alloc(&fl); - Vec3 *c = fl_alloc(&fl); - - memset(a, 0x23, sizeof(Vec3)); - memset(b, 0x24, sizeof(Vec3)); - memset(c, 0x25, sizeof(Vec3)); - - *a = vec3_new(12, 13, 435); - *b = vec3_new(192, 199, 435); - *c = vec3_new(432, 11, 435); - - printvec(a); - printvec(b); - printvec(c); - - assert(fl_check(&fl) == cap - 3); - assert(fl_capacity(&fl) == fl_available(&fl) + 3); - - printf("Available: %zu of %zu\n", fl_available(&fl), fl_capacity(&fl)); - - assert(fl_free(&fl, a) == EXIT_SUCCESS); - assert(fl_free(&fl, b) == EXIT_SUCCESS); - assert(fl_free(&fl, c) == EXIT_SUCCESS); - assert(fl_free(&fl, a) == EXIT_FAILURE); // Double free - - printf("Available: %zu of %zu\n", fl_available(&fl), fl_capacity(&fl)); - - assert(fl_check(&fl) == fl_capacity(&fl) - fl_allocated(&fl)); - assert(fl_allocated(&fl) == 0); - - /* All memory is free here */ - - uintptr_t *ptr_buf = malloc(sizeof(uintptr_t) * fl_capacity(&fl)); - - /* Fill it up */ - for (int i = 0; i < fl_capacity(&fl); i++) { - ptr_buf[i] = (uintptr_t)fl_alloc(&fl); - } - - assert(0 == fl_available(&fl)); - assert(fl_allocated(&fl) == fl_capacity(&fl)); - assert(fl_check(&fl) == 0); - - /* Return it all */ - for (int i = 0; i < fl_capacity(&fl); i++) { - fl_free(&fl, (void *)ptr_buf[i]); - } - - assert(cap == fl_available(&fl)); - assert(fl_allocated(&fl) == 0); - assert(fl_check(&fl) == cap); - - printf("All tests passed!\n"); - return 0; -}