From 6f334756c57ce83871e13085f72fd6bfde8d5772 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 24 Mar 2023 01:32:35 +0200 Subject: [PATCH] Kernel: Create RecursiveSpinLock and add it to Process We now lock every function within Proccess, just to be sure. Recursive lock allows us to use lock from the same thread even if we already have the spinlock locked --- kernel/include/kernel/Process.h | 2 +- kernel/include/kernel/SpinLock.h | 19 +++++++++++++++++++ kernel/kernel/Process.cpp | 11 +++++++++++ kernel/kernel/SpinLock.cpp | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 0a74a380..b483023e 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -61,7 +61,7 @@ namespace Kernel BAN::Vector m_open_files; - mutable SpinLock m_lock; + mutable RecursiveSpinLock m_lock; pid_t m_pid = 0; BAN::String m_working_directory; diff --git a/kernel/include/kernel/SpinLock.h b/kernel/include/kernel/SpinLock.h index ebf79df9..d3d2471a 100644 --- a/kernel/include/kernel/SpinLock.h +++ b/kernel/include/kernel/SpinLock.h @@ -2,6 +2,8 @@ #include +#include + namespace Kernel { @@ -20,4 +22,21 @@ namespace Kernel int m_lock = 0; }; + class RecursiveSpinLock + { + BAN_NON_COPYABLE(RecursiveSpinLock); + BAN_NON_MOVABLE(RecursiveSpinLock); + + public: + RecursiveSpinLock() = default; + void lock(); + void unlock(); + bool is_locked() const; + + private: + pid_t m_locker = 0; + uint32_t m_lock_depth = 0; + SpinLock m_lock; + }; + } \ No newline at end of file diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 8b3e6fc7..4649aa44 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -20,6 +20,8 @@ namespace Kernel BAN::ErrorOr Process::add_thread(entry_t entry, void* data) { + LockGuard _(m_lock); + auto thread = TRY(Thread::create(entry, data, this)); TRY(m_threads.push_back(thread)); if (auto res = Scheduler::get().add_thread(thread); res.is_error()) @@ -33,6 +35,7 @@ namespace Kernel void Process::on_thread_exit(Thread& thread) { + LockGuard _(m_lock); (void)thread; } @@ -118,6 +121,8 @@ namespace Kernel BAN::ErrorOr Process::absolute_path_of(BAN::StringView path) const { + LockGuard _(m_lock); + if (path.empty()) return m_working_directory; BAN::String absolute_path; @@ -142,6 +147,8 @@ namespace Kernel BAN::ErrorOr Process::validate_fd(int fd) { + LockGuard _(m_lock); + if (fd < 0 || m_open_files.size() <= (size_t)fd || !m_open_files[fd].inode) return BAN::Error::from_errno(EBADF); return {}; @@ -149,12 +156,16 @@ namespace Kernel Process::OpenFileDescription& Process::open_file_description(int fd) { + LockGuard _(m_lock); + MUST(validate_fd(fd)); return m_open_files[fd]; } BAN::ErrorOr Process::get_free_fd() { + LockGuard _(m_lock); + for (size_t fd = 0; fd < m_open_files.size(); fd++) if (!m_open_files[fd].inode) return fd; diff --git a/kernel/kernel/SpinLock.cpp b/kernel/kernel/SpinLock.cpp index 5f32ce2d..9ddffa98 100644 --- a/kernel/kernel/SpinLock.cpp +++ b/kernel/kernel/SpinLock.cpp @@ -1,4 +1,5 @@ #include +#include namespace Kernel { @@ -21,4 +22,35 @@ namespace Kernel return m_lock; } + void RecursiveSpinLock::lock() + { + // FIXME: is this thread safe? + if (m_locker == Thread::current()->tid()) + { + m_lock_depth++; + } + else + { + m_lock.lock(); + ASSERT(m_locker == 0); + m_locker = Thread::current()->tid(); + m_lock_depth = 1; + } + } + + void RecursiveSpinLock::unlock() + { + m_lock_depth--; + if (m_lock_depth == 0) + { + m_locker = 0; + m_lock.unlock(); + } + } + + bool RecursiveSpinLock::is_locked() const + { + return m_lock.is_locked(); + } + } \ No newline at end of file