diff --git a/core/alloc.c b/core/alloc.c index 6b08a7c..fe5299f 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -1,6 +1,7 @@ #define pr_fmt(fmt) "[alloc]: " fmt //#define DEBUG #include "alloc.h" +#include "assert.h" #include "errno.h" #include "irq.h" #include "kernel.h" @@ -11,7 +12,6 @@ #include "paging.h" #define IS_SELF_CONTAINED(desc) ((vaddr_t)((desc)->page) == (vaddr_t)(desc)) -// Slab will contains object from sizeof(void *) to PAGE_SIZE/2 by pow2 static struct slabDesc *slub; static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab, @@ -20,14 +20,13 @@ static int allocSlabEntry(struct slabEntry **desc, size_t sizeEl, size_t sizeSla int selfContained); static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int selfContained); static int freeFromSlab(void *ptr, struct slabEntry *slab); +static struct slabDesc *allocGetSlab(size_t size); static struct { size_t elementSize; size_t slabSize; unsigned char isSelf; -} initSlab[] = {{sizeof(struct slabDesc), PAGE_SIZE, 1}, - {sizeof(struct slabEntry), PAGE_SIZE, 1}, - {4, PAGE_SIZE, 0}, +} initSlab[] = {{4, PAGE_SIZE, 0}, {8, PAGE_SIZE, 0}, {16, PAGE_SIZE, 0}, {32, PAGE_SIZE, 0}, @@ -41,10 +40,22 @@ static struct { {16384, 12 * PAGE_SIZE, 0}, {0, 0, 0}}; -int allocSetup(void) +int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr) { list_init(slub); + assert(allocBookSlab(sizeof(struct slabDesc), PAGE_SIZE, TRUE) == 0); + *descAddr = (vaddr_t)allocGetSlab(sizeof(struct slabDesc)); + assert(allocBookSlab(sizeof(struct slabEntry), PAGE_SIZE, TRUE) == 0); + *entryAddr = (vaddr_t)allocGetSlab(sizeof(struct slabEntry)); + assert(allocBookSlab(sizeOfArea, PAGE_SIZE, TRUE) == 0); + *areaAddr = (vaddr_t)allocGetSlab(sizeOfArea); + + return 0; +} + +int allocPopulate() +{ for (uint i = 0; initSlab[i].elementSize != 0; i++) { int ret; @@ -52,7 +63,7 @@ int allocSetup(void) initSlab[i].isSelf))) { if (ret == -EEXIST) continue; - pr_devel("Fail to allocBookSlab %d for %d \n", ret, (1U << i)); + pr_err("Fail to allocBookSlab %d for %d \n", ret, (1U << i)); return ret; } @@ -125,7 +136,7 @@ static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int s *desc = (struct slabDesc *)alloc; ((*desc)->slab).freeEl = (char *)(*desc) + sizeof(struct slabDesc); } else { - *desc = malloc(sizeof(struct slabDesc)); + *desc = malloc(sizeof(struct slabDesc)); if (*desc == NULL) return -ENOMEM; (*desc)->slab.freeEl = (void *)alloc; @@ -175,7 +186,7 @@ static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, *desc = (struct slabEntry *)alloc; (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry); } else { - *desc = malloc(sizeof(struct slabEntry)); + *desc = malloc(sizeof(struct slabEntry)); if (*desc == NULL) return -ENOMEM; (*desc)->freeEl = (void *)alloc; @@ -227,24 +238,31 @@ static void *allocFromSlab(struct slabEntry *slab) return (void *)next; } +static struct slabDesc *allocGetSlab(size_t size) +{ + struct slabDesc *slab = NULL; + uint slubIdx; + + list_foreach(slub, slab, slubIdx) + { + if (size <= slab->size) + return slab; + } + + return NULL; +} + void *malloc(size_t size) { struct slabEntry *slabEntry; struct slabDesc *slab = NULL; - uint slubIdx; void *ret; int flags; int slabIdx; disable_IRQs(flags); - list_foreach(slub, slab, slubIdx) - { - if (size <= slab->size) - break; - } - - if (!list_foreach_early_break(slub, slab, slubIdx)) { + if ((slab = allocGetSlab(size)) == NULL) { pr_devel("No slab found for %d\n", size); return NULL; } diff --git a/core/alloc.h b/core/alloc.h index 7095988..176f7a1 100644 --- a/core/alloc.h +++ b/core/alloc.h @@ -5,8 +5,9 @@ /* * Initialize malloc system */ -int allocSetup(void); +int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr); +int allocPopulate(); /* * Allow malloc to allocate elements of this precise size. * Otherwise the allocation will be in the closest biggest pool. diff --git a/core/allocArea.c b/core/allocArea.c index 7713091..d10d0f0 100644 --- a/core/allocArea.c +++ b/core/allocArea.c @@ -16,10 +16,21 @@ struct memArea { static struct memArea *freeArea; static struct memArea *usedArea; +static int areaMergeFreeArea(struct memArea *prev, struct memArea *next); + void areaInit(void) { list_init(freeArea); list_init(usedArea); + + vaddr_t areaAddr, descAddr, entryAddr; + allocSetup(sizeof(struct memArea), &areaAddr, &descAddr, &entryAddr); + areaAdd(descAddr, PAGE_SIZE, FALSE); + if (entryAddr != descAddr) + areaAdd(entryAddr, PAGE_SIZE, FALSE); + if (areaAddr != descAddr && areaAddr != entryAddr) + areaAdd(areaAddr, PAGE_SIZE, FALSE); + allocPopulate(); } struct memArea *areaFindFit(unsigned int nbPages) @@ -96,6 +107,36 @@ vaddr_t areaAlloc(unsigned int nbPages) return allocated->startAddr; } +int areaAdd(vaddr_t addr, uint nbPages, int isFree) +{ + struct memArea *area; + + struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea)); + if (!newArea) + return (vaddr_t)NULL; + + newArea->nbPages = nbPages; + newArea->startAddr = addr; + + if (isFree) { + area = freeArea; + } else { + area = usedArea; + } + + insertSorted(area, newArea); + + if (isFree) { + if (newArea->prev) + areaMergeFreeArea(newArea->prev, area); + + if (newArea->next) + areaMergeFreeArea(area, newArea->next); + } + + return 0; +} + static int areaMergeFreeArea(struct memArea *prev, struct memArea *next) { if (prev->startAddr + prev->nbPages * PAGE_SIZE != next->startAddr) { diff --git a/core/allocArea.h b/core/allocArea.h index 0bea2cc..509a582 100644 --- a/core/allocArea.h +++ b/core/allocArea.h @@ -1,6 +1,8 @@ #pragma once #include "paging.h" +#include "stdarg.h" void areaInit(void); vaddr_t areaAlloc(unsigned int nbPages); int areaFree(vaddr_t addr); +int areaAdd(vaddr_t addr, uint nbPages, int isFree); diff --git a/core/klibc.h b/core/klibc.h index ea1b89e..248f69e 100644 --- a/core/klibc.h +++ b/core/klibc.h @@ -51,3 +51,4 @@ int vasprintf(char **strp, const char *fmt, va_list ap); #endif #define pr_info(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__) +#define pr_err(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__) diff --git a/core/main.c b/core/main.c index 835d3c2..d514ca1 100644 --- a/core/main.c +++ b/core/main.c @@ -1,4 +1,5 @@ #include "alloc.h" +#include "allocArea.h" #include "exception.h" #include "gdt.h" #include "idt.h" @@ -143,7 +144,8 @@ void kmain(unsigned long magic, unsigned long addr) serialSetup(115200); printf("Setting up allocation system\n"); - allocSetup(); + areaInit(); + //allocSetup(); printf("Setting up thread system\n"); kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));