link slab allocator to areaAlloc

This commit is contained in:
Mathieu Maret 2021-08-19 16:44:47 +02:00
parent 220597a881
commit 8edaa8646f
6 changed files with 75 additions and 55 deletions

View File

@ -1,6 +1,7 @@
#define pr_fmt(fmt) "[alloc]: " fmt #define pr_fmt(fmt) "[alloc]: " fmt
//#define DEBUG //#define DEBUG
#include "alloc.h" #include "alloc.h"
#include "allocArea.h"
#include "assert.h" #include "assert.h"
#include "errno.h" #include "errno.h"
#include "irq.h" #include "irq.h"
@ -13,6 +14,7 @@
#define IS_SELF_CONTAINED(desc) ((vaddr_t)((desc)->page) == (vaddr_t)(desc)) #define IS_SELF_CONTAINED(desc) ((vaddr_t)((desc)->page) == (vaddr_t)(desc))
static struct slabDesc *slub; static struct slabDesc *slub;
static int allocInitialized = FALSE;
static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab, static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab,
int self_containing); int self_containing);
@ -36,20 +38,19 @@ static struct {
{1024, 2 * PAGE_SIZE, 0}, {1024, 2 * PAGE_SIZE, 0},
{2048, 3 * PAGE_SIZE, 0}, {2048, 3 * PAGE_SIZE, 0},
{4096, 4 * PAGE_SIZE, 0}, {4096, 4 * PAGE_SIZE, 0},
{8192, 8 * PAGE_SIZE, 0},
{16384, 12 * PAGE_SIZE, 0},
{0, 0, 0}}; {0, 0, 0}};
int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr) int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr)
{ {
list_init(slub); 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)); *descAddr = (vaddr_t)allocGetSlab(sizeof(struct slabDesc));
assert(allocBookSlab(sizeof(struct slabEntry), PAGE_SIZE, TRUE) == 0); assert(allocBookSlab(sizeof(struct slabEntry), PAGE_SIZE, TRUE) == 0);
*entryAddr = (vaddr_t)allocGetSlab(sizeof(struct slabEntry)); *entryAddr = (vaddr_t)allocGetSlab(sizeof(struct slabEntry));
assert(allocBookSlab(sizeOfArea, PAGE_SIZE, TRUE) == 0); assert(allocBookSlab(sizeOfArea, PAGE_SIZE, TRUE) == 0);
*areaAddr = (vaddr_t)allocGetSlab(sizeOfArea); *areaAddr = (vaddr_t)allocGetSlab(sizeOfArea);
allocInitialized = TRUE;
return 0; return 0;
} }
@ -95,6 +96,7 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained)
} }
if ((ret = allocSlab(&newSlab, sizeEl, sizeSlab, selfContained))) { if ((ret = allocSlab(&newSlab, sizeEl, sizeSlab, selfContained))) {
pr_devel("Failed to alloc Slab\n");
restore_IRQs(flags); restore_IRQs(flags);
return ret; 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) static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int selfContained)
{ {
uint nbPage, i; uint nbPage, i;
vaddr_t alloc;
pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); 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; return -ENOENT;
} }
nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE); nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE);
paddr_t alloc = allocPhyPage(nbPage); if (allocInitialized) {
if (alloc == (paddr_t)NULL) alloc = areaAlloc(nbPage);
return -ENOMEM; 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++) { for (i = 0; i < nbPage; i++) {
if (pageMap((vaddr_t)alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE)) if (pageMap(alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE))
goto free_page; goto free_page;
}
} }
if (selfContained) { if (selfContained) {
@ -162,7 +171,7 @@ free_page:
static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab,
int selfContained) int selfContained)
{ {
uint nbPage, i; uint nbPage;
pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); 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); nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE);
paddr_t alloc = allocPhyPage(nbPage); vaddr_t alloc = areaAlloc(nbPage);
if (alloc == (paddr_t)NULL) if (alloc == (paddr_t)NULL)
return -ENOMEM; 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) { if (selfContained) {
*desc = (struct slabEntry *)alloc; *desc = (struct slabEntry *)alloc;
(*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry); (*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); return formatPage((*desc), size, sizeSlab, selfContained);
free_page:
for (uint j = 0; j < i; j++) {
pageUnmap((vaddr_t)alloc + i * PAGE_SIZE);
}
return -ENOMEM; return -ENOMEM;
} }
@ -262,6 +261,11 @@ void *malloc(size_t size)
disable_IRQs(flags); 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) { if ((slab = allocGetSlab(size)) == NULL) {
pr_devel("No slab found for %d\n", size); pr_devel("No slab found for %d\n", size);
return NULL; return NULL;
@ -320,11 +324,7 @@ static int freeFromSlab(void *ptr, struct slabEntry *slab)
return 0; return 0;
} }
void free(void *ptr) int freeSlabAllocated(void *ptr){
{
if (!ptr)
return;
struct slabDesc *slab; struct slabDesc *slab;
int slabIdx; int slabIdx;
int flags; int flags;
@ -339,11 +339,21 @@ void free(void *ptr)
{ {
if (freeFromSlab(ptr, slabEntry)) { if (freeFromSlab(ptr, slabEntry)) {
restore_IRQs(flags); restore_IRQs(flags);
return; return 0;
} }
} }
} }
restore_IRQs(flags); 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");
} }

