kernel: spinlocks

This commit is contained in:
Matheus
2023-04-23 17:12:05 -03:00
parent f16091656a
commit 0394165361
8 changed files with 59 additions and 30 deletions
+2 -1
View File
@@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <spinlock.h>
typedef struct slab_t { typedef struct slab_t {
struct slab_t *next; struct slab_t *next;
@@ -13,7 +14,7 @@ typedef struct slab_t {
} slab_t; } slab_t;
typedef struct scache_t { typedef struct scache_t {
// TODO lock spinlock_t lock;
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;
+2
View File
@@ -3,6 +3,7 @@
#include <time.h> #include <time.h>
#include <arch/context.h> #include <arch/context.h>
#include <spinlock.h>
typedef struct timerentry_t { typedef struct timerentry_t {
struct timerentry_t *next; struct timerentry_t *next;
@@ -12,6 +13,7 @@ typedef struct timerentry_t {
} timerentry_t; } timerentry_t;
typedef struct { typedef struct {
spinlock_t lock;
time_t ticksperus; time_t ticksperus;
time_t tickcurrent; time_t tickcurrent;
void (*arm)(time_t); void (*arm)(time_t);
+3 -1
View File
@@ -2,6 +2,7 @@
#define _VMM_H #define _VMM_H
#include <arch/mmu.h> #include <arch/mmu.h>
#include <spinlock.h>
#define VMM_FLAGS_PAGESIZE 1 #define VMM_FLAGS_PAGESIZE 1
#define VMM_FLAGS_ALLOCATE 2 #define VMM_FLAGS_ALLOCATE 2
@@ -29,7 +30,7 @@ typedef struct vmmrange_t{
} vmmrange_t; } vmmrange_t;
typedef struct { typedef struct {
// TODO lock spinlock_t lock;
struct vmmcache_t *next; struct vmmcache_t *next;
size_t freecount; size_t freecount;
uintmax_t firstfree; uintmax_t firstfree;
@@ -43,6 +44,7 @@ typedef struct vmmcache_t {
} vmmcache_t; } vmmcache_t;
typedef struct { typedef struct {
spinlock_t lock;
vmmrange_t *ranges; vmmrange_t *ranges;
void *start; void *start;
void *end; void *end;
+22
View File
@@ -0,0 +1,22 @@
#ifndef _SPINLOCK_H
#define _SPINLOCK_H
#include <stdbool.h>
typedef int spinlock_t;
#define SPINLOCK_INIT(x) x = 0;
static inline void spinlock_acquire(spinlock_t *lock){
while(!__sync_bool_compare_and_swap(lock, 0, 1)) asm("pause");
}
static inline bool spinlock_try(spinlock_t *lock){
return __sync_bool_compare_and_swap(lock, 0, 1);
}
static inline void spinlock_release(spinlock_t *lock){
*lock = 0;
}
#endif
+9 -5
View File
@@ -3,12 +3,14 @@
#include <logging.h> #include <logging.h>
#include <string.h> #include <string.h>
#include <arch/mmu.h> #include <arch/mmu.h>
#include <spinlock.h>
uintptr_t hhdmbase; uintptr_t hhdmbase;
static size_t memorysize; static size_t memorysize;
static size_t physicalpagecount; static size_t physicalpagecount;
typedef struct { typedef struct {
spinlock_t lock;
uintmax_t base; uintmax_t base;
uintmax_t top; uintmax_t top;
uintmax_t searchstart; uintmax_t searchstart;
@@ -75,11 +77,12 @@ static inline void initsection(int section, uintmax_t base, uintmax_t top) {
.top = top, .top = top,
.searchstart = base .searchstart = base
}; };
SPINLOCK_INIT(bmsections[section].lock);
} }
void *pmm_alloc(size_t size, int section) { void *pmm_alloc(size_t size, int section) {
for (int i = section; i >= 0; --i) { for (int i = section; i >= 0; --i) {
// TODO lock section spinlock_acquire(&bmsections[i].lock);
uintmax_t page = getfreearea(&bmsections[i], size); uintmax_t page = getfreearea(&bmsections[i], size);
if (page) { if (page) {
@@ -88,10 +91,11 @@ void *pmm_alloc(size_t size, int section) {
for (size_t j = 0; j < size; ++j) for (size_t j = 0; j < size; ++j)
bmset((void *)((page + j) * PAGE_SIZE), 0); bmset((void *)((page + j) * PAGE_SIZE), 0);
// TODO unlock
spinlock_release(&bmsections[i].lock);
return (void *)(page * PAGE_SIZE); return (void *)(page * PAGE_SIZE);
} }
// TODO unlock section spinlock_release(&bmsections[i].lock);
} }
return NULL; return NULL;
} }
@@ -101,7 +105,7 @@ void pmm_free(void *addr, size_t size) {
for (int i = 0; i < PMM_SECTION_COUNT; ++i) { for (int i = 0; i < PMM_SECTION_COUNT; ++i) {
if (page >= bmsections[i].base && page < bmsections[i].top) { if (page >= bmsections[i].base && page < bmsections[i].top) {
// TODO lock spinlock_acquire(&bmsections[i].lock);
if ((uintptr_t)addr / PAGE_SIZE < bmsections[i].searchstart) if ((uintptr_t)addr / PAGE_SIZE < bmsections[i].searchstart)
bmsections[i].searchstart = (uintptr_t)addr / PAGE_SIZE; bmsections[i].searchstart = (uintptr_t)addr / PAGE_SIZE;
@@ -109,7 +113,7 @@ void pmm_free(void *addr, size_t size) {
for (uintmax_t j = 0; j < size; ++j) for (uintmax_t j = 0; j < size; ++j)
bmset((void *)((page + j) * PAGE_SIZE), 1); bmset((void *)((page + j) * PAGE_SIZE), 1);
// TODO unlock spinlock_release(&bmsections[i].lock);
return; return;
} }
} }
+6 -8
View File
@@ -125,7 +125,7 @@ static slab_t *returnobject(scache_t *cache, void *obj) {
} }
void *slab_allocate(scache_t *cache) { void *slab_allocate(scache_t *cache) {
// TODO lock spinlock_acquire(&cache->lock);
slab_t *slab = NULL; slab_t *slab = NULL;
if (cache->partial != NULL) if (cache->partial != NULL)
slab = cache->partial; slab = cache->partial;
@@ -170,12 +170,12 @@ void *slab_allocate(scache_t *cache) {
} }
cleanup: cleanup:
// TODO unlock spinlock_release(&cache->lock);
return ret; return ret;
} }
void slab_free(scache_t *cache, void *addr) { void slab_free(scache_t *cache, void *addr) {
// TODO lock spinlock_acquire(&cache->lock);
slab_t *slab = returnobject(cache, addr); slab_t *slab = returnobject(cache, addr);
__assert(slab); __assert(slab);
@@ -205,8 +205,7 @@ void slab_free(scache_t *cache, void *addr) {
slab->prev = NULL; slab->prev = NULL;
cache->partial = slab; cache->partial = slab;
} }
spinlock_release(&cache->lock);
// TODO unlock
} }
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 *)) {
@@ -227,6 +226,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);
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);
@@ -256,13 +256,11 @@ static size_t purge(scache_t *cache, size_t maxcount){
} }
void slab_freecache(scache_t *cache) { void slab_freecache(scache_t *cache) {
// TODO lock spinlock_acquire(&cache->lock);
__assert(cache->partial == NULL); __assert(cache->partial == NULL);
__assert(cache->full == NULL); __assert(cache->full == NULL);
purge(cache, (size_t)-1); purge(cache, (size_t)-1);
slab_free(&selfcache, cache); slab_free(&selfcache, cache);
// TODO unlock
} }
+10 -11
View File
@@ -9,7 +9,6 @@
#define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size) #define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size)
static vmmcache_t *newcache() { static vmmcache_t *newcache() {
// TODO initialize lock
vmmcache_t *ptr = pmm_alloc(1, PMM_SECTION_DEFAULT); vmmcache_t *ptr = pmm_alloc(1, PMM_SECTION_DEFAULT);
if (ptr == NULL) if (ptr == NULL)
return NULL; return NULL;
@@ -17,6 +16,7 @@ static vmmcache_t *newcache() {
ptr->header.freecount = VMM_RANGES_PER_CACHE; ptr->header.freecount = VMM_RANGES_PER_CACHE;
ptr->header.firstfree = 0; ptr->header.firstfree = 0;
ptr->header.next = NULL; ptr->header.next = NULL;
SPINLOCK_INIT(ptr->header.lock);
for (uintmax_t i = 0; i < VMM_RANGES_PER_CACHE; ++i) { for (uintmax_t i = 0; i < VMM_RANGES_PER_CACHE; ++i) {
ptr->ranges[i].size = 0; ptr->ranges[i].size = 0;
@@ -42,23 +42,22 @@ static vmmrange_t *allocrange() {
vmmcache_t *cache = cachelist; vmmcache_t *cache = cachelist;
vmmrange_t *range = NULL; vmmrange_t *range = NULL;
while (cache) { while (cache) {
// TODO lock spinlock_acquire(&cache->header.lock);
if (cache->header.freecount > 0) { if (cache->header.freecount > 0) {
--cache->header.freecount; --cache->header.freecount;
uintmax_t r = getentrynumber(cache); uintmax_t r = getentrynumber(cache);
cache->header.firstfree = r + 1; cache->header.firstfree = r + 1;
range = &cache->ranges[r]; range = &cache->ranges[r];
range->size = -1; // set as allocated temporarily range->size = -1; // set as allocated temporarily
spinlock_release(&cache->header.lock);
break; break;
} else if (cache->header.next == NULL) } else if (cache->header.next == NULL)
cache->header.next = newcache(); cache->header.next = newcache();
cache = cache->header.next; cache = cache->header.next;
// TODO unlock spinlock_release(&cache->header.lock);
} }
// TODO unlock cache
return range; return range;
} }
@@ -233,7 +232,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
if (space == NULL || (space == &kernelspace && user)) if (space == NULL || (space == &kernelspace && user))
return false; return false;
// TODO lock spinlock_acquire(&space->lock);
vmmrange_t *range = getrange(space, addr); vmmrange_t *range = getrange(space, addr);
bool status = false; bool status = false;
@@ -267,7 +266,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
status = true; status = true;
cleanup: cleanup:
// TODO unlock spinlock_release(&space->lock);
return status; return status;
} }
@@ -288,7 +287,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
if (space == NULL) if (space == NULL)
return NULL; return NULL;
// TODO lock space spinlock_acquire(&space->lock);
void *start = getfreerange(space, addr, size); void *start = getfreerange(space, addr, size);
void *retaddr = NULL; void *retaddr = NULL;
@@ -345,7 +344,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
if (start == NULL && range) { if (start == NULL && range) {
// TODO free range // TODO free range
} }
// TODO unlock spinlock_release(&space->lock);
return retaddr; return retaddr;
} }
@@ -363,11 +362,11 @@ void vmm_unmap(void *addr, size_t size, int flags) {
if (space == NULL) if (space == NULL)
return; return;
// TODO lock space spinlock_acquire(&space->lock);
unmap(space, addr, size); unmap(space, addr, size);
// TODO unlock space spinlock_release(&space->lock);
} }
vmmcontext_t *vmm_newcontext() { vmmcontext_t *vmm_newcontext() {
+5 -4
View File
@@ -4,7 +4,7 @@
#include <kernel/interrupt.h> #include <kernel/interrupt.h>
void timer_isr(timer_t *timer, context_t *context) { void timer_isr(timer_t *timer, context_t *context) {
// TODO lock spinlock_acquire(&timer->lock);
__assert(timer->queue); __assert(timer->queue);
timer->tickcurrent = timer->queue->absolutetick; timer->tickcurrent = timer->queue->absolutetick;
timerentry_t *oldentry = timer->queue; timerentry_t *oldentry = timer->queue;
@@ -16,13 +16,13 @@ void timer_isr(timer_t *timer, context_t *context) {
timer->arm(timer->queue->absolutetick - timer->tickcurrent); timer->arm(timer->queue->absolutetick - timer->tickcurrent);
} }
// TODO unlock spinlock_release(&timer->lock);
oldentry->func(oldentry->private, context); oldentry->func(oldentry->private, context);
} }
void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) { void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) {
long oldipl = interrupt_setipl(IPL_TIMER); long oldipl = interrupt_setipl(IPL_TIMER);
// TODO lock spinlock_acquire(&timer->lock);
timer->tickcurrent += timer->stop(timer); timer->tickcurrent += timer->stop(timer);
@@ -56,7 +56,7 @@ void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) {
__assert(timer->queue->absolutetick > timer->tickcurrent); __assert(timer->queue->absolutetick > timer->tickcurrent);
timer->arm(timer->queue->absolutetick - timer->tickcurrent); timer->arm(timer->queue->absolutetick - timer->tickcurrent);
// TODO unlock spinlock_release(&timer->lock);
interrupt_setipl(oldipl); interrupt_setipl(oldipl);
} }
@@ -68,6 +68,7 @@ timer_t *timer_new(time_t ticksperus, void (*arm)(time_t), time_t (*stop)()) {
timer->ticksperus = ticksperus; timer->ticksperus = ticksperus;
timer->arm = arm; timer->arm = arm;
timer->stop = stop; timer->stop = stop;
SPINLOCK_INIT(timer->lock);
return timer; return timer;
} }