#include #include #define __scoped_seqlock_read(lock, s, cond) \ unrolled_full for (struct { unsigned long phase, data; } s = { 0 }; \ s.phase < 3 && cond(lock, s.phase, &s.data); s.phase++) #define scoped_seqlock_read(lock) \ __scoped_seqlock_read(lock, __UNIQUE_ID(s), __seqlock_cond) #define scoped_seqlock_read_irqsave(lock) \ __scoped_seqlock_read(lock, __UNIQUE_ID(s), __seqlock_cond_irqsave) /* Do the phase action and return true if the loop should go on */ static __always_inline bool __seqlock_cond(seqlock_t *lock, int phase, unsigned long *data) { switch (phase) { case 0: *data = read_seqbegin(lock); return true; case 1: if (!read_seqretry(lock, *data)) return false; read_seqlock_excl(lock); return true; default: read_sequnlock_excl(lock); return false; } } static __always_inline bool __seqlock_cond_irqsave(seqlock_t *lock, int phase, unsigned long *data) { switch (phase) { case 0: *data = read_seqbegin(lock); return true; case 1: if (!read_seqretry(lock, *data)) return false; read_seqlock_excl_irqsave(lock, *data); return true; default: read_sequnlock_excl_irqrestore(lock, *data); return false; } } void testme(seqlock_t *lock); void testme(seqlock_t *lock) { scoped_seqlock_read_irqsave(lock) { asm volatile("TEST"); } }