Commit d301cc8e authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents ec619a1d 98a7fa0c
...@@ -50,9 +50,22 @@ class rw_lock ...@@ -50,9 +50,22 @@ class rw_lock
static constexpr uint32_t UPDATER= 1U << 29; static constexpr uint32_t UPDATER= 1U << 29;
#endif /* SUX_LOCK_GENERIC */ #endif /* SUX_LOCK_GENERIC */
/** Start waiting for an exclusive lock. */
void write_lock_wait_start()
{
#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
static_assert(WRITER_WAITING == 1U << 30, "compatibility");
__asm__ __volatile__("lock btsl $30, %0" : "+m" (lock));
#elif defined _MSC_VER && (defined _M_IX86 || defined _M_IX64)
static_assert(WRITER_WAITING == 1U << 30, "compatibility");
_interlockedbittestandset(reinterpret_cast<volatile long*>(&lock), 30);
#else
lock.fetch_or(WRITER_WAITING, std::memory_order_relaxed);
#endif
}
/** Start waiting for an exclusive lock. /** Start waiting for an exclusive lock.
@return current value of the lock word */ @return current value of the lock word */
uint32_t write_lock_wait_start() uint32_t write_lock_wait_start_read()
{ return lock.fetch_or(WRITER_WAITING, std::memory_order_relaxed); } { return lock.fetch_or(WRITER_WAITING, std::memory_order_relaxed); }
/** Wait for an exclusive lock. /** Wait for an exclusive lock.
@param l the value of the lock word @param l the value of the lock word
......
...@@ -193,10 +193,10 @@ void ssux_lock_impl<spinloop>::write_lock(bool holding_u) ...@@ -193,10 +193,10 @@ void ssux_lock_impl<spinloop>::write_lock(bool holding_u)
{ {
for (;;) for (;;)
{ {
uint32_t l= write_lock_wait_start(); write_lock_wait_start();
const uint32_t e= holding_u ? WRITER_WAITING | UPDATER : WRITER_WAITING; const uint32_t e= holding_u ? WRITER_WAITING | UPDATER : WRITER_WAITING;
l= e; uint32_t l= e;
if (write_lock_wait_try(l)) if (write_lock_wait_try(l))
return; return;
...@@ -213,7 +213,7 @@ void ssux_lock_impl<spinloop>::write_lock(bool holding_u) ...@@ -213,7 +213,7 @@ void ssux_lock_impl<spinloop>::write_lock(bool holding_u)
return; return;
} }
for (l= write_lock_wait_start() | WRITER_WAITING; for (l= write_lock_wait_start_read() | WRITER_WAITING;
(l | WRITER_WAITING) == e; ) (l | WRITER_WAITING) == e; )
if (write_lock_wait_try(l)) if (write_lock_wait_try(l))
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment