diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 82c8a65..0468617 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -4,7 +4,7 @@ #include #include -NEWLOCK(DebuggerLock); +NewLock(DebuggerLock); using namespace UniversalAsynchronousReceiverTransmitter; @@ -57,7 +57,7 @@ namespace SysDbg void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) { - // SMARTLOCK(DebuggerLock); + // SmartLock(DebuggerLock); WritePrefix(Level, File, Line, Function); va_list args; va_start(args, Format); diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/Core/Memory/PhysicalMemoryManager.cpp index 5569b5d..b0c0f02 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/Core/Memory/PhysicalMemoryManager.cpp @@ -6,25 +6,25 @@ namespace Memory { uint64_t Physical::GetTotalMemory() { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); return this->TotalMemory; } uint64_t Physical::GetFreeMemory() { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); return this->FreeMemory; } uint64_t Physical::GetReservedMemory() { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); return this->ReservedMemory; } uint64_t Physical::GetUsedMemory() { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); return this->UsedMemory; } @@ -58,7 +58,7 @@ namespace Memory void *Physical::RequestPage() { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) { if (PageBitmap[PageBitmapIndex] == true) @@ -81,7 +81,7 @@ namespace Memory void *Physical::RequestPages(uint64_t Count) { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) { if (PageBitmap[PageBitmapIndex] == true) @@ -119,7 +119,7 @@ namespace Memory void Physical::FreePage(void *Address) { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); if (Address == nullptr) { warn("Null pointer passed to FreePage."); @@ -228,7 +228,7 @@ namespace Memory void Physical::Init(BootInfo *Info) { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); void *LargestFreeMemorySegment = nullptr; uint64_t LargestFreeMemorySegmentSize = 0; uint64_t MemorySize = Info->Memory.Size; diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index ce56beb..748ca91 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -7,7 +7,7 @@ namespace Memory { void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags) { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); if (!this->Table) { error("No page table"); @@ -85,7 +85,7 @@ namespace Memory void Virtual::Unmap(void *VirtualAddress) { - SMARTLOCK(this->MemoryLock); + SmartLock(this->MemoryLock); if (!this->Table) { error("No page table"); diff --git a/Core/Video/Display.cpp b/Core/Video/Display.cpp index cff8d20..fb5a5d6 100644 --- a/Core/Video/Display.cpp +++ b/Core/Video/Display.cpp @@ -7,13 +7,13 @@ extern uint64_t _binary_Files_ter_powerline_v12n_psf_start; extern uint64_t _binary_Files_ter_powerline_v12n_psf_end; extern uint64_t _binary_Files_ter_powerline_v12n_psf_size; -NEWLOCK(PrintLock); +NewLock(PrintLock); namespace Video { char Display::Print(char Char, int Index, bool WriteToUART) { - SMARTLOCK(PrintLock); + SmartLock(PrintLock); if (this->ColorIteration) { diff --git a/Kernel.cpp b/Kernel.cpp index 57abc5d..a36e881 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -12,7 +12,7 @@ #include #include -NEWLOCK(KernelLock); +NewLock(KernelLock); BootInfo *bInfo = nullptr; Video::Display *Display = nullptr; @@ -29,7 +29,7 @@ extern "C" void putchar(char c) { Display->Print(c, 0); } EXTERNC void KPrint(const char *Format, ...) { - SMARTLOCK(KernelLock); + SmartLock(KernelLock); Time tm = ReadClock(); printf_("\eCCCCCC[\e00AEFF%02ld:%02ld:%02ld\eCCCCCC] ", tm.Hour, tm.Minute, tm.Second); va_list args; diff --git a/Library/liballocimpl.cpp b/Library/liballocimpl.cpp index f81c904..163a930 100644 --- a/Library/liballocimpl.cpp +++ b/Library/liballocimpl.cpp @@ -2,7 +2,7 @@ #include #include -NEWLOCK(liballocLock); +NewLock(liballocLock); EXTERNC int liballoc_lock() { return liballocLock.Lock(); } EXTERNC int liballoc_unlock() { return liballocLock.Unlock(); } diff --git a/include/lock.hpp b/include/lock.hpp index 5f8104f..d76c6bf 100644 --- a/include/lock.hpp +++ b/include/lock.hpp @@ -1,11 +1,15 @@ #ifndef __FENNIX_KERNEL_LOCK_H__ #define __FENNIX_KERNEL_LOCK_H__ +/* +TODO: Add deadlock detection. +*/ + #include #include #ifdef __cplusplus - +/** @brief Please use this macro to create a new lock. */ class LockClass { private: @@ -28,26 +32,50 @@ public: return 0; } }; - -#define NEWLOCK(Name) LockClass Name - -class SmartLock +/** @brief Please use this macro to create a new smart lock. */ +class SmartLockClass { private: LockClass *LockPointer = nullptr; public: - SmartLock(LockClass &Lock) + SmartLockClass(LockClass &Lock) { this->LockPointer = &Lock; this->LockPointer->Lock(); } - ~SmartLock() { this->LockPointer->Unlock(); } + ~SmartLockClass() { this->LockPointer->Unlock(); } +}; +/** @brief Please use this macro to create a new smart critical section lock. */ +class SmartCriticalSectionClass +{ +private: + LockClass *LockPointer = nullptr; + bool InterruptsEnabled = false; + +public: + SmartCriticalSectionClass(LockClass &Lock) + { + if (CPU::Interrupts(CPU::Check)) + InterruptsEnabled = true; + CPU::Interrupts(CPU::Disable); + this->LockPointer = &Lock; + this->LockPointer->Lock(); + } + ~SmartCriticalSectionClass() + { + if (InterruptsEnabled) + CPU::Interrupts(CPU::Enable); + this->LockPointer->Unlock(); + } }; -#define SL_CONCAT(x, y) x##y -#define SMARTLOCK(LockClassName) SmartLock SL_CONCAT(lock##_, __COUNTER__)(LockClassName) - -#endif +/** @brief Create a new lock (can be used with SmartCriticalSection). */ +#define NewLock(Name) LockClass Name +/** @brief Simple lock that is automatically released when the scope ends. */ +#define SmartLock(LockClassName) SmartLockClass CONCAT(lock##_, __COUNTER__)(LockClassName) +/** @brief Simple critical section that is automatically released when the scope ends and interrupts are restored if they were enabled. */ +#define SmartCriticalSection(LockClassName) SmartCriticalSectionClass CONCAT(lock##_, __COUNTER__)(LockClassName) +#endif // __cplusplus #endif // !__FENNIX_KERNEL_LOCK_H__ diff --git a/include/memory.hpp b/include/memory.hpp index 006b12e..76a4c71 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -232,7 +232,7 @@ namespace Memory class Physical { private: - NEWLOCK(MemoryLock); + NewLock(MemoryLock); uint64_t TotalMemory = 0; uint64_t FreeMemory = 0; @@ -358,7 +358,7 @@ namespace Memory class Virtual { private: - NEWLOCK(MemoryLock); + NewLock(MemoryLock); PageTable *Table = nullptr; class PageMapIndexer diff --git a/include/types.h b/include/types.h index 3cb61f5..cf692a9 100644 --- a/include/types.h +++ b/include/types.h @@ -33,6 +33,7 @@ #endif #define UNUSED(x) (void)(x) +#define CONCAT(x, y) x##y #ifndef __va_list__ typedef __builtin_va_list va_list;