arch,lib/seqlock: implement seqlock with C++ atomic if compiled with C++
[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 #ifdef __cplusplus
9         std::atomic<unsigned int> sequence;
10 #else
11         volatile unsigned int sequence;
12 #endif
13 };
14
15 static inline void seqlock_init(struct seqlock *s)
16 {
17         s->sequence = 0;
18 }
19
20 static inline unsigned int read_seqlock_begin(struct seqlock *s)
21 {
22         unsigned int seq;
23
24         do {
25                 seq = atomic_load_acquire(&s->sequence);
26                 if (!(seq & 1))
27                         break;
28                 nop;
29         } while (1);
30
31         return seq;
32 }
33
34 static inline bool read_seqlock_retry(struct seqlock *s, unsigned int seq)
35 {
36         read_barrier();
37         return s->sequence != seq;
38 }
39
40 static inline void write_seqlock_begin(struct seqlock *s)
41 {
42         s->sequence = atomic_load_acquire(&s->sequence) + 1;
43 }
44
45 static inline void write_seqlock_end(struct seqlock *s)
46 {
47         atomic_store_release(&s->sequence, s->sequence + 1);
48 }
49
50 #endif