Messages in this thread | | | Date | Thu, 12 Sep 2013 03:25:31 +0200 | From | Peter Zijlstra <> | Subject | Re: [RFC PATCH] timekeeping: introduce timekeeping_is_busy() |
| |
On Wed, Sep 11, 2013 at 08:48:11PM -0400, Mathieu Desnoyers wrote: > Thoughts ?
struct foo { ... };
spinlock_t foo_lock; unsigned int foo_head = 0; unsigned int foo_tail = 0; struct foo foo_array[2];
void foo_assign(struct foo f) { spin_lock(&foo_lock); foo_head++; smp_wmb(); foo_array[foo_head & 1] = f; smp_wmb(); foo_tail++; spin_unlock(&foo_lock); }
struct foo foo_get(void) { unsigned int tail, head; struct foo ret;
again: tail = ACCESS_ONCE(foo_tail); smp_rmb(); ret = foo_array[tail & 1]; smp_rmb(); head = ACCESS_ONCE(foo_head); if (head - tail >= 2) goto again;
return ret; }
Should work and get you the most recent 'complete' foo even when foo_get() is called nested inside foo_assign().
| |