On Thu, Sep 20, 2018 at 06:08:32PM +0200, Peter Zijlstra wrote: > Another approach might be to use something like: > > val = xchg_relaxed(&lock->locked_pending, _Q_PENDING_VAL | > _Q_LOCKED_VAL); > val |= atomic_read_acquire(&lock->val) & _Q_TAIL_MASK; > > combined with something like: > > /* 0,0,0 -> 0,1,1 - we won trylock */ > if (!(val & _Q_LOCKED_MASK)) {
That one doesn't actually work... let me think about this more. > clear_pending(lock); > return; > } > > /* 0,0,1 -> 0,1,1 - we won pending */ > if (!(val & ~_Q_LOCKED_MASK)) { > ... > } > > /* *,0,1 -> *,1,1 - we won pending, but there's queueing */ > if (!(val & _Q_PENDING_VAL)) > clear_pending(lock); > > ... > > > Hmmm?