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:
parent
310713d203
commit
6f334756c5
|
@ -61,7 +61,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::Vector<OpenFileDescription> m_open_files;
|
BAN::Vector<OpenFileDescription> m_open_files;
|
||||||
|
|
||||||
mutable SpinLock m_lock;
|
mutable RecursiveSpinLock m_lock;
|
||||||
|
|
||||||
pid_t m_pid = 0;
|
pid_t m_pid = 0;
|
||||||
BAN::String m_working_directory;
|
BAN::String m_working_directory;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <BAN/NoCopyMove.h>
|
#include <BAN/NoCopyMove.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -20,4 +22,21 @@ namespace Kernel
|
||||||
int m_lock = 0;
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,6 +20,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::add_thread(entry_t entry, void* data)
|
BAN::ErrorOr<void> Process::add_thread(entry_t entry, void* data)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
auto thread = TRY(Thread::create(entry, data, this));
|
auto thread = TRY(Thread::create(entry, data, this));
|
||||||
TRY(m_threads.push_back(thread));
|
TRY(m_threads.push_back(thread));
|
||||||
if (auto res = Scheduler::get().add_thread(thread); res.is_error())
|
if (auto res = Scheduler::get().add_thread(thread); res.is_error())
|
||||||
|
@ -33,6 +35,7 @@ namespace Kernel
|
||||||
|
|
||||||
void Process::on_thread_exit(Thread& thread)
|
void Process::on_thread_exit(Thread& thread)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
(void)thread;
|
(void)thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +121,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::String> Process::absolute_path_of(BAN::StringView path) const
|
BAN::ErrorOr<BAN::String> Process::absolute_path_of(BAN::StringView path) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
return m_working_directory;
|
return m_working_directory;
|
||||||
BAN::String absolute_path;
|
BAN::String absolute_path;
|
||||||
|
@ -142,6 +147,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::validate_fd(int fd)
|
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)
|
if (fd < 0 || m_open_files.size() <= (size_t)fd || !m_open_files[fd].inode)
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
return {};
|
return {};
|
||||||
|
@ -149,12 +156,16 @@ namespace Kernel
|
||||||
|
|
||||||
Process::OpenFileDescription& Process::open_file_description(int fd)
|
Process::OpenFileDescription& Process::open_file_description(int fd)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
MUST(validate_fd(fd));
|
MUST(validate_fd(fd));
|
||||||
return m_open_files[fd];
|
return m_open_files[fd];
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<int> Process::get_free_fd()
|
BAN::ErrorOr<int> Process::get_free_fd()
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
for (size_t fd = 0; fd < m_open_files.size(); fd++)
|
for (size_t fd = 0; fd < m_open_files.size(); fd++)
|
||||||
if (!m_open_files[fd].inode)
|
if (!m_open_files[fd].inode)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <kernel/SpinLock.h>
|
#include <kernel/SpinLock.h>
|
||||||
|
#include <kernel/Thread.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
@ -21,4 +22,35 @@ namespace Kernel
|
||||||
return m_lock;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue