diff options
Diffstat (limited to 'kernel/kapi/tracked_mutex.cpp')
| -rw-r--r-- | kernel/kapi/tracked_mutex.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/kernel/kapi/tracked_mutex.cpp b/kernel/kapi/tracked_mutex.cpp new file mode 100644 index 00000000..6608169c --- /dev/null +++ b/kernel/kapi/tracked_mutex.cpp @@ -0,0 +1,55 @@ +#include <kapi/tracked_mutex.hpp> + +#include <kapi/cpu.hpp> +#include <kapi/system.hpp> + +#include <atomic> + +namespace kapi +{ + + auto tracked_mutex::lock() -> void + { + auto self = kapi::cpu::current_id(); + auto expected = kapi::cpu::invalid_id; + + while (!m_owner.compare_exchange_weak(expected, self, std::memory_order::acquire, std::memory_order::relaxed)) + { + if (expected == self) + { + system::panic("[OS] CPU {} tried to reacquire a mutex it already holds!", self); + } + expected = kapi::cpu::invalid_id; + } + } + + auto tracked_mutex::try_lock() -> bool + { + auto self = kapi::cpu::current_id(); + auto expected = kapi::cpu::invalid_id; + + if (m_owner.compare_exchange_strong(expected, self, std::memory_order::acquire, std::memory_order::relaxed)) + { + return true; + } + + if (expected == self) + { + system::panic("[OS] CPU {} tried to reacquire a mutex it already holds!", self); + } + + return false; + } + + auto tracked_mutex::unlock() -> void + { + auto self = kapi::cpu::current_id(); + auto expected = self; + + if (!m_owner.compare_exchange_strong(expected, kapi::cpu::invalid_id, std::memory_order::release)) + { + system::panic("[OS] CPU {} released a mutex it did not hold!", self); + } + } + +} // namespace kapi
\ No newline at end of file |