View File

@ -6,19 +6,13 @@
#include "mem.h" #include "mem.h"
#include "stdarg.h" #include "stdarg.h"
struct memArea {
vaddr_t startAddr;
uint nbPages;
struct memArea *next;
struct memArea *prev;
};
static struct memArea *freeArea; static struct memArea *freeArea;
static struct memArea *usedArea; static struct memArea *usedArea;
static int areaMergeFreeArea(struct memArea *prev, struct memArea *next); 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(freeArea);
list_init(usedArea); list_init(usedArea);
@ -30,6 +24,10 @@ void areaInit(void)
areaAdd(entryAddr, PAGE_SIZE, FALSE); areaAdd(entryAddr, PAGE_SIZE, FALSE);
if (areaAddr != descAddr && areaAddr != entryAddr) if (areaAddr != descAddr && areaAddr != entryAddr)
areaAdd(areaAddr, PAGE_SIZE, FALSE); 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(); allocPopulate();
} }
@ -46,22 +44,22 @@ struct memArea *areaFindFit(unsigned int nbPages)
return NULL; return NULL;
} }
static void insertSorted(struct memArea *list, struct memArea *item) static void insertSorted(struct memArea **list, struct memArea *item)
{ {
struct memArea *prev, *cur; struct memArea *prev, *cur;
int count; int count;
prev = NULL; prev = NULL;
list_foreach(list, cur, count) list_foreach(*list, cur, count)
{ {
if (cur->startAddr > item->startAddr) if (cur->startAddr > item->startAddr)
break; break;
prev = cur; prev = cur;
} }
if (prev) if (prev)
list_insert_after(list, prev, item); list_insert_after(*list, prev, item);
else else
list_add_tail(list, item); list_add_tail(*list, item);
} }
vaddr_t areaAlloc(unsigned int nbPages) vaddr_t areaAlloc(unsigned int nbPages)
@ -74,13 +72,15 @@ vaddr_t areaAlloc(unsigned int nbPages)
if (area->nbPages == nbPages) { if (area->nbPages == nbPages) {
list_delete(freeArea, area); list_delete(freeArea, area);
insertSorted(usedArea, area); insertSorted(&usedArea, area);
allocated = area; allocated = area;
} }
struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea)); 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; return (vaddr_t)NULL;
}
// Avoid insertSorted(freeArea, newArea) call by modifying area // Avoid insertSorted(freeArea, newArea) call by modifying area
@ -90,14 +90,14 @@ vaddr_t areaAlloc(unsigned int nbPages)
area->nbPages -= nbPages; area->nbPages -= nbPages;
area->startAddr += nbPages * PAGE_SIZE; area->startAddr += nbPages * PAGE_SIZE;
insertSorted(usedArea, newArea); insertSorted(&usedArea, newArea);
allocated = newArea; allocated = newArea;
for (uint i = 0; i < nbPages; i++) { for (uint i = 0; i < nbPages; i++) {
paddr_t page = allocPhyPage(1); paddr_t page = allocPhyPage(1);
if (page) { if (page) {
pageMap(area->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE); pageMap(newArea->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
} else { } else {
// TODO // TODO
assert(1); assert(1);
@ -109,7 +109,7 @@ vaddr_t areaAlloc(unsigned int nbPages)
int areaAdd(vaddr_t addr, uint nbPages, int isFree) int areaAdd(vaddr_t addr, uint nbPages, int isFree)
{ {
struct memArea *area; struct memArea **area;
struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea)); struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea));
if (!newArea) if (!newArea)
@ -119,19 +119,19 @@ int areaAdd(vaddr_t addr, uint nbPages, int isFree)
newArea->startAddr = addr; newArea->startAddr = addr;
if (isFree) { if (isFree) {
area = freeArea; area = &freeArea;
} else { } else {
area = usedArea; area = &usedArea;
} }
insertSorted(area, newArea); insertSorted(area, newArea);
if (isFree) { if (isFree) {
if (newArea->prev) if (newArea->prev)
areaMergeFreeArea(newArea->prev, area); areaMergeFreeArea(newArea->prev, *area);
if (newArea->next) if (newArea->next)
areaMergeFreeArea(area, newArea->next); areaMergeFreeArea(*area, newArea->next);
} }
return 0; return 0;
@ -175,7 +175,7 @@ int areaFree(vaddr_t addr)
return -1; return -1;
} }
list_delete(usedArea, area); list_delete(usedArea, area);
insertSorted(freeArea, area); insertSorted(&freeArea, area);
if (area->prev) if (area->prev)
areaMergeFreeArea(area->prev, area); areaMergeFreeArea(area->prev, area);

View File

@ -2,7 +2,15 @@
#include "paging.h" #include "paging.h"
#include "stdarg.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); vaddr_t areaAlloc(unsigned int nbPages);
int areaFree(vaddr_t addr); int areaFree(vaddr_t addr);
int areaAdd(vaddr_t addr, uint nbPages, int isFree); int areaAdd(vaddr_t addr, uint nbPages, int isFree);

View File

@ -51,4 +51,4 @@ int vasprintf(char **strp, const char *fmt, va_list ap);
#endif #endif
#define pr_info(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__) #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);}

View File

@ -144,7 +144,7 @@ void kmain(unsigned long magic, unsigned long addr)
serialSetup(115200); serialSetup(115200);
printf("Setting up allocation system\n"); printf("Setting up allocation system\n");
areaInit(); areaInit(firstUsedByMem, lastUsedByMem);
//allocSetup(); //allocSetup();
printf("Setting up thread system\n"); printf("Setting up thread system\n");

View File

@ -85,6 +85,7 @@ static void testAlloc(void)
void *alloc5 = testAllocNSet(1024); void *alloc5 = testAllocNSet(1024);
void *alloc6 = testAllocNSet(1024); void *alloc6 = testAllocNSet(1024);
void *alloc7 = testAllocNSet(4096); void *alloc7 = testAllocNSet(4096);
void *alloc8 = testAllocNSet(8192);
free(alloc1); free(alloc1);
free(alloc2); free(alloc2);
free(alloc3); free(alloc3);
@ -92,6 +93,7 @@ static void testAlloc(void)
free(alloc5); free(alloc5);
free(alloc6); free(alloc6);
free(alloc7); free(alloc7);
free(alloc8);
void *alloc11 = testAllocNSet(1024); void *alloc11 = testAllocNSet(1024);
void *alloc12 = testAllocNSet(1024); void *alloc12 = testAllocNSet(1024);
void *alloc13 = testAllocNSet(1024); void *alloc13 = testAllocNSet(1024);