Designed and implemented by Chris M. Thomasson. Complete implementation can be found on GitHub.
mutex.h:
class rw_fast_mutex
{
public:
rw_fast_mutex()
: m_wrstate(1), m_count(INT_MAX), m_rdwake(0),
m_rdwset(0), m_wrwset(0), m_wrmtx(0) {}
void read_lock()
{
if (m_count.fetch_add(-1, std::memory_order_acquire) < 1)
m_rdwset.wait();
}
void read_unlock()
{
if (m_count.fetch_add(1, std::memory_order_release) < 0)
if (m_rdwake.fetch_add(-1, std::memory_order_acq_rel) == 1)
m_wrwset.post();
}
void write_lock()
{
if (m_wrstate.fetch_sub(1, std::memory_order_acquire) < 1)
m_wrmtx.wait();
int count = m_count.fetch_add(-INT_MAX, std::memory_order_acquire);
if (count < INT_MAX)
{
int rdwake = m_rdwake.fetch_add(INT_MAX - count, std::memory_order_acquire);
if (rdwake + INT_MAX - count)
m_wrwset.wait();
}
}
void write_unlock()
{
int count = m_count.fetch_add(INT_MAX, std::memory_order_release);
if (count < 0)
m_rdwset.post(-count);
if (m_wrstate.fetch_add(1, std::memory_order_release) < 0)
m_wrmtx.post();
}
private:
std::atomic m_wrstate;
std::atomic m_count;
std::atomic m_rdwake;
semaphore m_rdwset;
semaphore m_wrwset;
semaphore m_wrmtx;
};
Thanks for your interest in my algorithm. I had a fun time creating it back in 2007-2008. It was interesting to think up a scheme that can get around any CAS loops. Also, this is 100% starvation free. Nice. :^)