From 5ab68d8197deb32d3dde10830d32fc8762f44e67 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Mon, 25 Jan 2021 20:05:38 +0100 Subject: [PATCH] Various cleaning --- core/alloc.c | 59 ++++++++++++++++++++++++++++++++++++++------------ core/alloc.h | 21 +++++++++++++----- core/kthread.c | 6 +++++ drivers/vga.c | 39 +++++++++++++++++++-------------- drivers/vga.h | 2 ++ 5 files changed, 92 insertions(+), 35 deletions(-) diff --git a/core/alloc.c b/core/alloc.c index 91442ef..75f2ad5 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -14,9 +14,12 @@ // Slab will contains object from sizeof(void *) to PAGE_SIZE/2 by pow2 static struct slabDesc *slub; -int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab, int self_containing); -int allocSlabEntry(struct slabEntry **desc, size_t sizeEl, size_t sizeSlab, int selfContained); +static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab, + int self_containing); +static int allocSlabEntry(struct slabEntry **desc, size_t sizeEl, size_t sizeSlab, + int selfContained); static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int selfContained); +static int freeFromSlab(void *ptr, struct slabEntry *slab); static struct { size_t elementSize; @@ -44,26 +47,30 @@ int allocSetup(void) for (uint i = 0; initSlab[i].elementSize != 0; i++) { int ret; + if ((ret = allocBookSlab(initSlab[i].elementSize, initSlab[i].slabSize, initSlab[i].isSelf))) { if (ret == -EEXIST) continue; pr_devel("Fail to allocBookSlab %d for %d \n", ret, (1U << i)); + return ret; } } + return 0; } int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained) { - pr_devel("%s for element of size %d is self %d\n", __func__, sizeEl, selfContained); struct slabDesc *slab = NULL; struct slabDesc *newSlab = NULL; int slabIdx; int ret; int flags; + pr_devel("%s for element of size %d is self %d\n", __func__, sizeEl, selfContained); + disable_IRQs(flags); list_foreach(slub, slab, slabIdx) { @@ -88,14 +95,16 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained) } restore_IRQs(flags); + return 0; } -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; pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + sizeSlab = MAX(sizeSlab, PAGE_SIZE); if (size > sizeSlab) { pr_devel("size of element %d are bigger than slab size %d\n", size, sizeSlab); @@ -106,6 +115,7 @@ int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int selfCont paddr_t alloc = 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; @@ -118,27 +128,31 @@ int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int selfCont *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 = sizeSlab; (*desc)->size = size; - // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->slab.freeEl); + return formatPage(&(*desc)->slab, size, sizeSlab, selfContained); free_page: for (uint j = 0; j < i; j++) { pageUnmap((vaddr_t)alloc + i * PAGE_SIZE); } + return -ENOMEM; } -int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, int selfContained) +static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, + int selfContained) { uint nbPage, i; pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + sizeSlab = MAX(sizeSlab, PAGE_SIZE); if (size > sizeSlab) { pr_devel("size of element %d are bigger than slab size %d\n", size, sizeSlab); @@ -149,6 +163,7 @@ int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, int se paddr_t alloc = 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; @@ -161,17 +176,19 @@ int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab, int se *desc = malloc(sizeof(struct slabEntry)); (*desc)->freeEl = (void *)alloc; } + list_singleton(*desc, *desc); (*desc)->page = (vaddr_t)alloc; (*desc)->full = 0; (*desc)->size = sizeSlab; - // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->freeEl); + return formatPage((*desc), size, sizeSlab, selfContained); free_page: for (uint j = 0; j < i; j++) { pageUnmap((vaddr_t)alloc + i * PAGE_SIZE); } + return -ENOMEM; } @@ -179,36 +196,42 @@ static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int { char *cur = desc->freeEl; ulong nbEl = sizeSlab / size - 1; + if (selfContained) nbEl = (sizeSlab - sizeof(struct slabDesc)) / size - 1; - ulong i; - for (i = 0; i < nbEl; i++) { + + for (ulong i = 0; i < nbEl; i++) { *((vaddr_t *)cur) = (vaddr_t)cur + size; cur += size; } + *((vaddr_t *)cur) = (vaddr_t)NULL; - // pr_devel("last at %d allocated %d\n", cur, i + 1); + return 0; } static void *allocFromSlab(struct slabEntry *slab) { vaddr_t *next = slab->freeEl; + if (*next == (vaddr_t)NULL) { pr_devel("Slab @%d is now full\n", slab); slab->full = 1; } else { slab->freeEl = (void *)(*next); } + return (void *)next; } void *malloc(size_t size) { + struct slabEntry *slabEntry; struct slabDesc *slab = NULL; uint slubIdx; void *ret; int flags; + int slabIdx; disable_IRQs(flags); @@ -223,8 +246,6 @@ void *malloc(size_t size) return NULL; } - struct slabEntry *slabEntry; - int slabIdx; list_foreach(&slab->slab, slabEntry, slabIdx) { if (!slabEntry->full) { @@ -241,40 +262,48 @@ void *malloc(size_t size) struct slabEntry *slabList = &slab->slab; size_t slabSize = MAX(PAGE_SIZE, size); int retSlab; + if ((retSlab = allocSlabEntry(&newSlabEntry, slab->size, slabSize, IS_SELF_CONTAINED(&slab->slab)))) { pr_devel("Fail to allocSlabEntry %d\n", retSlab); restore_IRQs(flags); return NULL; } + pr_devel("Allocate new slab for object of size %d\n", slab->size); list_add_tail(slabList, newSlabEntry); ret = allocFromSlab(newSlabEntry); + restore_IRQs(flags); + return ret; } -int freeFromSlab(void *ptr, struct slabEntry *slab) +static int freeFromSlab(void *ptr, struct slabEntry *slab) { struct slabEntry *slabEntry; int slabIdx; + list_foreach(slab, slabEntry, slabIdx) { if ((slabEntry->page <= (vaddr_t)ptr) && ((vaddr_t)ptr < (slabEntry->page + slabEntry->size))) { - // pr_devel("free place! was %d is now %d\n", slabEntry->freeEl, ptr); + if (slabEntry->full) { *((vaddr_t *)ptr) = (vaddr_t)NULL; } else { *((vaddr_t *)ptr) = (vaddr_t)slabEntry->freeEl; } + slabEntry->freeEl = ptr; slabEntry->full = 0; return 1; } } + return 0; } + void free(void *ptr) { if (!ptr) @@ -285,6 +314,7 @@ void free(void *ptr) int flags; disable_IRQs(flags); + list_foreach(slub, slab, slabIdx) { struct slabEntry *slabEntry; @@ -297,6 +327,7 @@ void free(void *ptr) } } } + restore_IRQs(flags); pr_devel("free: slab not found\n"); } diff --git a/core/alloc.h b/core/alloc.h index 522122d..7095988 100644 --- a/core/alloc.h +++ b/core/alloc.h @@ -2,6 +2,22 @@ #include "paging.h" #include "stdarg.h" +/* + * Initialize malloc system + */ +int allocSetup(void); + +/* + * Allow malloc to allocate elements of this precise size. + * Otherwise the allocation will be in the closest biggest pool. + * */ +int allocBookSlab(size_t size, size_t sizeSlab, int selfContained); + +void *malloc(size_t size); +void free(void *ptr); + +/* Stuct definition shared for test purpose + */ struct slabEntry { vaddr_t page; size_t size; @@ -17,8 +33,3 @@ struct slabDesc { struct slabDesc *next; struct slabDesc *prev; }; -int allocSetup(void); -int allocBookSlab(size_t size, size_t sizeSlab, int selfContained); - -void *malloc(size_t size); -void free(void *ptr); diff --git a/core/kthread.c b/core/kthread.c index fe00b68..78e115a 100644 --- a/core/kthread.c +++ b/core/kthread.c @@ -13,17 +13,23 @@ static struct kthread *threadWithTimeout; void kthreadExit() { uint32_t flags; + disable_IRQs(flags); + struct kthread *current = currentThread; struct kthread *next = kthreadSelectNext(); + if (next == current) assert("cannot exit thread"); + currentThread->state = EXITING; currentThread = next; currentThread->state = RUNNING; cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete, (uint32_t)current); + restore_IRQs(flags); + return; } diff --git a/drivers/vga.c b/drivers/vga.c index 8953273..82f5e9c 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -27,7 +27,7 @@ int VGASetup(uint bgColor, uint color) static void clearScreen(uint bgColor) { uint32_t flags; - long int colorAttr = bgColor << 12; + long int colorAttr = bgColor << 12; disable_IRQs(flags); for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) { @@ -39,7 +39,7 @@ static void clearScreen(uint bgColor) void VGAclearLine(uint bgColor, uint line) { uint32_t flags; - long int colorAttr = bgColor << 12; + long int colorAttr = bgColor << 12; if (line >= VGA_HEIGHT) return; @@ -55,41 +55,46 @@ void VGAPrintf(uint color, uint bgColor, int startX, int startY, const char *for { int flags; char tmp[VGA_WIDTH]; - int idx = 0; + int idx = 0; disable_IRQs(flags); va_list ap; va_start(ap, format); - int ret = vsnprintf(tmp, sizeof(tmp), format, ap); + int ret = vsnprintf(tmp, sizeof(tmp), format, ap); while (ret > 0 && tmp[idx]) { - printCharDetails(tmp[idx++], color, bgColor, startX++, startY); + printCharDetails(tmp[idx++], color, bgColor, startX++, startY); } va_end(ap); - restore_IRQs(flags); } static void printCharDetails(const char str, uint color, uint bgColor, int startX, int startY) { - long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; - vga[VGA_WIDTH * startY + startX] = colorAttr | str; + int pos = VGA_WIDTH * startY + startX; + + if (pos > VGA_WIDTH * VGA_HEIGHT || pos < 0) + return; + + long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; + vga[pos] = colorAttr | str; } void VGAScrollUp(void) { - long int colorAttr = vgaBgColor << 12; + long int colorAttr = vgaBgColor << 12; int flags; disable_IRQs(flags); - for (int i = 1; i < VGA_HEIGHT - 1; i++) { // last line is status line. Do not scroll it + for (int i = 1; i < VGA_HEIGHT - VGA_STATUS_LINE_HEIGHT; + i++) { // last line is status line. Do not scroll it memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i], VGA_WIDTH * sizeof(short)); } for (int i = 0; i < VGA_WIDTH; i++) { - vga[(VGA_HEIGHT - 2) * VGA_WIDTH + i] = colorAttr; + vga[(VGA_HEIGHT - 1 - VGA_STATUS_LINE_HEIGHT) * VGA_WIDTH + i] = colorAttr; } restore_IRQs(flags); } @@ -102,7 +107,7 @@ void VGAPutc(const char str) if (str == '\n') { line++; col = 0; - if (line >= VGA_HEIGHT - 1) { + if (line >= VGA_HEIGHT - VGA_STATUS_LINE_HEIGHT) { VGAScrollUp(); line--; } @@ -113,6 +118,8 @@ void VGAPutc(const char str) if (col < 0) { col = VGA_WIDTH - 1; line--; + if (line < 0) + line = 0; } printCharDetails(' ', vgaColor, vgaBgColor, col, line); } else { @@ -121,7 +128,7 @@ void VGAPutc(const char str) col = 0; line++; } - if (line >= VGA_HEIGHT - 1) { + if (line >= VGA_HEIGHT - VGA_STATUS_LINE_HEIGHT) { VGAScrollUp(); line--; } @@ -148,9 +155,9 @@ void cursorDisable(void) static void cursorMove(int x, int y) { - long int colorAttr = (vgaBgColor << 4 | (vgaColor & 0x0f)) << 8; - uint16_t pos = y * VGA_WIDTH + x; - vga[pos] = colorAttr; + long int colorAttr = (vgaBgColor << 4 | (vgaColor & 0x0f)) << 8; + uint16_t pos = y * VGA_WIDTH + x; + vga[pos] = colorAttr; outb(0x3D4, 0x0F); outb(0x3D5, (uint8_t)(pos & 0xFF)); diff --git a/drivers/vga.h b/drivers/vga.h index d9f47a4..ae608ac 100644 --- a/drivers/vga.h +++ b/drivers/vga.h @@ -17,6 +17,8 @@ #define VGA_WIDTH 80 #define VGA_HEIGHT 25 +#define VGA_STATUS_LINE_HEIGHT 1 + int VGASetup(uint bgColor, uint color); void VGAPutc(const char str); void VGAPrintf(uint color, uint bgColor, int startX, int startY, const char *format, ...);