]> Git Repo - qemu.git/blame - include/qemu/seqlock.h
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' 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 */
13#ifndef QEMU_SEQLOCK_H
14#define QEMU_SEQLOCK_H 1
15
16#include <qemu/atomic.h>
17#include <qemu/thread.h>
18
19typedef struct QemuSeqLock QemuSeqLock;
20
21struct QemuSeqLock {
22 QemuMutex *mutex;
23 unsigned sequence;
24};
25
26static inline void seqlock_init(QemuSeqLock *sl, QemuMutex *mutex)
27{
28 sl->mutex = mutex;
29 sl->sequence = 0;
30}
31
32/* Lock out other writers and update the count. */
33static inline void seqlock_write_lock(QemuSeqLock *sl)
34{
35 if (sl->mutex) {
36 qemu_mutex_lock(sl->mutex);
37 }
38 ++sl->sequence;
39
40 /* Write sequence before updating other fields. */
41 smp_wmb();
42}
43
44static inline void seqlock_write_unlock(QemuSeqLock *sl)
45{
46 /* Write other fields before finalizing sequence. */
47 smp_wmb();
48
49 ++sl->sequence;
50 if (sl->mutex) {
51 qemu_mutex_unlock(sl->mutex);
52 }
53}
54
55static inline unsigned seqlock_read_begin(QemuSeqLock *sl)
56{
57 /* Always fail if a write is in progress. */
d12f7309 58 unsigned ret = atomic_read(&sl->sequence);
ea753d81
PB
59
60 /* Read sequence before reading other fields. */
61 smp_rmb();
d12f7309 62 return ret & ~1;
ea753d81
PB
63}
64
123fdbac 65static inline int seqlock_read_retry(const QemuSeqLock *sl, unsigned start)
ea753d81
PB
66{
67 /* Read other fields before reading final sequence. */
68 smp_rmb();
d12f7309 69 return unlikely(atomic_read(&sl->sequence) != start);
ea753d81
PB
70}
71
72#endif
This page took 0.113127 seconds and 4 git commands to generate.