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 !

> 
>       rwsem_set_owner(sem);
>       return true;
> 
> it almost looks like sensible code.

Reply via email to