diff options
Diffstat (limited to 'kernel/src/generic/lock')
| -rw-r--r-- | kernel/src/generic/lock/mutex.hpp | 35 | ||||
| -rw-r--r-- | kernel/src/generic/lock/spinlock.hpp | 35 |
2 files changed, 70 insertions, 0 deletions
diff --git a/kernel/src/generic/lock/mutex.hpp b/kernel/src/generic/lock/mutex.hpp new file mode 100644 index 0000000..d48b0b4 --- /dev/null +++ b/kernel/src/generic/lock/mutex.hpp @@ -0,0 +1,35 @@ +#pragma once +#include <cstdint> +#include <atomic> + +#include <generic/lock/spinlock.hpp> +#include <generic/scheduling.hpp> + +namespace locks { + class mutex { + private: + std::atomic_flag flag = ATOMIC_FLAG_INIT; + + public: + void lock() { + if(locks::is_disabled) + return; + + while (flag.test_and_set(std::memory_order_acquire)) { + process::yield(); + } + } + + void unlock() { + flag.clear(std::memory_order_release); + } + + bool test() { + return flag.test(); + } + + bool try_lock() { + return !flag.test_and_set(std::memory_order_acquire); + } + }; +};
\ No newline at end of file diff --git a/kernel/src/generic/lock/spinlock.hpp b/kernel/src/generic/lock/spinlock.hpp index 782e682..2c2b2a6 100644 --- a/kernel/src/generic/lock/spinlock.hpp +++ b/kernel/src/generic/lock/spinlock.hpp @@ -6,6 +6,41 @@ namespace locks { inline bool is_disabled = 0; + + class preempt_spinlock { + private: + std::atomic_flag flag = ATOMIC_FLAG_INIT; + public: + bool lock() { + if(is_disabled) + return 0; + + bool state = arch::test_interrupts(); + + arch::disable_interrupts(); + while (flag.test_and_set(std::memory_order_acquire)) { + arch::pause(); + } + + return state; + } + + void unlock(bool state) { + flag.clear(std::memory_order_release); + + if(state) + arch::enable_interrupts(); + } + + bool test() { + return flag.test(); + } + + bool try_lock() { + return !flag.test_and_set(std::memory_order_acquire); + } + }; + class spinlock { private: std::atomic_flag flag = ATOMIC_FLAG_INIT; |
