Messages in this thread | | | Date | 12 Nov 2013 12:16:33 -0500 | From | "George Spelvin" <> | Subject | Re: [PATCH v5 4/4] MCS Lock: Barrier corrections |
| |
> On Mon, Nov 11, 2013 at 09:17:52PM +0000, Tim Chen wrote: >> An alternate implementation is >> while (!ACCESS_ONCE(node->locked)) >> arch_mutex_cpu_relax(); >> smp_load_acquire(&node->locked); >> >> Leaving the smp_load_acquire at the end to provide appropriate barrier. >> Will that be acceptable?
Will Deacon <will.deacon@arm.com> wrote: > It still doesn't solve my problem though: I want a way to avoid that busy > loop by some architecture-specific manner. The arch_mutex_cpu_relax() hook > is a start, but there is no corresponding hook on the unlock side to issue a > wakeup. Given a sensible relax implementation, I don't have an issue with > putting a load-acquire in a loop, since it shouldn't be aggresively spinning > anymore.
So you want something like this?
/* * This is a spin-wait with acquire semantics. That is, accesses after * this are not allowed to be reordered before the load that meets * the specified condition. This requires that it end with either a * load-acquire or a full smp_mb(). The optimal way to do this is likely * to be architecture-dependent. E.g. x86 MONITOR/MWAIT instructions. */ #ifndef smp_load_acquire_until #define smp_load_acquire_until(addr, cond) \ while (!(smp_load_acquire(addr) cond)) { \ do { \ arch_mutex_cpu_relax(); \ } while (!(ACCESS_ONCE(*(addr)) cond)); \ } #endif
smp_load_acquire_until(&node->locked, != 0);
Alternative implementations:
#define smp_load_acquire_until(addr, cond) { \ while (!(ACCESS_ONCE(*(addr)) cond)) \ arch_mutex_cpu_relax(); \ smp_mb(); }
#define smp_load_acquire_until(addr, cond) \ if (!(smp_load_acquire(addr) cond)) { \ do { \ arch_mutex_cpu_relax(); \ } while (!(ACCESS_ONCE(*(addr)) cond)); \ smp_mb(); \ }
| |