Details
-
Task
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Duplicate
-
None
Description
lock_word is boolean: 0 - mutex unlocked, 1 - mutex_locked
waiters is boolean: 0 - no waiters, 1 - there are suspended waiters
There are a few problems with maintaining these variables:
- we need to issue heavyweight memory barriers to ensure proper StoreLoad order
- even with memory barriers it didn't seem to work properly: we have utility thread that awakes stale waiters
- we need to load/store 2 variables instead of just 1, which may increase bus traffic
One of options would be to encode waiters into lock_word:
0 - unlocked
1 - locked, no waiters
>1 - locked, there are waiters
Ideally mutex_enter() should create just one acquire memory barrier, mutex_exit() should create just one release memory barrier.
One of possible options (neither tested nor benchmarked):
mutex_enter()
|
{
|
for (;;)
|
{
|
for (i= 0; i < SPIN_ROUNDS; i++)
|
{
|
expected= 0;
|
if (__atomic_compare_exchange_n(&lock_word, &expected, 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
|
return;
|
delay();
|
}
|
if (__atomic_fetch_add(&lock_word, 1, __ATOMIC_ACQUIRE))
|
suspend();
|
else
|
return;
|
}
|
}
|
 |
mutex_exit()
|
{
|
if (__atomic_exchange_n(&lock_word, 0, __ATOMIC_RELEASE) > 1)
|
wakeup_waiters();
|
}
|
Attachments
Issue Links
- relates to
-
MDEV-6478 MariaDB on Power8
- Closed
-
MDEV-7026 Race in InnoDB/XtraDB mutex implementation can stall or hang the server
- Closed
-
MDEV-10813 Clean-up InnoDB atomics, memory barriers and mutexes
- Closed