diff --git a/core/alloc.c b/core/alloc.c index e9a8c7f..d1bfaa1 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -13,7 +13,7 @@ struct slabDesc *slub; int addSlab(struct slabDesc **desc, size_t size, int self_containing); -static int formatPage(struct slabDesc *desc, size_t size, int selfContained); +static int formatPage(struct slabEntry *desc, size_t size, int selfContained); int allocInit(void) { @@ -21,7 +21,11 @@ int allocInit(void) list_init(slub); int ret; if ((ret = allocBookSlab(sizeof(struct slabDesc), 1))) { - pr_devel("Fail to allocBookSlab %d for slabDesc :( \n"); + pr_devel("Fail to allocBookSlab %d for slabDesc :( \n", ret); + return ret; + } + if ((ret = allocBookSlab(sizeof(struct slabEntry), 1))) { + pr_devel("Fail to allocBookSlab %d for slabEntry :( \n", ret); return ret; } for (uint i = start; i <= SLUB_SIZE; i++) { @@ -35,29 +39,59 @@ int allocInit(void) int allocBookSlab(size_t size, int selfContained) { - // pr_devel("%s for size %d is self %d\n", __func__, size, selfContained ); - struct slabDesc *slabEntry; - struct slabDesc *slab; + pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + struct slabDesc *slab = NULL; int slabIdx; int ret; - if ((ret = addSlab(&slabEntry, size, selfContained))) - return ret; list_foreach(slub, slab, slabIdx) { if (slab->size == size) { - pr_devel("Slab already exist"); return -EEXIST; } if (slab->size > size) { - list_insert_before(slub, slab, slabEntry); - return 0; + break; } } - list_add_tail(slub, slabEntry); + struct slabDesc *newSlab; + if ((ret = addSlab(&newSlab, size, selfContained))) + return ret; + if (list_foreach_early_break(slub, slab, slabIdx)) { + list_insert_before(slub, slab, newSlab); + } else { + list_add_tail(slub, newSlab); + } return 0; } int addSlab(struct slabDesc **desc, size_t size, int selfContained) +{ + // pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + if (size > PAGE_SIZE) + return -ENOENT; + paddr_t alloc = allocPhyPage(); + if (alloc == (paddr_t)NULL) + return -ENOMEM; + if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) + return -ENOMEM; + + if (selfContained) { + *desc = (struct slabDesc *)alloc; + ((*desc)->slab).freeEl = (char *)(*desc) + sizeof(struct slabDesc); + } else { + *desc = malloc(sizeof(struct slabDesc)); + (*desc)->slab.freeEl = (void *)alloc; + } + struct slabEntry *slab = &(*desc)->slab; + list_singleton(slab, slab); + slab->page = (vaddr_t)alloc; + slab->full = 0; + slab->size = size; + (*desc)->size = size; + // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->slab.freeEl); + return formatPage(&(*desc)->slab, size, selfContained); +} + +int addSlabEntry(struct slabEntry **desc, size_t size, int selfContained) { pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); if (size > PAGE_SIZE) @@ -69,21 +103,21 @@ int addSlab(struct slabDesc **desc, size_t size, int selfContained) return -ENOMEM; if (selfContained) { - *desc = (struct slabDesc *)alloc; - (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabDesc); + *desc = (struct slabEntry *)alloc; + (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry); } else { - *desc = malloc(sizeof(struct slabDesc)); + *desc = malloc(sizeof(struct slabEntry)); (*desc)->freeEl = (void *)alloc; } list_singleton(*desc, *desc); (*desc)->page = (vaddr_t)alloc; (*desc)->full = 0; (*desc)->size = size; - pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->freeEl); + // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->freeEl); return formatPage((*desc), size, selfContained); } -static int formatPage(struct slabDesc *desc, size_t size, int selfContained) +static int formatPage(struct slabEntry *desc, size_t size, int selfContained) { char *cur = desc->freeEl; ulong nbEl = PAGE_SIZE / size - 1; @@ -95,11 +129,11 @@ static int formatPage(struct slabDesc *desc, size_t size, int selfContained) cur += size; } *((vaddr_t *)cur) = (vaddr_t)NULL; - pr_devel("last at %d allocated %d\n", cur, i + 1); + // pr_devel("last at %d allocated %d\n", cur, i + 1); return 0; } -static void *allocFromSlab(struct slabDesc *slab) +static void *allocFromSlab(struct slabEntry *slab) { vaddr_t *next = slab->freeEl; if (*next == (vaddr_t)NULL) { @@ -117,49 +151,46 @@ void *malloc(size_t size) printf("implement malloc for big size\n"); return NULL; } - struct slabDesc *slubEntry; + struct slabDesc *slab; uint slubIdx; - list_foreach(slub, slubEntry, slubIdx) + list_foreach(slub, slab, slubIdx) { - if (size <= slubEntry->size) + if (size <= slab->size) break; } - struct slabDesc *slab; + struct slabEntry *slabEntry; int slabIdx; - list_foreach(slubEntry, slab, slabIdx) + list_foreach(&slab->slab, slabEntry, slabIdx) { - if (slab->size > slubEntry->size){ - pr_devel("No more room in slub %d\n", slubIdx); - break; - } - if (!slab->full) { - pr_devel("found place in slub %d at idx %d for size %d\n", slubIdx, - slabIdx, size); - return allocFromSlab(slab); + if (!slabEntry->full) { + // pr_devel("found place in slub %d at idx %d for size %d\n", slubIdx, + // slabIdx, size); + return allocFromSlab(slabEntry); } } // No room found - struct slabDesc *newSlab; + struct slabEntry *newSlabEntry; + struct slabEntry *slabList = &slab->slab; int ret; - if ((ret = addSlab(&newSlab, slubEntry->size, IS_SELF_CONTAINED(slubEntry)))) { - pr_devel("Fail to addSlab %d\n", ret); + if ((ret = addSlabEntry(&newSlabEntry, slab->size, IS_SELF_CONTAINED(&slab->slab)))) { + pr_devel("Fail to addSlabEntry %d\n", ret); return NULL; } - pr_devel("Allocate new slab for object of size %d\n", slubEntry->size); - list_add_head(slubEntry, newSlab); - return allocFromSlab(newSlab); + pr_devel("Allocate new slab for object of size %d\n", slab->size); + list_add_tail(slabList, newSlabEntry); + return allocFromSlab(newSlabEntry); } -int slabFree(void *ptr, struct slabDesc *slab) +int slabFree(void *ptr, struct slabEntry *slab) { - struct slabDesc *slabEntry; + struct slabEntry *slabEntry; int slabIdx; list_foreach(slab, slabEntry, slabIdx) { if ((slabEntry->page <= (vaddr_t)ptr) && ((vaddr_t)ptr < (slabEntry->page + PAGE_SIZE))) { - pr_devel("free place! was %d is now %d\n", slabEntry->freeEl, ptr); + // pr_devel("free place! was %d is now %d\n", slabEntry->freeEl, ptr); *((vaddr_t *)ptr) = (vaddr_t)slabEntry->freeEl; slabEntry->freeEl = ptr; slabEntry->full = 0; @@ -177,8 +208,13 @@ void free(void *ptr) int slabIdx; list_foreach(slub, slab, slabIdx) { - if (slabFree(ptr, slab)) - return; + struct slabEntry *slabEntry; + int entryIdx; + list_foreach(&slab->slab, slabEntry, entryIdx) + { + if (slabFree(ptr, slabEntry)) + return; + } } pr_devel("free: slab not found\n"); } diff --git a/core/alloc.h b/core/alloc.h index f339a9d..4d3058e 100644 --- a/core/alloc.h +++ b/core/alloc.h @@ -2,11 +2,18 @@ #include "paging.h" #include "stdarg.h" -struct slabDesc { +struct slabEntry { vaddr_t page; size_t size; void *freeEl; char full; + struct slabEntry *next; + struct slabEntry *prev; +}; + +struct slabDesc { + struct slabEntry slab; + size_t size; struct slabDesc *next; struct slabDesc *prev; }; diff --git a/tests/test.c b/tests/test.c index 6ebb120..635e125 100644 --- a/tests/test.c +++ b/tests/test.c @@ -40,6 +40,12 @@ void testPhymem(void) static void testAlloc(void) { + for( uint i = 0; i < PAGE_SIZE/(sizeof(struct slabEntry)); i++){ + malloc(sizeof(struct slabEntry)); + } + for( uint i = 0; i < PAGE_SIZE/(sizeof(struct slabDesc)); i++){ + malloc(sizeof(struct slabDesc)); + } assert(malloc(1)); assert(malloc(2)); assert(malloc(3)); @@ -55,6 +61,9 @@ static void testAlloc(void) assert(malloc(1024)); assert(malloc(1024)); assert(malloc(1024)); + assert(malloc(1024)); + assert(malloc(2048)); + //assert(malloc(4096)); } static void testPaging(void)