diff --git a/kernel-src/include/kernel/slab.h b/kernel-src/include/kernel/slab.h index 744cac62..f8997a8a 100644 --- a/kernel-src/include/kernel/slab.h +++ b/kernel-src/include/kernel/slab.h @@ -3,7 +3,7 @@ #include #include -#include +#include typedef struct slab_t { struct slab_t *next; @@ -14,7 +14,7 @@ typedef struct slab_t { } slab_t; typedef struct scache_t { - spinlock_t lock; + mutex_t mutex; void (*ctor)(struct scache_t *cache, void *obj); void (*dtor)(struct scache_t *cache, void *obj); slab_t *full; diff --git a/kernel-src/mm/pmm.c b/kernel-src/mm/pmm.c index 9634d85f..b75a21d0 100644 --- a/kernel-src/mm/pmm.c +++ b/kernel-src/mm/pmm.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include uintptr_t hhdmbase; @@ -11,7 +11,7 @@ static size_t memorysize; static size_t pagecount; size_t freepagecount; -static spinlock_t freelistlock; +static mutex_t freelistmutex; static page_t *freelists[PMM_SECTION_COUNT]; static page_t *standbylists[PMM_SECTION_COUNT]; @@ -112,11 +112,11 @@ void pmm_release(void *addr) { uintmax_t newrefcount = __atomic_sub_fetch(&page->refcount, 1, __ATOMIC_SEQ_CST); if (newrefcount == 0) { - spinlock_acquire(&freelistlock); + MUTEX_ACQUIRE(&freelistmutex, false); insertinfreelist(page); if (page->backing == NULL) page->flags |= PAGE_FLAGS_FREE; - spinlock_release(&freelistlock); + MUTEX_RELEASE(&freelistmutex); } } @@ -128,7 +128,7 @@ static void doalloc(page_t *page) { } void *pmm_allocpage(int section) { - spinlock_acquire(&freelistlock); + MUTEX_ACQUIRE(&freelistmutex, false); page_t *page = NULL; for (int i = section; i >= 0; --i) { @@ -141,7 +141,7 @@ void *pmm_allocpage(int section) { // TODO get page from standby list and call to remove from cache - spinlock_release(&freelistlock); + MUTEX_RELEASE(&freelistmutex); void *address = NULL; if (page) { address = (void *)(PAGE_GETID(page) * PAGE_SIZE); @@ -204,7 +204,7 @@ void pmm_init() { } } - SPINLOCK_INIT(freelistlock); + MUTEX_INIT(&freelistmutex); } void *pmm_alloc(size_t size, int section) { @@ -213,7 +213,7 @@ void *pmm_alloc(size_t size, int section) { if (size == 1) return pmm_allocpage(section); - spinlock_acquire(&freelistlock); + MUTEX_ACQUIRE(&freelistmutex, false); uintmax_t page = 0; size_t found = 0; @@ -245,7 +245,7 @@ void *pmm_alloc(size_t size, int section) { } } - spinlock_release(&freelistlock); + MUTEX_RELEASE(&freelistmutex); return addr; } diff --git a/kernel-src/mm/slab.c b/kernel-src/mm/slab.c index 2d8e0170..520111cb 100644 --- a/kernel-src/mm/slab.c +++ b/kernel-src/mm/slab.c @@ -15,6 +15,7 @@ #define SLAB_DEBUG 0 // the cache responsible for allocating all others +static bool selfcacheinit = false; static scache_t selfcache = { .size = sizeof(scache_t), .alignment = 8, @@ -142,7 +143,7 @@ static slab_t *returnobject(scache_t *cache, void *obj) { } void *slab_allocate(scache_t *cache) { - spinlock_acquire(&cache->lock); + MUTEX_ACQUIRE(&cache->mutex, false); slab_t *slab = NULL; if (cache->partial != NULL) slab = cache->partial; @@ -186,12 +187,12 @@ void *slab_allocate(scache_t *cache) { } cleanup: - spinlock_release(&cache->lock); + MUTEX_RELEASE(&cache->mutex); return ret; } void slab_free(scache_t *cache, void *addr) { - spinlock_acquire(&cache->lock); + MUTEX_ACQUIRE(&cache->mutex, false); slab_t *slab = returnobject(cache, addr); __assert(slab); @@ -227,13 +228,18 @@ void slab_free(scache_t *cache, void *addr) { slab->next->prev = slab; cache->partial = slab; } - spinlock_release(&cache->lock); + MUTEX_RELEASE(&cache->mutex); } scache_t *slab_newcache(size_t size, size_t alignment, void (*ctor)(scache_t *, void *), void (*dtor)(scache_t *, void *)) { if (alignment == 0) alignment = 8; + if (selfcacheinit == false) { + selfcacheinit = true; + MUTEX_INIT(&selfcache.mutex); + } + scache_t *cache = slab_allocate(&selfcache); if (cache == NULL) return NULL; @@ -248,7 +254,7 @@ scache_t *slab_newcache(size_t size, size_t alignment, void (*ctor)(scache_t *, cache->full = NULL; cache->empty = NULL; cache->partial = NULL; - SPINLOCK_INIT(cache->lock); + MUTEX_INIT(&cache->mutex); printf("slab: new cache: size %lu align %lu truesize %lu objcount %lu\n", cache->size, cache->alignment, cache->truesize, cache->slabobjcount); @@ -278,7 +284,7 @@ static size_t purge(scache_t *cache, size_t maxcount){ } void slab_freecache(scache_t *cache) { - spinlock_acquire(&cache->lock); + MUTEX_ACQUIRE(&cache->mutex, false); __assert(cache->partial == NULL); __assert(cache->full == NULL);