diff --git a/core/alloc.c b/core/alloc.c index fe5299f..d7414b6 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 "allocArea.h" #include "assert.h" #include "errno.h" #include "irq.h" @@ -13,6 +14,7 @@ #define IS_SELF_CONTAINED(desc) ((vaddr_t)((desc)->page) == (vaddr_t)(desc)) static struct slabDesc *slub; +static int allocInitialized = FALSE; static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab, int self_containing); @@ -36,20 +38,19 @@ static struct { {1024, 2 * PAGE_SIZE, 0}, {2048, 3 * PAGE_SIZE, 0}, {4096, 4 * PAGE_SIZE, 0}, - {8192, 8 * PAGE_SIZE, 0}, - {16384, 12 * PAGE_SIZE, 0}, {0, 0, 0}}; 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); + 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); + *areaAddr = (vaddr_t)allocGetSlab(sizeOfArea); + allocInitialized = TRUE; return 0; } @@ -95,6 +96,7 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained) } if ((ret = allocSlab(&newSlab, sizeEl, sizeSlab, selfContained))) { + pr_devel("Failed to alloc Slab\n"); restore_IRQs(flags); return ret; } @@ -113,6 +115,7 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained) static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int selfContained) { uint nbPage, i; + vaddr_t alloc; pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); @@ -122,14 +125,20 @@ static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int s return -ENOENT; } - nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE); - paddr_t alloc = allocPhyPage(nbPage); - if (alloc == (paddr_t)NULL) - return -ENOMEM; + nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE); + if (allocInitialized) { + alloc = areaAlloc(nbPage); + if (alloc == (paddr_t)NULL) + return -ENOMEM; + } else { + alloc = (vaddr_t)allocPhyPage(nbPage); + if (alloc == (paddr_t)NULL) + return -ENOMEM; - for (i = 0; i < nbPage; i++) { - if (pageMap((vaddr_t)alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE)) - goto free_page; + for (i = 0; i < nbPage; i++) { + if (pageMap(alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE)) + goto free_page; + } } if (selfContained) { @@ -162,7 +171,7 @@ free_page: static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, int selfContained) { - uint nbPage, i; + uint nbPage; pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); @@ -173,15 +182,10 @@ static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, } nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE); - paddr_t alloc = allocPhyPage(nbPage); + vaddr_t alloc = areaAlloc(nbPage); if (alloc == (paddr_t)NULL) return -ENOMEM; - for (i = 0; i < nbPage; i++) { - if (pageMap((vaddr_t)alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE)) - goto free_page; - } - if (selfContained) { *desc = (struct slabEntry *)alloc; (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry); @@ -199,11 +203,6 @@ static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, return formatPage((*desc), size, sizeSlab, selfContained); -free_page: - for (uint j = 0; j < i; j++) { - pageUnmap((vaddr_t)alloc + i * PAGE_SIZE); - } - return -ENOMEM; } @@ -262,6 +261,11 @@ void *malloc(size_t size) disable_IRQs(flags); + if (size >= PAGE_SIZE){ + vaddr_t area = areaAlloc(DIV_ROUND_UP(size, PAGE_SIZE)); + + return (void *)area; + } if ((slab = allocGetSlab(size)) == NULL) { pr_devel("No slab found for %d\n", size); return NULL; @@ -320,11 +324,7 @@ static int freeFromSlab(void *ptr, struct slabEntry *slab) return 0; } -void free(void *ptr) -{ - if (!ptr) - return; - +int freeSlabAllocated(void *ptr){ struct slabDesc *slab; int slabIdx; int flags; @@ -339,11 +339,21 @@ void free(void *ptr) { if (freeFromSlab(ptr, slabEntry)) { restore_IRQs(flags); - return; + return 0; } } } - restore_IRQs(flags); - pr_devel("free: slab not found\n"); + + return -1; +} + +void free(void *ptr) +{ + if (!ptr) + return; + if(!freeSlabAllocated(ptr)) + return; + if(areaFree((vaddr_t)ptr)) + pr_err("free: cannot found origin\n"); } diff --git a/core/allocArea.c b/core/allocArea.c index d10d0f0..5c999ed 100644 --- a/core/allocArea.c +++ b/core/allocArea.c @@ -6,19 +6,13 @@ #include "mem.h" #include "stdarg.h" -struct memArea { - vaddr_t startAddr; - uint nbPages; - struct memArea *next; - struct memArea *prev; -}; static struct memArea *freeArea; static struct memArea *usedArea; static int areaMergeFreeArea(struct memArea *prev, struct memArea *next); -void areaInit(void) +void areaInit(vaddr_t firstMemUsed, vaddr_t lastUsed) { list_init(freeArea); list_init(usedArea); @@ -30,6 +24,10 @@ void areaInit(void) areaAdd(entryAddr, PAGE_SIZE, FALSE); if (areaAddr != descAddr && areaAddr != entryAddr) areaAdd(areaAddr, PAGE_SIZE, FALSE); + + int nbPages = DIV_ROUND_UP((lastUsed - firstMemUsed), PAGE_SIZE); + areaAdd(ALIGN_DOWN(firstMemUsed, PAGE_SIZE), nbPages, FALSE); + areaAdd(ALIGN_DOWN(areaAddr + PAGE_SIZE, PAGE_SIZE), 300 , TRUE); allocPopulate(); } @@ -46,22 +44,22 @@ struct memArea *areaFindFit(unsigned int nbPages) return NULL; } -static void insertSorted(struct memArea *list, struct memArea *item) +static void insertSorted(struct memArea **list, struct memArea *item) { struct memArea *prev, *cur; int count; prev = NULL; - list_foreach(list, cur, count) + list_foreach(*list, cur, count) { if (cur->startAddr > item->startAddr) break; prev = cur; } if (prev) - list_insert_after(list, prev, item); + list_insert_after(*list, prev, item); else - list_add_tail(list, item); + list_add_tail(*list, item); } vaddr_t areaAlloc(unsigned int nbPages) @@ -74,13 +72,15 @@ vaddr_t areaAlloc(unsigned int nbPages) if (area->nbPages == nbPages) { list_delete(freeArea, area); - insertSorted(usedArea, area); + insertSorted(&usedArea, area); allocated = area; } struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea)); - if (!newArea) + if (!newArea){ + pr_devel("Failed to allocated area of %d pages\n", nbPages); return (vaddr_t)NULL; + } // Avoid insertSorted(freeArea, newArea) call by modifying area @@ -90,14 +90,14 @@ vaddr_t areaAlloc(unsigned int nbPages) area->nbPages -= nbPages; area->startAddr += nbPages * PAGE_SIZE; - insertSorted(usedArea, newArea); + insertSorted(&usedArea, newArea); allocated = newArea; for (uint i = 0; i < nbPages; i++) { paddr_t page = allocPhyPage(1); if (page) { - pageMap(area->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE); + pageMap(newArea->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE); } else { // TODO assert(1); @@ -109,7 +109,7 @@ vaddr_t areaAlloc(unsigned int nbPages) int areaAdd(vaddr_t addr, uint nbPages, int isFree) { - struct memArea *area; + struct memArea **area; struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea)); if (!newArea) @@ -119,19 +119,19 @@ int areaAdd(vaddr_t addr, uint nbPages, int isFree) newArea->startAddr = addr; if (isFree) { - area = freeArea; + area = &freeArea; } else { - area = usedArea; + area = &usedArea; } insertSorted(area, newArea); if (isFree) { if (newArea->prev) - areaMergeFreeArea(newArea->prev, area); + areaMergeFreeArea(newArea->prev, *area); if (newArea->next) - areaMergeFreeArea(area, newArea->next); + areaMergeFreeArea(*area, newArea->next); } return 0; @@ -175,7 +175,7 @@ int areaFree(vaddr_t addr) return -1; } list_delete(usedArea, area); - insertSorted(freeArea, area); + insertSorted(&freeArea, area); if (area->prev) areaMergeFreeArea(area->prev, area); diff --git a/core/allocArea.h b/core/allocArea.h index 509a582..292190b 100644 --- a/core/allocArea.h +++ b/core/allocArea.h @@ -2,7 +2,15 @@ #include "paging.h" #include "stdarg.h" -void areaInit(void); +struct memArea { + vaddr_t startAddr; + uint nbPages; + + struct memArea *next; + struct memArea *prev; +}; + +void areaInit(vaddr_t firstMemUsed, vaddr_t lastUsed); 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 248f69e..c4a5490 100644 --- a/core/klibc.h +++ b/core/klibc.h @@ -51,4 +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__) +#define pr_err(fmt, ...) {printf(pr_fmt(fmt), ##__VA_ARGS__); assert(0);} diff --git a/core/main.c b/core/main.c index d514ca1..d6268be 100644 --- a/core/main.c +++ b/core/main.c @@ -144,7 +144,7 @@ void kmain(unsigned long magic, unsigned long addr) serialSetup(115200); printf("Setting up allocation system\n"); - areaInit(); + areaInit(firstUsedByMem, lastUsedByMem); //allocSetup(); printf("Setting up thread system\n"); diff --git a/tests/test.c b/tests/test.c index 2b9ded3..2a87674 100644 --- a/tests/test.c +++ b/tests/test.c @@ -85,6 +85,7 @@ static void testAlloc(void) void *alloc5 = testAllocNSet(1024); void *alloc6 = testAllocNSet(1024); void *alloc7 = testAllocNSet(4096); + void *alloc8 = testAllocNSet(8192); free(alloc1); free(alloc2); free(alloc3); @@ -92,6 +93,7 @@ static void testAlloc(void) free(alloc5); free(alloc6); free(alloc7); + free(alloc8); void *alloc11 = testAllocNSet(1024); void *alloc12 = testAllocNSet(1024); void *alloc13 = testAllocNSet(1024);