diff --git a/core/alloc.c b/core/alloc.c index 1448334..fa466e7 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -11,32 +11,56 @@ #define SLUB_SIZE (PAGE_SHIFT - 1) struct slabDesc *slub; -int initSlabDesc(struct slabDesc **desc, size_t size); +int addSlab(struct slabDesc **desc, size_t size); static int formatPage(struct slabDesc *desc, size_t size); -int initSlab(void) +int allocInit(void) { uint start = log2(sizeof(void *)); list_init(slub); for (uint i = start; i < SLUB_SIZE; i++) { - struct slabDesc *slab; - if (initSlabDesc(&slab, 1U << i)) - return ENOMEM; - list_add_tail(slub, slab); + int ret; + if ((ret = allocBookSlab(1U << i))) { + pr_devel("Fail to allocBookSlab %d\n", ret); + return -ENOMEM; + } } return 0; } -int initSlabDesc(struct slabDesc **desc, size_t size) +int allocBookSlab(size_t size) +{ + struct slabDesc *slabEntry; + struct slabDesc *slab; + int slabIdx; + int ret; + if ((ret = addSlab(&slabEntry, size))) + 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; + } + } + list_add_tail(slub, slabEntry); + return 0; +} + +int addSlab(struct slabDesc **desc, size_t size) { if (size > PAGE_SIZE) - return ENOENT; + return -ENOENT; paddr_t alloc = allocPhyPage(); if (alloc == (paddr_t)NULL) - return ENOMEM; - if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) { - return ENOMEM; - } + return -ENOMEM; + if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) + return -ENOMEM; + *desc = (struct slabDesc *)alloc; list_singleton(*desc, *desc); (*desc)->page = (vaddr_t)alloc; @@ -64,7 +88,7 @@ static void *allocFromSlab(struct slabDesc *slab) { vaddr_t *next = slab->freeEl; if (*next == (vaddr_t)NULL) { - pr_devel("Slab %d full\n", slab); + pr_devel("Slab @%d for %d full\n", slab, slab->size); slab->full = 1; } else { slab->freeEl = (void *)(*next); @@ -82,7 +106,7 @@ void *malloc(size_t size) uint slubIdx = 0; list_foreach(slub, slubEntry, slubIdx) { - if(size <= slubEntry->size) + if (size <= slubEntry->size) break; } struct slabDesc *slab; @@ -96,7 +120,11 @@ void *malloc(size_t size) } if (!list_foreach_early_break(slubEntry, slab, slabIdx)) { struct slabDesc *newSlab; - initSlabDesc(&newSlab, slab->size); + int ret; + if ((ret = addSlab(&newSlab, slab->size))) { + pr_devel("Fail to addSlab %d\n", ret); + return NULL; + } list_add_head(slubEntry, newSlab); return allocFromSlab(newSlab); } diff --git a/core/alloc.h b/core/alloc.h index cbe1019..d644cd3 100644 --- a/core/alloc.h +++ b/core/alloc.h @@ -10,6 +10,7 @@ struct slabDesc { struct slabDesc *next; struct slabDesc *prev; }; -int initSlab(void); +int allocInit(void); +int allocBookSlab(size_t size); void *malloc(size_t size); diff --git a/core/main.c b/core/main.c index 15b7ca2..f119452 100644 --- a/core/main.c +++ b/core/main.c @@ -81,7 +81,7 @@ void kmain(unsigned long magic, unsigned long addr) printf("Setting up Serial link (115200)\n"); serialSetup(115200); - initSlab(); + allocInit(); #ifdef RUN_TEST run_test(); #endif diff --git a/core/paging.c b/core/paging.c index 8f44ae9..223073e 100644 --- a/core/paging.c +++ b/core/paging.c @@ -141,7 +141,7 @@ int pageMap(vaddr_t vaddr, paddr_t paddr, int flags) if (!pd[pdEntry].present) { paddr_t ptPhy = allocPhyPage(); if (ptPhy == (vaddr_t)NULL) - return ENOMEM; + return -ENOMEM; pd[pdEntry].user = (flags & PAGING_MEM_USER) ? 1 : 0; pd[pdEntry].present = 1;