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().



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to