Optimize the seqlock implementation
[fio.git] / lib / seqlock.h
1 #ifndef FIO_SEQLOCK_H
2 #define FIO_SEQLOCK_H
3
4 #include "types.h"
5 #include "../arch/arch.h"
6
7 struct seqlock {
8         volatile int sequence;
9 };
10
11 static inline void seqlock_init(struct seqlock *s)
12 {
13         s->sequence = 0;
14 }
15
16 static inline unsigned int read_seqlock_begin(struct seqlock *s)
17 {
18         unsigned int seq;
19
20         do {
21                 seq = atomic_load_acquire(&s->sequence);
22                 if (!(seq & 1))
23                         break;
24                 nop;
25         } while (1);
26
27         return seq;
28 }
29
30 static inline bool read_seqlock_retry(struct seqlock *s, unsigned int seq)
31 {
32         read_barrier();
33         return s->sequence != seq;
34 }
35
36 static inline void write_seqlock_begin(struct seqlock *s)
37 {
38         s->sequence = atomic_load_acquire(&s->sequence) + 1;
39 }
40
41 static inline void write_seqlock_end(struct seqlock *s)
42 {
43         atomic_store_release(&s->sequence, s->sequence + 1);
44 }
45
46 #endif