On Wed, May 07, 2014 at 07:29:16PM +0100, Will Deacon wrote: > better_spin_lock(atomic_t *lock) > { > /* > * Atomic add to lock with acquire semantics, returning original > * value. > */ > int old = atomic_xchg_add(ACQUIRE, lock, 1 << TICKET_SHIFT); > if ((old << TICKET_SHIFT) == (old & (TICKET_MASK << TICKET_SHIFT))) > return; /* Got the lock */ > > while (smp_load_acquire((u16 *)lock) != (old >> TICKET_SHIFT)) > cpu_relax(); > } So xchg_add and atomic_add_return() are pretty much an identity map because the add operation is reversible. The other popular name for this operation is fetch_add() fwiw. In any case, something that's been brewing in the back of my mind is an ATOMIC_OP() and ATOMIC_RET_OP() macro construct that takes a lambda function (expr-stmt is I think the closes we get in C) and either generates the appropriate ll/sc loop or a cmpxchg loop, depending on arch. Its fairly sad that many of the generic atomic operations we do with cmpxchg loops where ll/sc archs can do better using their ll/sc primitive and I just feel there must be a semi-sane way to express all that, despite C :-) That also reminds me, I should send round 2 of the arch atomic cleanups (I've got the patches), and write changelogs for round 3, and start on the patches for round 4 :-)