pmm and slab: switch from spinlocks to mutexes

This commit is contained in:
Matheus
2024-05-08 21:07:42 -03:00
parent ce3fad266b
commit 6087a20d81
3 changed files with 23 additions and 17 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <spinlock.h> #include <mutex.h>
typedef struct slab_t { typedef struct slab_t {
struct slab_t *next; struct slab_t *next;
@@ -14,7 +14,7 @@ typedef struct slab_t {
} slab_t; } slab_t;
typedef struct scache_t { typedef struct scache_t {
spinlock_t lock; mutex_t mutex;
void (*ctor)(struct scache_t *cache, void *obj); void (*ctor)(struct scache_t *cache, void *obj);
void (*dtor)(struct scache_t *cache, void *obj); void (*dtor)(struct scache_t *cache, void *obj);
slab_t *full; slab_t *full;
+9 -9
View File
@@ -3,7 +3,7 @@
#include <logging.h> #include <logging.h>
#include <string.h> #include <string.h>
#include <arch/mmu.h> #include <arch/mmu.h>
#include <spinlock.h> #include <mutex.h>
#include <util.h> #include <util.h>
uintptr_t hhdmbase; uintptr_t hhdmbase;
@@ -11,7 +11,7 @@ static size_t memorysize;
static size_t pagecount; static size_t pagecount;
size_t freepagecount; size_t freepagecount;
static spinlock_t freelistlock; static mutex_t freelistmutex;
static page_t *freelists[PMM_SECTION_COUNT]; static page_t *freelists[PMM_SECTION_COUNT];
static page_t *standbylists[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); uintmax_t newrefcount = __atomic_sub_fetch(&page->refcount, 1, __ATOMIC_SEQ_CST);
if (newrefcount == 0) { if (newrefcount == 0) {
spinlock_acquire(&freelistlock); MUTEX_ACQUIRE(&freelistmutex, false);
insertinfreelist(page); insertinfreelist(page);
if (page->backing == NULL) if (page->backing == NULL)
page->flags |= PAGE_FLAGS_FREE; 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) { void *pmm_allocpage(int section) {
spinlock_acquire(&freelistlock); MUTEX_ACQUIRE(&freelistmutex, false);
page_t *page = NULL; page_t *page = NULL;
for (int i = section; i >= 0; --i) { 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 // TODO get page from standby list and call to remove from cache
spinlock_release(&freelistlock); MUTEX_RELEASE(&freelistmutex);
void *address = NULL; void *address = NULL;
if (page) { if (page) {
address = (void *)(PAGE_GETID(page) * PAGE_SIZE); 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) { void *pmm_alloc(size_t size, int section) {
@@ -213,7 +213,7 @@ void *pmm_alloc(size_t size, int section) {
if (size == 1) if (size == 1)
return pmm_allocpage(section); return pmm_allocpage(section);
spinlock_acquire(&freelistlock); MUTEX_ACQUIRE(&freelistmutex, false);
uintmax_t page = 0; uintmax_t page = 0;
size_t found = 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; return addr;
} }
+12 -6
View File
@@ -15,6 +15,7 @@
#define SLAB_DEBUG 0 #define SLAB_DEBUG 0
// the cache responsible for allocating all others // the cache responsible for allocating all others
static bool selfcacheinit = false;
static scache_t selfcache = { static scache_t selfcache = {
.size = sizeof(scache_t), .size = sizeof(scache_t),
.alignment = 8, .alignment = 8,
@@ -142,7 +143,7 @@ static slab_t *returnobject(scache_t *cache, void *obj) {
} }
void *slab_allocate(scache_t *cache) { void *slab_allocate(scache_t *cache) {
spinlock_acquire(&cache->lock); MUTEX_ACQUIRE(&cache->mutex, false);
slab_t *slab = NULL; slab_t *slab = NULL;
if (cache->partial != NULL) if (cache->partial != NULL)
slab = cache->partial; slab = cache->partial;
@@ -186,12 +187,12 @@ void *slab_allocate(scache_t *cache) {
} }
cleanup: cleanup:
spinlock_release(&cache->lock); MUTEX_RELEASE(&cache->mutex);
return ret; return ret;
} }
void slab_free(scache_t *cache, void *addr) { void slab_free(scache_t *cache, void *addr) {
spinlock_acquire(&cache->lock); MUTEX_ACQUIRE(&cache->mutex, false);
slab_t *slab = returnobject(cache, addr); slab_t *slab = returnobject(cache, addr);
__assert(slab); __assert(slab);
@@ -227,13 +228,18 @@ void slab_free(scache_t *cache, void *addr) {
slab->next->prev = slab; slab->next->prev = slab;
cache->partial = 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 *)) { scache_t *slab_newcache(size_t size, size_t alignment, void (*ctor)(scache_t *, void *), void (*dtor)(scache_t *, void *)) {
if (alignment == 0) if (alignment == 0)
alignment = 8; alignment = 8;
if (selfcacheinit == false) {
selfcacheinit = true;
MUTEX_INIT(&selfcache.mutex);
}
scache_t *cache = slab_allocate(&selfcache); scache_t *cache = slab_allocate(&selfcache);
if (cache == NULL) if (cache == NULL)
return 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->full = NULL;
cache->empty = NULL; cache->empty = NULL;
cache->partial = 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); 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) { void slab_freecache(scache_t *cache) {
spinlock_acquire(&cache->lock); MUTEX_ACQUIRE(&cache->mutex, false);
__assert(cache->partial == NULL); __assert(cache->partial == NULL);
__assert(cache->full == NULL); __assert(cache->full == NULL);