On 04/16/2019 12:15 PM, Peter Zijlstra wrote: > On Tue, Apr 16, 2019 at 05:49:37PM +0200, Peter Zijlstra wrote: >> See, if you first write that function in the form: >> >> long new; >> >> do { >> new = count | RWSEM_WRITER_LOCKED; >> >> if (count & RWSEM_LOCK_MASK) >> return false; >> >> if (list_is_singular(&sem->wait_list)) >> new &= ~RWSEM_FLAG_WAITERS; >> >> } while (atomic_long_try_cmpxchg_acquire(&sem->count, &count, new)); >> >> rwsem_set_owner(sem); >> return true; >> >> And then add the HANDOFF bits like: >> >> long new; >> >> do { >> + bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF); >> >> + new = (count | RWSEM_WRITER_LOCKED) & ~RWSEM_FLAG_HANDOFF; >> >> if (count & RWSEM_LOCK_MASK) { >> + if (has_handoff && wstate != WRITER_HANDOFF) >> + return false; >> new |= RWSEM_FLAG_HANDOFF; >> } >> >> + if (has_handoff && wstate == WRITER_NOT_FIRST) >> + return false; >> >> if (list_is_singular(&sem->wait_list)) >> new &= ~RWSEM_FLAG_WAITERS; >> >> } while (atomic_long_try_cmpxchg_acquire(&sem->count, &count, new)); > obviously that should be ! >
Right. -Longman