mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
kernel: spinlocks
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <time.h>
|
||||
#include <arch/context.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
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);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _VMM_H
|
||||
|
||||
#include <arch/mmu.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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
@@ -3,12 +3,14 @@
|
||||
#include <logging.h>
|
||||
#include <string.h>
|
||||
#include <arch/mmu.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+10
-11
@@ -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() {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <kernel/interrupt.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user