diff --git a/include/mm/kmalloc.h b/include/mm/kmalloc.h index a1e4f01..d3e256f 100644 --- a/include/mm/kmalloc.h +++ b/include/mm/kmalloc.h @@ -4,6 +4,6 @@ void _kmalloc_init(void); -void *kmalloc(size_t size); -void *kzalloc(size_t size); +void *kmalloc(size_t size) __attribute__ ((alloc_size (1))); +void *kzalloc(size_t size) __attribute__ ((alloc_size (1))); kstatus kfree(void *addr); diff --git a/include/mm/slab.h b/include/mm/slab.h index 81d30b9..26d1998 100644 --- a/include/mm/slab.h +++ b/include/mm/slab.h @@ -43,11 +43,16 @@ struct ma_cache { uint16_t flags; // Not useful yet uint32_t num; // Number of objects per slab uint32_t slabsize; // How many pages does a single slab take up. Useful for objects > PAGE_SIZE - + uint16_t color; // Max color of the slab + uint16_t color_next; // Next color to use + uint16_t alignment; // Alignment required of the objects. Default is 8 bytes if 0 is passed struct ma_slab *slabs_free; struct ma_slab *slabs_partial; struct ma_slab *slabs_used; + void (*constructor)(void *, size_t); + void (*destructor)(void *, size_t); + atomic_flag lock; char name[KCACHE_NAME_LEN]; @@ -55,6 +60,6 @@ struct ma_cache { void *ma_cache_alloc(struct ma_cache *kcache, uint32_t flags); kstatus ma_cache_dealloc(void *object); -struct ma_cache *ma_cache_create(char *name, size_t size, uint32_t flags, void (*constructor)(void *, size_t), void (*destructor)(void *, size_t)); +struct ma_cache *ma_cache_create(char *name, size_t size, uint32_t flags, uint16_t align, void (*constructor)(void *, size_t), void (*destructor)(void *, size_t)); void cache_info(struct ma_cache *cache); void create_base_caches(); \ No newline at end of file diff --git a/include/neobbo.h b/include/neobbo.h index 597ca10..2ec95da 100644 --- a/include/neobbo.h +++ b/include/neobbo.h @@ -27,6 +27,8 @@ typedef char link_symbol_ptr[]; #define SIZE_IN_PAGES(size) size/PAGE_SIZE +#define UNLIKELY(c) (__builtin_expect(c, 0)) + struct kernel_info *get_kinfo(); void initialize_kinfo(); void kkill(void); // phase this out in favor of assert \ No newline at end of file diff --git a/src/mm/kmalloc.c b/src/mm/kmalloc.c index 3a2bf23..69c95bc 100644 --- a/src/mm/kmalloc.c +++ b/src/mm/kmalloc.c @@ -7,25 +7,25 @@ struct ma_cache *kmalloc_caches[14] = {0}; // Create various sizes of caches to be used by kmalloc void _kmalloc_init(void){ - kmalloc_caches[0] = ma_cache_create("kmalloc16", 16, 0, NULL, NULL); - kmalloc_caches[1] = ma_cache_create("kmalloc32", 32, 0, NULL, NULL); - kmalloc_caches[2] = ma_cache_create("kmalloc64", 64, 0, NULL, NULL); - kmalloc_caches[3] = ma_cache_create("kmalloc128", 128, 0, NULL, NULL); - kmalloc_caches[4] = ma_cache_create("kmalloc256", 256, 0, NULL, NULL); - kmalloc_caches[5] = ma_cache_create("kmalloc512", 512, 0, NULL, NULL); - kmalloc_caches[6] = ma_cache_create("kmalloc1K", 1024, 0, NULL, NULL); - kmalloc_caches[7] = ma_cache_create("kmalloc4K", 4096, 0, NULL, NULL); - kmalloc_caches[8] = ma_cache_create("kmalloc8K", 8192, 0, NULL, NULL); - kmalloc_caches[9] = ma_cache_create("kmalloc32K", 32768, 0, NULL, NULL); - kmalloc_caches[10] = ma_cache_create("kmalloc64K", 65536, 0, NULL, NULL); - kmalloc_caches[11] = ma_cache_create("kmalloc131K", 131072, 0, NULL, NULL); - kmalloc_caches[12] = ma_cache_create("kmalloc524K", 524288, 0, NULL, NULL); - kmalloc_caches[13] = ma_cache_create("kmalloc1M", 1048576, 0, NULL, NULL); +kmalloc_caches[0] = ma_cache_create("kmalloc16", 16, 0, 8, NULL, NULL); +kmalloc_caches[1] = ma_cache_create("kmalloc32", 32, 0, 8, NULL, NULL); +kmalloc_caches[2] = ma_cache_create("kmalloc64", 64, 0, 8, NULL, NULL); +kmalloc_caches[3] = ma_cache_create("kmalloc128", 128, 0, 8, NULL, NULL); +kmalloc_caches[4] = ma_cache_create("kmalloc256", 256, 0, 8, NULL, NULL); +kmalloc_caches[5] = ma_cache_create("kmalloc512", 512, 0, 8, NULL, NULL); +kmalloc_caches[6] = ma_cache_create("kmalloc1K", 1024, 0, 8, NULL, NULL); +kmalloc_caches[7] = ma_cache_create("kmalloc4K", 4096, 0, 8, NULL, NULL); +kmalloc_caches[8] = ma_cache_create("kmalloc8K", 8192, 0, 8, NULL, NULL); +kmalloc_caches[9] = ma_cache_create("kmalloc32K", 32768, 0, 8, NULL, NULL); +kmalloc_caches[10] = ma_cache_create("kmalloc64K", 65536, 0, 8, NULL, NULL); +kmalloc_caches[11] = ma_cache_create("kmalloc131K", 131072, 0, 8, NULL, NULL); +kmalloc_caches[12] = ma_cache_create("kmalloc524K", 524288, 0, 8, NULL, NULL); +kmalloc_caches[13] = ma_cache_create("kmalloc1M", 1048576, 0, 8, NULL, NULL); } size_t sizes[14] = {16, 32, 64, 128, 256, 512, 1024, 4096, 8192, 32768, 65536, 131072, 524288, 1048756}; -void *kmalloc(size_t size){ +__attribute__((malloc)) void *kmalloc(size_t size) { if(size > 1048576){ klog(__func__, "Attempted to allocate more than max size (1M)"); return NULL; @@ -52,6 +52,7 @@ void *kzalloc(size_t size){ if(addr == NULL){ return NULL; } + kprintf("addr: 0x{x}, size: {d}", addr, size); memset(addr, 0, size); return addr; } diff --git a/src/mm/pmm.c b/src/mm/pmm.c index 612fac7..411227c 100644 --- a/src/mm/pmm.c +++ b/src/mm/pmm.c @@ -26,8 +26,8 @@ atomic_flag pmm_lock = ATOMIC_FLAG_INIT; void pmm_free(uint64_t *addr){ acquire_spinlock(&pmm_lock); uint64_t *virt_addr = (uint64_t*)((uint64_t)addr+get_kinfo()->hhdmoffset); - /* Make the given page point to the previous free page */ + /* Make the given page point to the previous free page */ *virt_addr = (uint64_t)free_list; /* Make the free_list point to the newly freed page */ @@ -66,13 +66,8 @@ void pmm_init(){ for(uint64_t i = 0; i < memmap_response->entry_count; i++){ switch (entries[i]->type) { case LIMINE_MEMMAP_USABLE: - //kprintf("usable: base: 0x{x}, length: 0x{xn}", entries[i]->base, entries[i]->length); mem_size += entries[i]->length; break; - default: - ; - //kprintf("base: 0x{x}, length: 0x{xn}", entries[i]->base, entries[i]->length); - } } @@ -105,4 +100,4 @@ void pmm_init(){ } } -} \ No newline at end of file +} diff --git a/src/mm/slab.c b/src/mm/slab.c index db0c23c..422c366 100644 --- a/src/mm/slab.c +++ b/src/mm/slab.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -22,6 +23,61 @@ enum SLAB_STATE { USED }; +void _unlink_slab(struct ma_slab *slab, struct ma_slab **list){ + if(*list == slab){ + *list = slab->next; + if (slab->next) slab->next->prev = NULL; + }else{ + if(slab->next) slab->next->prev = slab->prev; + if(slab->prev) slab->prev->next = slab->next; + } + + slab->next = NULL; + slab->prev = NULL; +} + +void _link_slab(struct ma_slab *slab, struct ma_slab **list){ + if(*list){ + slab->next = *list; + (*list)->prev = slab; + } + *list = slab; +} + +void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ + struct ma_cache *cache = slab->cache; + struct ma_slab **list; + struct ma_slab **new_list; + + if(slab->refcount == 0){ + list = &cache->slabs_free; + }else if(slab->refcount == slab->cache->num){ + list = &cache->slabs_used; + }else{ + list = &cache->slabs_partial; + } + + switch (newstate) { + case FREE: + new_list = &cache->slabs_free; + break; + case PARTIAL: + new_list = &cache->slabs_partial; + break; + case USED: + new_list = &cache->slabs_used; + break; + default: + klog(__func__, "Unknown new state!"); + return; + } + + _unlink_slab(slab, list); + + _link_slab(slab, new_list); + +} + // Gets free object from slab and handles stuff uint64_t *_ma_slab_get_free_obj(struct ma_slab *slab){ @@ -35,29 +91,19 @@ uint64_t *_ma_slab_get_free_obj(struct ma_slab *slab){ return NULL; } - if(slab->free->next != NULL){ + slab->free = slab->free->next; - slab->free = slab->free->next; - }else{ - slab->free = NULL; - } - - // Move the slab from the free to the partial list on the first time it's allocated from if(slab->refcount == 0){ - if(slab->prev != NULL){ - slab->prev->next = slab->next; - }else{ - slab->cache->slabs_free = NULL; - } + _unlink_slab(slab, &slab->cache->slabs_free); - /* If there is a partial slab head then make it the head and do other stuff */ - if(slab->cache->slabs_partial != NULL){ - slab->cache->slabs_partial->next = slab; - slab->prev = slab->cache->slabs_partial; + if(slab->cache->num == 1){ + /* If max object number in slab is 1, then move the slab directly to + * used list to prevent bug with _ma_move_slab() + */ + _link_slab(slab, &slab->cache->slabs_used); + }else{ + _link_slab(slab, &slab->cache->slabs_partial); } - - slab->next = NULL; - slab->cache->slabs_partial = slab; } slab->refcount++; @@ -72,24 +118,34 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ // Put the addresses in the slab structure into the bufctls if(kcache->objsize >= 512){ - /* Here we store the bufctls seperately from the actual objects - * - */ + // Here we store the bufctls seperately from the actual objects - slab_structure->free = (struct ma_bufctl*)(va_alloc_contigious_pages(1)); // Store the bufctls off-page - memset(slab_structure->free, 0, 4096); + slab_structure->free = va_alloc_contigious_pages(1); // Store the bufctls off-page + memset(slab_structure->free, 0, PAGE_SIZE); uint64_t slabsize = kcache->slabsize; - void *mstart = va_alloc_contigious_pages(kcache->slabsize); + void *mstart = va_alloc_contigious_pages(kcache->slabsize) + kcache->color_next; + struct page *page; for(size_t j = 0; j < kcache->slabsize; j++){ - get_page((void*)((uint64_t)mstart + j*PAGE_SIZE))->slab = slab_structure; - get_page((void*)((uint64_t)mstart + j*PAGE_SIZE))->bufctls = slab_structure->free; + page = get_page((void*)((uint64_t)mstart + j*PAGE_SIZE)); + page->slab = slab_structure; + page->bufctls = slab_structure->free; } for(size_t i = 0; i < (PAGE_SIZE * slabsize)/kcache->objsize; i++){ - ((struct ma_bufctl*)((uint64_t)slab_structure->free + sizeof(struct ma_bufctl)*(i)))->startaddr = (size_t*)((uint64_t)mstart + i * kcache->objsize); - ((struct ma_bufctl*)((uint64_t)slab_structure->free + sizeof(struct ma_bufctl)*(i)))->next = (struct ma_bufctl*)((uint64_t)slab_structure->free + sizeof(struct ma_bufctl)*(i+1)); + struct ma_bufctl *current_obj = ((struct ma_bufctl*)((uint64_t)slab_structure->free + sizeof(struct ma_bufctl)*(i))); + current_obj->startaddr = (size_t*)((uint64_t)mstart + i * kcache->objsize); + + if(i+1 < kcache->num){ + current_obj->next = (struct ma_bufctl*)((uint64_t)slab_structure->free + sizeof(struct ma_bufctl)*(i+1)); + }else{ + current_obj->next = NULL; + } + + if(kcache->constructor){ + kcache->constructor(current_obj->startaddr, kcache->objsize); + } } }else{ @@ -99,7 +155,7 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ * Their startaddr is the same as the address of the bufctl, since the objects act as the bufctls */ - slab_structure->free = va_alloc_contigious_pages(kcache->slabsize); + slab_structure->free = va_alloc_contigious_pages(kcache->slabsize) + kcache->color_next; get_page(slab_structure->free)->slab = slab_structure; get_page(slab_structure->free)->bufctls = slab_structure->free; @@ -107,182 +163,68 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ uint64_t size = (kcache->objsize >= sizeof(struct ma_bufctl)) ? kcache->objsize : sizeof(struct ma_bufctl); for(size_t i = 0; i < kcache->num; i++){ - ((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i))->startaddr = (size_t*)((uint64_t)slab_structure->free + i * size); - serial_kprintf("{s}: Adding 0x{x} to freelist\n", kcache->name, (size_t*)((uint64_t)slab_structure->free + i * size)); + struct ma_bufctl *current_obj = ((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i)); + current_obj->startaddr = (size_t*)((uint64_t)slab_structure->free + i * size); if(i+1 < kcache->num){ - ((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i))->next = (struct ma_bufctl*)((uint64_t)slab_structure->free + size*(i+1)); + current_obj->next = (struct ma_bufctl*)((uint64_t)slab_structure->free + size*(i+1)); }else{ - ((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i))->next = NULL; + current_obj->next = NULL; + } + + if(kcache->constructor){ + kcache->constructor(current_obj->startaddr, kcache->objsize); } } - - //memcpy(get_page(slab_structure->free)->bufctls, slab_structure->free, kcache->slabsize * PAGE_SIZE); } - //asm("int $1"); - - if(kcache->slabs_free == NULL){ - kcache->slabs_free = slab_structure; - }else{ - // Change head - kcache->slabs_free->next = slab_structure; - slab_structure->prev = kcache->slabs_free; - kcache->slabs_free = slab_structure; - } + kcache->color_next = (kcache->color_next + kcache->alignment > kcache->color) ? 0 : kcache->color_next + kcache->alignment; + + _link_slab(slab_structure, &kcache->slabs_free); slab_structure->cache = kcache; return KERNEL_STATUS_SUCCESS; } -// TODO: fix this complicated POS -void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ - struct ma_cache *cache = slab->cache; - struct ma_slab *sb = 0; - switch (newstate) { - case FREE: - if(cache->slabs_partial != NULL){ - sb = cache->slabs_partial; - while(sb != NULL){ - if(sb == slab){ - goto free_common; - } - sb = sb->prev; - } - } - if(cache->slabs_used != NULL){ - sb = cache->slabs_used; - while(sb != NULL){ - if(sb == slab){ - goto free_common; - } - sb = sb->prev; - } - } - return; - case PARTIAL: - if(cache->slabs_free != NULL){ - sb = cache->slabs_free; - while(sb != NULL){ - if(sb == slab){ - goto partial_common; - } - sb = sb->prev; - } - } - - if(cache->slabs_used != NULL){ - sb = cache->slabs_used; - while(sb != NULL){ - if(sb == slab){ - goto partial_common; - } - sb = sb->prev; - } - } - return; - - case USED: - if(cache->slabs_free != NULL){ - sb = cache->slabs_free; - while(sb != NULL){ - if(sb == slab){ - goto used_common; - } - sb = sb->prev; - } - } - - if(cache->slabs_partial != NULL){ - sb = cache->slabs_partial; - while(sb != NULL){ - if(sb == slab){ - goto used_common; - } - sb = sb->prev; - } - } - return; - } - - free_common: - - slab->next = NULL; - slab->prev = NULL; - - // Preserve the linkage - if(sb->prev != NULL){ - if(sb->next != NULL){ - sb->next->prev = sb->prev; - } - sb->prev->next = sb->next; - } - - if(cache->slabs_free != NULL){ - cache->slabs_free->next = slab; - slab->prev = cache->slabs_free; - } - - cache->slabs_free = slab; - - return; - partial_common: - - slab->next = NULL; - slab->prev = NULL; - - if(sb->prev != NULL){ - if(sb->next != NULL){ - sb->next->prev = sb->prev; - } - sb->prev->next = sb->next; - } - - if(cache->slabs_partial != NULL){ - cache->slabs_partial->next = slab; - slab->prev = cache->slabs_partial; - } - - cache->slabs_partial = slab; - - return; - used_common: - slab->next = NULL; - slab->prev = NULL; - - if(sb->prev != NULL){ - if(sb->next != NULL){ - sb->next->prev = sb->prev; - } - sb->prev->next = sb->next; - } - - if(cache->slabs_used != NULL){ - cache->slabs_used->next = slab; - slab->prev = cache->slabs_used; - } - - cache->slabs_used = slab; - - return; - -} - -struct ma_cache *ma_cache_create(char *name, size_t size, uint32_t flags, void (*constructor)(void *, size_t), void (*destructor)(void *, size_t)){ +struct ma_cache *ma_cache_create(char *name, size_t size, uint32_t flags, uint16_t align, void (*constructor)(void *, size_t), void (*destructor)(void *, size_t)){ acquire_spinlock(&caches_lock); struct ma_cache *kcache = (struct ma_cache*)va_alloc_contigious_pages(1); - memset(kcache, 0, 4096); + + assert(kcache && "kcache is null!"); + + memset(kcache, 0, PAGE_SIZE); memcpy(kcache->name, name, 16); - kcache->slabsize = (size / PAGE_SIZE) + 1; - kcache->num = (4096 * kcache->slabsize - sizeof(struct ma_slab)) / ((size >= sizeof(struct ma_bufctl)) ? size : sizeof(struct ma_bufctl)); // Calculate the number of buffers in this slab - kcache->objsize = size; + kcache->slabsize = (size + PAGE_SIZE - 1) / PAGE_SIZE; + + if(size >= 512){ + kcache->num = (PAGE_SIZE * kcache->slabsize) / size; // Calculate the number of buffers in this slab + }else{ + kcache->num = (PAGE_SIZE * kcache->slabsize - sizeof(struct ma_slab)) / ((size >= sizeof(struct ma_bufctl)) ? size : sizeof(struct ma_bufctl)); // Calculate the number of buffers in this slab + } + + kcache->objsize = (size > 16) ? size : sizeof(struct ma_bufctl); + memset(&kcache->lock, 0, sizeof(atomic_flag)); + kcache->constructor = constructor; + kcache->destructor = destructor; + + // Calculate color + kcache->alignment = (align == 0) ? 8 : align; // We default to 8 byte alignment (SDM Volume 1 Chapter 4.1.1) but also change this once we support more than x86 + + if(size >= 512){ + kcache->color = (kcache->slabsize * PAGE_SIZE) % kcache->objsize; // This is going to be the max color we can use + }else { + kcache->color = (PAGE_SIZE - sizeof(struct ma_slab)) % kcache->objsize; // This is going to be the max color we can use + } + + kcache->color_next = 0; // Calculated by doing += align while color_next < color + _ma_alloc_slab(kcache); if(caches != NULL){ @@ -300,43 +242,31 @@ struct ma_cache *ma_cache_create(char *name, size_t size, uint32_t flags, void ( void *ma_cache_alloc(struct ma_cache *kcache, uint32_t flags){ + kprintf("Allocating from: {s}\n", kcache->name); + acquire_spinlock(&kcache->lock); struct ma_slab *slab = NULL; - if(kcache->slabs_free == NULL){ - if(kcache->slabs_partial == NULL){ + if(kcache->slabs_partial == NULL){ + if(kcache->slabs_free == NULL){ _ma_alloc_slab(kcache); - slab = kcache->slabs_free; - }else{ - slab = kcache->slabs_partial; } - }else{ slab = kcache->slabs_free; + }else{ + slab = kcache->slabs_partial; } uint64_t *addr = _ma_slab_get_free_obj(slab); // If there's no free object then allocate new slab if(addr == NULL){ - slab->free = NULL; - - if(kcache->slabs_partial->prev != NULL){ - kcache->slabs_partial = kcache->slabs_partial->prev; - }else{ - kcache->slabs_partial = NULL; + if(kcache->num > 1){ + _ma_move_slab(slab, USED); } - - if(kcache->slabs_used != NULL){ - kcache->slabs_used->next = slab; - slab->prev = kcache->slabs_used; - kcache->slabs_used = slab; - }else{ - kcache->slabs_used = slab; - } - _ma_alloc_slab(kcache); - addr = _ma_slab_get_free_obj(kcache->slabs_free); + slab = kcache->slabs_free; + addr = _ma_slab_get_free_obj(slab); } free_spinlock(&kcache->lock); @@ -345,65 +275,6 @@ void *ma_cache_alloc(struct ma_cache *kcache, uint32_t flags){ } -void cache_info(struct ma_cache *cache){ - kprintf("name: {s}\n", cache->name); - kprintf("objsize: {d}\n", cache->objsize); - kprintf("num: {d}\n", cache->num); - kprintf("slabsize: {d}\n", cache->slabsize); - - int slabsfreecnt = 0; - if(cache->slabs_free == NULL){ - kprintf("slabsfree: 0\n"); - }else{ - if(cache->slabs_free->prev == NULL){ - kprintf("slabsfree: 1\n"); - }else{ - struct ma_slab *slab = cache->slabs_free; - - while(slab->prev != NULL){ - slab = slab->prev; - slabsfreecnt++; - } - - kprintf("slabsfree : {d}\n", slabsfreecnt); - } - } - - int slabspartcnt = 0; - if(cache->slabs_partial == NULL){ - kprintf("slabspartial: 0\n"); - }else{ - if(cache->slabs_partial->prev == NULL){ - kprintf("slabspartial: 1\n"); - }else{ - struct ma_slab *slab = cache->slabs_partial; - while(slab->prev != NULL){ - slab = slab->prev; - slabspartcnt++; - } - kprintf("slabspartial: {d}\n", slabspartcnt+1); - } - } - - int slabsfullcnt = 0; - if(cache->slabs_used == NULL){ - kprintf("slabsused: 0\n"); - }else{ - if(cache->slabs_used->prev == NULL){ - kprintf("slabsused: 1\n"); - }else{ - struct ma_slab *slab = cache->slabs_used; - while(slab->prev != NULL){ - slab = slab->prev; - slabsfullcnt++; - } - - - kprintf("slabsused : {d}\n", slabsfullcnt); - } - } -} - struct ma_bufctl *addr_to_bufctl(void *object){ struct ma_slab *slab = get_page(object)->slab; @@ -422,12 +293,7 @@ struct ma_bufctl *addr_to_bufctl(void *object){ } for(size_t i = 0; i < slab->cache->num; i++){ - if((bufs + i)->startaddr != 0){ - kprintf("addr_to_bufctl: we're looking at 0x{x}\n", (bufs + i)->startaddr); - } - if((bufs + i)->startaddr == object){ - //kprintf("addr_to_bufctl: we're looking at 0x{x}\n", (bufs + i)->startaddr); return (bufs + i); } } @@ -436,7 +302,7 @@ struct ma_bufctl *addr_to_bufctl(void *object){ } kstatus ma_cache_dealloc(void *object){ - + struct ma_slab *slab = get_page(object)->slab; if(slab == NULL){ @@ -444,7 +310,7 @@ kstatus ma_cache_dealloc(void *object){ return KERNEL_STATUS_ERROR; } - acquire_spinlock(&slab->lock); + acquire_spinlock(&slab->cache->lock); struct ma_bufctl *buf = addr_to_bufctl(object); @@ -464,7 +330,7 @@ kstatus ma_cache_dealloc(void *object){ _ma_move_slab(slab, FREE); } - free_spinlock(&slab->lock); + free_spinlock(&slab->cache->lock); return KERNEL_STATUS_SUCCESS; @@ -472,6 +338,6 @@ kstatus ma_cache_dealloc(void *object){ extern struct ma_cache *thread_cache; extern struct ma_cache *mutex_cache; void create_base_caches(){ - thread_cache = ma_cache_create("thread", sizeof(struct thread), 0, NULL, NULL); - mutex_cache = ma_cache_create("mutex", sizeof(struct mutex), 0, NULL, NULL); + thread_cache = ma_cache_create("thread", sizeof(struct thread), 0, 0, NULL, NULL); + mutex_cache = ma_cache_create("mutex", sizeof(struct mutex), 0, 0, NULL, NULL); } diff --git a/src/mm/vmm.c b/src/mm/vmm.c index 4a3ab2b..ee04d80 100644 --- a/src/mm/vmm.c +++ b/src/mm/vmm.c @@ -339,7 +339,7 @@ void *va_alloc_contigious_pages(size_t pages){ } -/* Maps pages from phys_addr to phys_addr+size into the kernels address space */ +/* Maps pages from phys_addr to phys_addr+size into the kernels address space (phys_addr + hhdmoffset) */ void kmap_pages(void *phys_addr, uint64_t size, uint64_t flags){ for(uint64_t i = 0; i < size; i++){ vmm_map_page(kernel_page_map, (uint64_t)phys_addr + get_kinfo()->hhdmoffset + (i * PAGE_SIZE), (uint64_t)phys_addr + (i * PAGE_SIZE), PTE_BIT_PRESENT | flags); diff --git a/src/scheduler/sched.c b/src/scheduler/sched.c index e64de21..9aea7ee 100644 --- a/src/scheduler/sched.c +++ b/src/scheduler/sched.c @@ -161,21 +161,23 @@ kstatus spawn_thread(struct thread *thread){ struct thread *prev = cpu->current_process; - if(prev == NULL){ - if(cpu->head == NULL){ - cpu->current_process = idle; - goto end; - }else{ - cpu->current_process = cpu->head; - cpu->head = cpu->head->next; - } - }else{ - if(prev->state == ZOMBIE){ + + if (prev != NULL) { + if (prev->state == ZOMBIE) { ma_cache_dealloc(prev); - }else{ + }else if(prev->state == RUNNING){ prev->state = READY; + cpu->current_process = prev->next; + goto end; } } + + if(cpu->head != NULL){ + cpu->current_process = cpu->head; + cpu->head = cpu->head->next; + } else { + cpu->current_process = idle; + } end: @@ -191,7 +193,7 @@ void scheduler_init(){ cpu_state *cpu = get_current_cpu_state(); - if(cpu->current_process != NULL){ + if(UNLIKELY(cpu->current_process != NULL)){ kprintf("scheduler on CPU {d} already initialized!\n", cpu->id); return; }