Details
-
Type:
Task
-
Status: Open
-
Priority:
Major
-
Resolution: Unresolved
-
Fix Version/s: 10.2
-
Component/s: None
-
Labels: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();
}
Gliffy Diagrams
Attachments
Issue Links
Activity
- All
- Comments
- Work Log
- History
- Activity
- Transitions
MySQL 5.7 got new mutex implementation, which is totally different from current one. It has combined waiters and lock_word. At first glance code looks dead complex and not very optimal: still a bunch of full memory barriers etc. We'll need to postpone this task till we merge and test new implementation.