Kernel: Implement basic RWLock
This commit is contained in:
parent
6cdf5a5a7f
commit
912c5ea0bf
|
|
@ -0,0 +1,97 @@
|
|||
#pragma once
|
||||
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
#include <kernel/Lock/LockGuard.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class RWLock
|
||||
{
|
||||
BAN_NON_COPYABLE(RWLock);
|
||||
BAN_NON_MOVABLE(RWLock);
|
||||
public:
|
||||
RWLock() = default;
|
||||
|
||||
void rd_lock()
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
while (m_writers_waiting > 0 || m_writer_active)
|
||||
m_thread_blocker.block_indefinite(&m_mutex);
|
||||
m_readers_active++;
|
||||
}
|
||||
|
||||
void rd_unlock()
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
if (--m_readers_active == 0)
|
||||
m_thread_blocker.unblock();
|
||||
}
|
||||
|
||||
void wr_lock()
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
m_writers_waiting++;
|
||||
while (m_readers_active > 0 || m_writer_active)
|
||||
m_thread_blocker.block_indefinite(&m_mutex);
|
||||
m_writers_waiting--;
|
||||
m_writer_active = true;
|
||||
}
|
||||
|
||||
|
||||
void wr_unlock()
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
m_writer_active = false;
|
||||
m_thread_blocker.unblock();
|
||||
}
|
||||
|
||||
private:
|
||||
Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
uint32_t m_readers_active { 0 };
|
||||
uint32_t m_writers_waiting { 0 };
|
||||
bool m_writer_active { false };
|
||||
};
|
||||
|
||||
class RWLockRDGuard
|
||||
{
|
||||
BAN_NON_COPYABLE(RWLockRDGuard);
|
||||
BAN_NON_MOVABLE(RWLockRDGuard);
|
||||
public:
|
||||
RWLockRDGuard(RWLock& lock)
|
||||
: m_lock(lock)
|
||||
{
|
||||
m_lock.rd_lock();
|
||||
}
|
||||
|
||||
~RWLockRDGuard()
|
||||
{
|
||||
m_lock.rd_unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
RWLock& m_lock;
|
||||
};
|
||||
|
||||
class RWLockWRGuard
|
||||
{
|
||||
BAN_NON_COPYABLE(RWLockWRGuard);
|
||||
BAN_NON_MOVABLE(RWLockWRGuard);
|
||||
public:
|
||||
RWLockWRGuard(RWLock& lock)
|
||||
: m_lock(lock)
|
||||
{
|
||||
m_lock.wr_lock();
|
||||
}
|
||||
|
||||
~RWLockWRGuard()
|
||||
{
|
||||
m_lock.wr_unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
RWLock& m_lock;
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue