Skip to content

Commit

Permalink
Rewrite critical sections / mutexes to C++
Browse files Browse the repository at this point in the history
  • Loading branch information
djphoenix committed May 23, 2019
1 parent 68d07bd commit d1bb756
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 174 deletions.
26 changes: 6 additions & 20 deletions src/kernlib/display.cpp
Expand Up @@ -42,16 +42,12 @@ class ConsoleDisplay: public Display {
clean();
}
void write(const char *str) {
uint64_t t = EnterCritical();
mutex.lock();
Mutex::CriticalLock lock(mutex);
while (*str != 0) putc(*(str++));
mutex.release();
LeaveCritical(t);
}
void clean() {
mutex.lock();
Mutex::Lock lock(mutex);
Memory::fill(base, 0, size);
mutex.release();
}
};

Expand Down Expand Up @@ -132,16 +128,12 @@ class FramebufferDisplay: public Display {
clean();
}
void write(const char *str) {
uint64_t t = EnterCritical();
mutex.lock();
Mutex::CriticalLock lock(mutex);
while (*str != 0) putc(*(str++));
mutex.release();
LeaveCritical(t);
}
void clean() {
mutex.lock();
Mutex::Lock lock(mutex);
Memory::zero(framebuffer, bufferSize());
mutex.release();
}
};

