diff --git a/core/alloc.c b/core/alloc.c index fa466e7..1b1c3a9 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -7,34 +7,41 @@ #include "mem.h" #include "vga.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 #define SLUB_SIZE (PAGE_SHIFT - 1) struct slabDesc *slub; -int addSlab(struct slabDesc **desc, size_t size); -static int formatPage(struct slabDesc *desc, size_t size); +int addSlab(struct slabDesc **desc, size_t size, int self_containing); +static int formatPage(struct slabDesc *desc, size_t size, int selfContained); int allocInit(void) { uint start = log2(sizeof(void *)); list_init(slub); + int ret; + if ((ret = allocBookSlab(sizeof(struct slabDesc), 1))) { + pr_devel("Fail to allocBookSlab %d for slabDesc :( \n"); + return ret; + } for (uint i = start; i < SLUB_SIZE; i++) { - int ret; - if ((ret = allocBookSlab(1U << i))) { - pr_devel("Fail to allocBookSlab %d\n", ret); - return -ENOMEM; + if ((ret = allocBookSlab(1U << i, 0))) { + pr_devel("Fail to allocBookSlab %d for %d \n", ret, (1U << i)); + return ret; } } return 0; } -int allocBookSlab(size_t size) +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; int slabIdx; int ret; - if ((ret = addSlab(&slabEntry, size))) + if ((ret = addSlab(&slabEntry, size, selfContained))) return ret; list_foreach(slub, slab, slabIdx) { @@ -51,8 +58,9 @@ int allocBookSlab(size_t size) return 0; } -int addSlab(struct slabDesc **desc, size_t size) +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(); @@ -61,21 +69,29 @@ int addSlab(struct slabDesc **desc, size_t size) if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) return -ENOMEM; - *desc = (struct slabDesc *)alloc; + if (selfContained) { + *desc = (struct slabDesc *)alloc; + (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabDesc); + } else { + *desc = malloc(sizeof(struct slabDesc)); + (*desc)->freeEl = (void *)alloc; + } list_singleton(*desc, *desc); (*desc)->page = (vaddr_t)alloc; (*desc)->full = 0; - (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabDesc); (*desc)->size = size; pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->freeEl); - return formatPage((*desc), size); + return formatPage((*desc), size, selfContained); } -static int formatPage(struct slabDesc *desc, size_t size) +static int formatPage(struct slabDesc *desc, size_t size, int selfContained) { - char *cur = (char *)desc + sizeof(struct slabDesc); + char *cur = desc->freeEl; + ulong nbEl = PAGE_SIZE / size - 1; + if (selfContained) + nbEl = (PAGE_SIZE - sizeof(struct slabDesc)) / size - 1; ulong i; - for (i = 0; i < ((PAGE_SIZE - sizeof(struct slabDesc)) / size - 1); i++) { + for (i = 0; i < nbEl; i++) { *((vaddr_t *)cur) = (vaddr_t)cur + size; cur += size; } @@ -114,19 +130,18 @@ void *malloc(size_t size) list_foreach(slubEntry, slab, slabIdx) { if (!slab->full) { - pr_devel("found place in slub %d at idx %d \n", slubIdx, slabIdx); + pr_devel("found place in slub %d at idx %d for size %d\n", slubIdx, slabIdx, size); return allocFromSlab(slab); } } - if (!list_foreach_early_break(slubEntry, slab, slabIdx)) { - struct slabDesc *newSlab; - 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); + + // No room found + struct slabDesc *newSlab; + int ret; + if ((ret = addSlab(&newSlab, slab->size, IS_SELF_CONTAINED(slubEntry)))) { + pr_devel("Fail to addSlab %d\n", ret); + return NULL; } - return NULL; + list_add_head(slubEntry, newSlab); + return allocFromSlab(newSlab); } diff --git a/core/alloc.h b/core/alloc.h index d644cd3..ee6ad3c 100644 --- a/core/alloc.h +++ b/core/alloc.h @@ -11,6 +11,6 @@ struct slabDesc { struct slabDesc *prev; }; int allocInit(void); -int allocBookSlab(size_t size); +int allocBookSlab(size_t size, int selfContained); void *malloc(size_t size);