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
This commit is contained in:
Bananymous 2023-03-24 01:32:35 +02:00
parent 310713d203
commit 6f334756c5
4 changed files with 63 additions and 1 deletions

View File

@ -61,7 +61,7 @@ namespace Kernel
BAN::Vector<OpenFileDescription> m_open_files;
mutable SpinLock m_lock;
mutable RecursiveSpinLock m_lock;
pid_t m_pid = 0;
BAN::String m_working_directory;

View File

@ -2,6 +2,8 @@
#include <BAN/NoCopyMove.h>
#include <sys/types.h>
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;
};
}

View File

@ -20,6 +20,8 @@ namespace Kernel
BAN::ErrorOr<void> 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<BAN::String> 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<void> 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<int> 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;

View File

@ -1,4 +1,5 @@
#include <kernel/SpinLock.h>
#include <kernel/Thread.h>
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();
}
}