Expand All @@ -164,12 +156,9 @@ class SerialDisplay: public Display {
Port<port + 3>::out<uint8_t>(0x03);
}
void write(const char *str) {
uint64_t t = EnterCritical();
mutex.lock();
Mutex::CriticalLock lock(mutex);
char c;
while ((c = *str++) != 0) Port<port>::out(uint8_t(c));
mutex.release();
LeaveCritical(t);
}
void clean() {}
};
Expand Down Expand Up @@ -221,11 +210,8 @@ void Display::setup() {

Display *Display::getInstance() {
if (instance) return instance;
uint64_t t = EnterCritical();
instanceMutex.lock();
Mutex::CriticalLock lock(instanceMutex);
if (!instance) setup();
instanceMutex.release();
LeaveCritical(t);
return instance;
}

Expand Down
1 change: 0 additions & 1 deletion src/kernlib/include/kernlib.hpp
Expand Up @@ -3,7 +3,6 @@

#pragma once

#include "kernlib/cpu.hpp"
#include "kernlib/display.hpp"
#include "kernlib/mem.hpp"
#include "kernlib/mutex.hpp"
Expand Down
23 changes: 0 additions & 23 deletions src/kernlib/include/kernlib/cpu.hpp

This file was deleted.

36 changes: 36 additions & 0 deletions src/kernlib/include/kernlib/mutex.hpp
Expand Up @@ -4,9 +4,29 @@
#pragma once
#include "std.hpp"

class CriticalSection {
private:
uint64_t flags;

public:
inline static uint64_t __attribute__((always_inline)) enter() {
uint64_t flags;
asm volatile("pushfq; cli; pop %q0":"=r"(flags));
return flags;
}

inline static void leave(uint64_t flags) {
asm volatile("push %q0; popfq"::"r"(flags));
}

CriticalSection() : flags(enter()) {}
~CriticalSection() { leave(flags); }
};

class Mutex {
private:
bool state;

public:
Mutex(): state(0) {}
inline void lock() {
Expand All @@ -28,4 +48,20 @@ class Mutex {
inline void release() {
asm volatile("movw $0, %0"::"m"(state));
}
class Lock {
private:
Mutex *mutex;
public:
explicit Lock(Mutex *mutex) : mutex(mutex) { mutex->lock(); }
explicit Lock(Mutex &mutex) : Lock(&mutex) {}
~Lock() { mutex->release(); }
};
class CriticalLock: public CriticalSection {
private:
Mutex *mutex;
public:
explicit CriticalLock(Mutex *mutex) : mutex(mutex) { mutex->lock(); }
explicit CriticalLock(Mutex &mutex) : CriticalLock(&mutex) {}
~CriticalLock() { mutex->release(); }
};
};
6 changes: 6 additions & 0 deletions src/kernlib/include/kernlib/std.hpp
Expand Up @@ -25,6 +25,12 @@ namespace klib {
int strncmp(const char*, const char*, int) PURE;
int strcmp(const char*, const char*) PURE;

inline static uint64_t rdtsc() {
uint32_t eax, edx;
asm volatile("rdtsc":"=a"(eax), "=d"(edx));
return ((uint64_t(edx) << 32) | eax);
}

inline static uintptr_t __align(uintptr_t base, size_t align) {
if (base % align == 0)
return base;
Expand Down
8 changes: 2 additions & 6 deletions src/platform/acpi.cpp
Expand Up @@ -12,12 +12,8 @@ ACPI* ACPI::controller = nullptr;

ACPI* ACPI::getController() {
if (controller) return controller;
uint64_t t = EnterCritical();
controllerMutex.lock();
if (!controller)
controller = new ACPI();
controllerMutex.release();
LeaveCritical(t);
Mutex::CriticalLock lock(controllerMutex);
if (!controller) controller = new ACPI();
return controller;
}

Expand Down
53 changes: 23 additions & 30 deletions src/platform/heap.cpp
Expand Up @@ -28,12 +28,10 @@ Mutex Heap::heap_mutex;
void* Heap::alloc(size_t size, size_t align) {
if (size == 0)
return nullptr;
heap_mutex.lock();
Mutex::Lock lock(heap_mutex);

if (!heap_pages)
heap_pages = reinterpret_cast<HeapPage*>(Pagetable::alloc());
if (!allocs)
allocs = reinterpret_cast<AllocTable*>(Pagetable::alloc());
if (!heap_pages) heap_pages = reinterpret_cast<HeapPage*>(Pagetable::alloc());
if (!allocs) allocs = reinterpret_cast<AllocTable*>(Pagetable::alloc());

uintptr_t ptr = 0, ptr_top;

Expand Down Expand Up @@ -123,59 +121,54 @@ void* Heap::alloc(size_t size, size_t align) {
table = table->next;
}
done:
heap_mutex.release();

void *a = reinterpret_cast<void*>(ptr);
Memory::zero(a, size);

return a;
}
void Heap::free(void* addr) {
if (addr == nullptr)
return;
heap_mutex.lock();
if (addr == nullptr) return;
Mutex::Lock lock(heap_mutex);
AllocTable *t = allocs;
while (1) {
for (int i = 0; i < 255; i++) {
if (t->allocs[i].addr == addr) {
t->allocs[i].addr = nullptr;
t->allocs[i].size = 0;
goto end;
return;
}
}
if (t->next == nullptr)
goto end;
if (t->next == nullptr) return;
t = t->next;
}
end: heap_mutex.release();
}
void *Heap::realloc(void *addr, size_t size, size_t align) {
if (size == 0) {
free(addr);
return nullptr;
}
if (addr == nullptr)
return alloc(size, align);
heap_mutex.lock();
AllocTable *t = allocs;
if (addr == nullptr) return alloc(size, align);
size_t oldsize = 0;
while (t != nullptr) {
for (int i = 0; i < 255; i++) {
if (t->allocs[i].addr == addr) {
oldsize = t->allocs[i].size;
if (oldsize >= size) {
t->allocs[i].size = size;
heap_mutex.release();
return addr;
{
Mutex::Lock lock(heap_mutex);
AllocTable *t = allocs;
while (t != nullptr) {
for (int i = 0; i < 255; i++) {
if (t->allocs[i].addr == addr) {
oldsize = t->allocs[i].size;
if (oldsize >= size) {
t->allocs[i].size = size;
return addr;
}
break;
}
break;
}
if (oldsize != 0)
break;
t = t->next;
}
if (oldsize != 0)
break;
t = t->next;
}
heap_mutex.release();
if (oldsize == 0)
return nullptr;
void *newptr = alloc(size, align);
Expand Down
19 changes: 9 additions & 10 deletions src/platform/interrupts.cpp
Expand Up @@ -223,8 +223,9 @@ void Interrupts::print(uint8_t num, CallbackRegs *regs, uint32_t code, const Pro

uint64_t __attribute__((sysv_abi)) Interrupts::handle(
unsigned char intr, uint64_t stack, uint64_t *pagetable) {
fault.lock();
fault.release();
{
Mutex::Lock lock(fault);
}
uint64_t *rsp = reinterpret_cast<uint64_t*>(stack);
bool has_code = (intr < 0x20) && FAULTS[intr].has_error_code;
uint32_t error_code = 0;
Expand Down Expand Up @@ -252,10 +253,11 @@ uint64_t __attribute__((sysv_abi)) Interrupts::handle(
size_t idx = 0;
Callback *cb;
for (;;) {
callback_locks[intr].lock();
cb = (callbacks[intr].getCount() > idx) ? callbacks[intr][idx] : nullptr;
idx++;
callback_locks[intr].release();
{
Mutex::Lock lock(callback_locks[intr]);
cb = (callbacks[intr].getCount() > idx) ? callbacks[intr][idx] : nullptr;
idx++;
}
if (cb == nullptr) break;
handled = cb(intr, error_code, &cb_regs);
if (handled) break;
Expand Down Expand Up @@ -402,9 +404,6 @@ uint16_t Interrupts::getIRQmask() {
}

void Interrupts::addCallback(uint8_t intr, Callback* cb) {
uint64_t t = EnterCritical();
callback_locks[intr].lock();
Mutex::CriticalLock lock(callback_locks[intr]);
callbacks[intr].add(cb);
callback_locks[intr].release();
LeaveCritical(t);
}
21 changes: 5 additions & 16 deletions src/platform/pagetable.cpp
Expand Up @@ -412,12 +412,8 @@ void* Pagetable::_map(const void* mem) {
}

void* Pagetable::map(const void* mem) {
uint64_t t = EnterCritical();
page_mutex.lock();
void *addr = _map(mem);
page_mutex.release();
LeaveCritical(t);
return addr;
Mutex::CriticalLock lock(page_mutex);
return _map(mem);
}

void* Pagetable::_alloc(uint8_t avl, bool nolow) {
Expand All @@ -441,25 +437,18 @@ void* Pagetable::_alloc(uint8_t avl, bool nolow) {
}

void* Pagetable::alloc(uint8_t avl) {
uint64_t t = EnterCritical();
page_mutex.lock();
void* ret = _alloc(avl);
page_mutex.release();
LeaveCritical(t);
return ret;
Mutex::CriticalLock lock(page_mutex);
return _alloc(avl);
}

void Pagetable::free(void* page) {
PTE *pagetable; asm volatile("mov %%cr3, %q0":"=r"(pagetable));
uint64_t t = EnterCritical();
page_mutex.lock();
Mutex::CriticalLock lock(page_mutex);
PTE *pdata = PTE::find(page, pagetable);
if ((pdata != nullptr) && pdata->present) {
pdata->present = 0;
void *addr = pdata->getPtr();
if ((uintptr_t(addr) >> 12) < last_page)
last_page = uintptr_t(addr) >> 12;
}
page_mutex.release();
LeaveCritical(t);
}

0 comments on commit d1bb756

Please sign in to comment.