diff --git a/kernel/src/Log.cpp b/kernel/src/Log.cpp index cd153c12..992d9db1 100644 --- a/kernel/src/Log.cpp +++ b/kernel/src/Log.cpp @@ -2,6 +2,7 @@ #include "arch/CPU.h" #include "arch/Serial.h" #include "arch/Timer.h" +#include "thread/Spinlock.h" #include "video/TextConsole.h" #include #include @@ -18,11 +19,16 @@ static constexpr u32 RED = 0xffff0000; static char log_level_letters[] = { 'D', 'I', 'W', 'E' }; // D for debug, I for info, W for warning, E for error static const char* ansi_color_codes_per_log_level[] = { "37", "37", "33", "31" }; // 37 is white, 33 yellow, 31 red +Spinlock g_serial_lock; + static void log_serial(LogLevel level, const char* format, va_list origin) { va_list ap; va_copy(ap, origin); + const SafeScopeLock lock { g_serial_lock }; + if (!lock.did_succeed()) return; + Serial::printf("\x1b[%sm" "%c" "\x1b[0m ", @@ -39,11 +45,15 @@ static void log_serial(LogLevel level, const char* format, va_list origin) va_end(ap); } +Spinlock g_console_lock; + static void log_text_console(LogLevel level, const char* format, va_list origin) { va_list ap; va_copy(ap, origin); + const ScopeLock lock { g_console_lock }; + const u32 original_foreground = TextConsole::foreground(); const u32 original_background = TextConsole::background(); diff --git a/kernel/src/thread/Spinlock.cpp b/kernel/src/thread/Spinlock.cpp index f1802b80..b1744f09 100644 --- a/kernel/src/thread/Spinlock.cpp +++ b/kernel/src/thread/Spinlock.cpp @@ -26,3 +26,28 @@ void Spinlock::unlock() kwarnln("Spinlock::unlock() called on an unlocked lock with value %d", expected); } } + +ScopeLock::ScopeLock(Spinlock& lock) : m_lock(lock) +{ + m_lock.lock(); +} + +ScopeLock::~ScopeLock() +{ + m_lock.unlock(); +} + +const u32 RETRIES = 5000000; + +SafeScopeLock::SafeScopeLock(Spinlock& lock) : m_lock(lock) +{ + u32 tries_left = RETRIES; + while (!lock.try_lock() && --tries_left) { CPU::pause(); } + + if (tries_left) m_success = true; +} + +SafeScopeLock::~SafeScopeLock() +{ + if (m_success) m_lock.unlock(); +} diff --git a/kernel/src/thread/Spinlock.h b/kernel/src/thread/Spinlock.h index 9a679d5f..2b8f2e5a 100644 --- a/kernel/src/thread/Spinlock.h +++ b/kernel/src/thread/Spinlock.h @@ -21,6 +21,38 @@ class Spinlock Atomic m_lock { 0 }; }; +class ScopeLock +{ + public: + ScopeLock(Spinlock& lock); + ~ScopeLock(); + + ScopeLock(const ScopeLock&) = delete; + ScopeLock(ScopeLock&&) = delete; + + private: + Spinlock& m_lock; +}; + +class SafeScopeLock +{ + public: + SafeScopeLock(Spinlock& lock); + ~SafeScopeLock(); + + SafeScopeLock(const SafeScopeLock&) = delete; + SafeScopeLock(SafeScopeLock&&) = delete; + + bool did_succeed() const + { + return m_success; + } + + private: + Spinlock& m_lock; + bool m_success { false }; +}; + template class LockedValue { struct LockedValueGuard