mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
pmm and slab: switch from spinlocks to mutexes
This commit is contained in:
@@ -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
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user