Messages in this thread | | | Date | Sun, 15 Jun 2014 15:12:55 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH v11 06/16] qspinlock: prolong the stay in the pending bit path |
| |
On Thu, Jun 12, 2014 at 04:54:52PM -0400, Waiman Long wrote: > If two tasks see the pending bit goes away and try to grab it with cmpxchg, > there is no way we can avoid the contention. However, if some how the > pending bit holder get the lock and another task set the pending bit before > the current task, the spinlock value will become > _Q_PENDING_VAL|_Q_LOCKED_VAL. The while loop will end and the code will > blindly try to do a cmpxchg unless we check for this case before hand. This > is what my code does by going back to the beginning of the for loop.
There is already a test for that; see the goto queue;
---
/* * wait for in-progress pending->locked hand-overs * * 0,1,0 -> 0,0,1 */ if (val == _Q_PENDING_VAL) { while ((val = atomic_read(&lock->val)) == _Q_PENDING_VAL) cpu_relax(); }
/* * trylock || pending * * 0,0,0 -> 0,0,1 ; trylock * 0,0,1 -> 0,1,1 ; pending */ for (;;) { /* * If we observe any contention; queue. */ if (val & ~_Q_LOCKED_MASK) goto queue;
new = _Q_LOCKED_VAL; if (val == new) new |= _Q_PENDING_VAL;
old = atomic_cmpxchg(&lock->val, val, new); if (old == val) break;
val = old; }
| |