qdev-properties-system: Change set_pointer's parse callback to use Error
[qemu.git] / include / qemu / seqlock.h
blob3ff118a1a1f5d2a2b3cc32c957b153452f995ae2
1 /*
2 * Seqlock implementation for QEMU
4 * Copyright Red Hat, Inc. 2013
6 * Author:
7 * Paolo Bonzini <pbonzini@redhat.com>
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.
13 #ifndef QEMU_SEQLOCK_H
14 #define QEMU_SEQLOCK_H 1
16 #include <qemu/atomic.h>
17 #include <qemu/thread.h>
19 typedef struct QemuSeqLock QemuSeqLock;
21 struct QemuSeqLock {
22 QemuMutex *mutex;
23 unsigned sequence;
26 static inline void seqlock_init(QemuSeqLock *sl, QemuMutex *mutex)
28 sl->mutex = mutex;
29 sl->sequence = 0;
32 /* Lock out other writers and update the count. */
33 static inline void seqlock_write_lock(QemuSeqLock *sl)
35 if (sl->mutex) {
36 qemu_mutex_lock(sl->mutex);
38 ++sl->sequence;
40 /* Write sequence before updating other fields. */
41 smp_wmb();
44 static inline void seqlock_write_unlock(QemuSeqLock *sl)
46 /* Write other fields before finalizing sequence. */
47 smp_wmb();
49 ++sl->sequence;
50 if (sl->mutex) {
51 qemu_mutex_unlock(sl->mutex);
55 static inline unsigned seqlock_read_begin(QemuSeqLock *sl)
57 /* Always fail if a write is in progress. */
58 unsigned ret = sl->sequence & ~1;
60 /* Read sequence before reading other fields. */
61 smp_rmb();
62 return ret;
65 static int seqlock_read_retry(const QemuSeqLock *sl, unsigned start)
67 /* Read other fields before reading final sequence. */
68 smp_rmb();
69 return unlikely(sl->sequence != start);
72 #endif