diff --git a/kernel-src/include/kernel/slab.h b/kernel-src/include/kernel/slab.h index b88fb77c..744cac62 100644 --- a/kernel-src/include/kernel/slab.h +++ b/kernel-src/include/kernel/slab.h @@ -3,6 +3,7 @@ #include #include +#include typedef struct slab_t { struct slab_t *next; @@ -13,7 +14,7 @@ typedef struct slab_t { } slab_t; typedef struct scache_t { - // TODO lock + spinlock_t lock; void (*ctor)(struct scache_t *cache, void *obj); void (*dtor)(struct scache_t *cache, void *obj); slab_t *full; diff --git a/kernel-src/include/kernel/timer.h b/kernel-src/include/kernel/timer.h index 59a833b1..e7fdc145 100644 --- a/kernel-src/include/kernel/timer.h +++ b/kernel-src/include/kernel/timer.h @@ -3,6 +3,7 @@ #include #include +#include typedef struct timerentry_t { struct timerentry_t *next; @@ -12,6 +13,7 @@ typedef struct timerentry_t { } timerentry_t; typedef struct { + spinlock_t lock; time_t ticksperus; time_t tickcurrent; void (*arm)(time_t); diff --git a/kernel-src/include/kernel/vmm.h b/kernel-src/include/kernel/vmm.h index 2754d820..f92a7ffd 100644 --- a/kernel-src/include/kernel/vmm.h +++ b/kernel-src/include/kernel/vmm.h @@ -2,6 +2,7 @@ #define _VMM_H #include +#include #define VMM_FLAGS_PAGESIZE 1 #define VMM_FLAGS_ALLOCATE 2 @@ -29,7 +30,7 @@ typedef struct vmmrange_t{ } vmmrange_t; typedef struct { - // TODO lock + spinlock_t lock; struct vmmcache_t *next; size_t freecount; uintmax_t firstfree; @@ -43,6 +44,7 @@ typedef struct vmmcache_t { } vmmcache_t; typedef struct { + spinlock_t lock; vmmrange_t *ranges; void *start; void *end; diff --git a/kernel-src/include/spinlock.h b/kernel-src/include/spinlock.h new file mode 100644 index 00000000..4132d00c --- /dev/null +++ b/kernel-src/include/spinlock.h @@ -0,0 +1,22 @@ +#ifndef _SPINLOCK_H +#define _SPINLOCK_H + +#include + +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 diff --git a/kernel-src/mm/pmm.c b/kernel-src/mm/pmm.c index f89f1fd2..fb69f979 100644 --- a/kernel-src/mm/pmm.c +++ b/kernel-src/mm/pmm.c @@ -3,12 +3,14 @@ #include #include #include +#include uintptr_t hhdmbase; static size_t memorysize; static size_t physicalpagecount; typedef struct { + spinlock_t lock; uintmax_t base; uintmax_t top; uintmax_t searchstart; @@ -75,11 +77,12 @@ static inline void initsection(int section, uintmax_t base, uintmax_t top) { .top = top, .searchstart = base }; + SPINLOCK_INIT(bmsections[section].lock); } void *pmm_alloc(size_t size, int section) { for (int i = section; i >= 0; --i) { - // TODO lock section + spinlock_acquire(&bmsections[i].lock); uintmax_t page = getfreearea(&bmsections[i], size); if (page) { @@ -88,10 +91,11 @@ void *pmm_alloc(size_t size, int section) { for (size_t j = 0; j < size; ++j) bmset((void *)((page + j) * PAGE_SIZE), 0); - // TODO unlock + + spinlock_release(&bmsections[i].lock); return (void *)(page * PAGE_SIZE); } - // TODO unlock section + spinlock_release(&bmsections[i].lock); } return NULL; } @@ -101,7 +105,7 @@ void pmm_free(void *addr, size_t size) { for (int i = 0; i < PMM_SECTION_COUNT; ++i) { 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) 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) bmset((void *)((page + j) * PAGE_SIZE), 1); - // TODO unlock + spinlock_release(&bmsections[i].lock); return; } } diff --git a/kernel-src/mm/slab.c b/kernel-src/mm/slab.c index 6c1e498d..aed42b22 100644 --- a/kernel-src/mm/slab.c +++ b/kernel-src/mm/slab.c @@ -125,7 +125,7 @@ static slab_t *returnobject(scache_t *cache, void *obj) { } void *slab_allocate(scache_t *cache) { - // TODO lock + spinlock_acquire(&cache->lock); slab_t *slab = NULL; if (cache->partial != NULL) slab = cache->partial; @@ -170,12 +170,12 @@ void *slab_allocate(scache_t *cache) { } cleanup: - // TODO unlock + spinlock_release(&cache->lock); return ret; } void slab_free(scache_t *cache, void *addr) { - // TODO lock + spinlock_acquire(&cache->lock); slab_t *slab = returnobject(cache, addr); __assert(slab); @@ -205,8 +205,7 @@ void slab_free(scache_t *cache, void *addr) { slab->prev = NULL; cache->partial = slab; } - - // TODO unlock + spinlock_release(&cache->lock); } 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->empty = 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); @@ -256,13 +256,11 @@ static size_t purge(scache_t *cache, size_t maxcount){ } void slab_freecache(scache_t *cache) { - // TODO lock + spinlock_acquire(&cache->lock); __assert(cache->partial == NULL); __assert(cache->full == NULL); purge(cache, (size_t)-1); slab_free(&selfcache, cache); - - // TODO unlock } diff --git a/kernel-src/mm/vmm.c b/kernel-src/mm/vmm.c index be2aca4f..3cba2c89 100644 --- a/kernel-src/mm/vmm.c +++ b/kernel-src/mm/vmm.c @@ -9,7 +9,6 @@ #define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size) static vmmcache_t *newcache() { - // TODO initialize lock vmmcache_t *ptr = pmm_alloc(1, PMM_SECTION_DEFAULT); if (ptr == NULL) return NULL; @@ -17,6 +16,7 @@ static vmmcache_t *newcache() { ptr->header.freecount = VMM_RANGES_PER_CACHE; ptr->header.firstfree = 0; ptr->header.next = NULL; + SPINLOCK_INIT(ptr->header.lock); for (uintmax_t i = 0; i < VMM_RANGES_PER_CACHE; ++i) { ptr->ranges[i].size = 0; @@ -42,23 +42,22 @@ static vmmrange_t *allocrange() { vmmcache_t *cache = cachelist; vmmrange_t *range = NULL; while (cache) { - // TODO lock + spinlock_acquire(&cache->header.lock); if (cache->header.freecount > 0) { --cache->header.freecount; uintmax_t r = getentrynumber(cache); cache->header.firstfree = r + 1; range = &cache->ranges[r]; range->size = -1; // set as allocated temporarily + spinlock_release(&cache->header.lock); break; } else if (cache->header.next == NULL) cache->header.next = newcache(); cache = cache->header.next; - // TODO unlock + spinlock_release(&cache->header.lock); } - // TODO unlock cache - return range; } @@ -233,7 +232,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) { if (space == NULL || (space == &kernelspace && user)) return false; - // TODO lock + spinlock_acquire(&space->lock); vmmrange_t *range = getrange(space, addr); bool status = false; @@ -267,7 +266,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) { status = true; cleanup: - // TODO unlock + spinlock_release(&space->lock); return status; } @@ -288,7 +287,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags, if (space == NULL) return NULL; - // TODO lock space + spinlock_acquire(&space->lock); void *start = getfreerange(space, addr, size); 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) { // TODO free range } - // TODO unlock + spinlock_release(&space->lock); return retaddr; } @@ -363,11 +362,11 @@ void vmm_unmap(void *addr, size_t size, int flags) { if (space == NULL) return; - // TODO lock space + spinlock_acquire(&space->lock); unmap(space, addr, size); - // TODO unlock space + spinlock_release(&space->lock); } vmmcontext_t *vmm_newcontext() { diff --git a/kernel-src/sys/timer.c b/kernel-src/sys/timer.c index deb7865b..95fa3dd1 100644 --- a/kernel-src/sys/timer.c +++ b/kernel-src/sys/timer.c @@ -4,7 +4,7 @@ #include void timer_isr(timer_t *timer, context_t *context) { - // TODO lock + spinlock_acquire(&timer->lock); __assert(timer->queue); timer->tickcurrent = timer->queue->absolutetick; 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); } - // TODO unlock + spinlock_release(&timer->lock); oldentry->func(oldentry->private, context); } void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) { long oldipl = interrupt_setipl(IPL_TIMER); - // TODO lock + spinlock_acquire(&timer->lock); 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); timer->arm(timer->queue->absolutetick - timer->tickcurrent); - // TODO unlock + spinlock_release(&timer->lock); 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->arm = arm; timer->stop = stop; + SPINLOCK_INIT(timer->lock); return timer; }