]> Git Repo - qemu.git/blame - include/qemu/seqlock.h
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[qemu.git] / include / qemu / seqlock.h
CommitLineData
ea753d81
PB
1/*
2 * Seqlock implementation for QEMU
3 *
4 * Copyright Red Hat, Inc. 2013
5 *
6 * Author:
7 * Paolo Bonzini <[email protected]>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 *
12 */
175de524 13
ea753d81 14#ifndef QEMU_SEQLOCK_H
175de524 15#define QEMU_SEQLOCK_H
ea753d81 16
a9c94277
MA
17#include "qemu/atomic.h"
18#include "qemu/thread.h"
ea753d81
PB
19
20typedef struct QemuSeqLock QemuSeqLock;
21
22struct QemuSeqLock {
ea753d81
PB
23 unsigned sequence;
24};
25
ccdb3c1f 26static inline void seqlock_init(QemuSeqLock *sl)
ea753d81 27{
ea753d81
PB
28 sl->sequence = 0;
29}
30
31/* Lock out other writers and update the count. */
03719e44 32static inline void seqlock_write_begin(QemuSeqLock *sl)
ea753d81 33{
f96a8cc3 34 atomic_set(&sl->sequence, sl->sequence + 1);
ea753d81
PB
35
36 /* Write sequence before updating other fields. */
37 smp_wmb();
38}
39
03719e44 40static inline void seqlock_write_end(QemuSeqLock *sl)
ea753d81
PB
41{
42 /* Write other fields before finalizing sequence. */
43 smp_wmb();
44
f96a8cc3 45 atomic_set(&sl->sequence, sl->sequence + 1);
ea753d81
PB
46}
47
48static inline unsigned seqlock_read_begin(QemuSeqLock *sl)
49{
50 /* Always fail if a write is in progress. */
d12f7309 51 unsigned ret = atomic_read(&sl->sequence);
ea753d81
PB
52
53 /* Read sequence before reading other fields. */
54 smp_rmb();
d12f7309 55 return ret & ~1;
ea753d81
PB
56}
57
123fdbac 58static inline int seqlock_read_retry(const QemuSeqLock *sl, unsigned start)
ea753d81
PB
59{
60 /* Read other fields before reading final sequence. */
61 smp_rmb();
d12f7309 62 return unlikely(atomic_read(&sl->sequence) != start);
ea753d81
PB
63}
64
65#endif
This page took 0.165954 seconds and 4 git commands to generate.