From: "Emilio G. Cota" <cota@braap.org>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Peter Crosthwaite" <crosthwaite.peter@gmail.com>,
"Richard Henderson" <rth@twiddle.net>,
"Eduardo Habkost" <ehabkost@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Murilo Opsfelder Araujo" <muriloo@linux.ibm.com>
Subject: [Qemu-devel] [PATCH v2 02/12] util: add atomic64
Date: Mon, 10 Sep 2018 19:27:42 -0400 [thread overview]
Message-ID: <20180910232752.31565-3-cota@braap.org> (raw)
In-Reply-To: <20180910232752.31565-1-cota@braap.org>
This introduces read/set accessors for int64_t and uint64_t.
Signed-off-by: Emilio G. Cota <cota@braap.org>
---
include/qemu/atomic.h | 34 ++++++++++++++++++
util/atomic64.c | 83 +++++++++++++++++++++++++++++++++++++++++++
util/cacheinfo.c | 3 ++
util/Makefile.objs | 1 +
4 files changed, 121 insertions(+)
create mode 100644 util/atomic64.c
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 9ed39effd3..c34c2f78c4 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -450,4 +450,38 @@
_oldn; \
})
+/* Abstractions to access atomically (i.e. "once") i64/u64 variables */
+#ifdef CONFIG_ATOMIC64
+static inline int64_t atomic_read_i64(const int64_t *ptr)
+{
+ /* use __nocheck because sizeof(void *) might be < sizeof(u64) */
+ return atomic_read__nocheck(ptr);
+}
+
+static inline uint64_t atomic_read_u64(const uint64_t *ptr)
+{
+ return atomic_read__nocheck(ptr);
+}
+
+static inline void atomic_set_i64(int64_t *ptr, int64_t val)
+{
+ atomic_set__nocheck(ptr, val);
+}
+
+static inline void atomic_set_u64(uint64_t *ptr, uint64_t val)
+{
+ atomic_set__nocheck(ptr, val);
+}
+
+static inline void atomic64_init(void)
+{
+}
+#else /* !CONFIG_ATOMIC64 */
+int64_t atomic_read_i64(const int64_t *ptr);
+uint64_t atomic_read_u64(const uint64_t *ptr);
+void atomic_set_i64(int64_t *ptr, int64_t val);
+void atomic_set_u64(uint64_t *ptr, uint64_t val);
+void atomic64_init(void);
+#endif /* !CONFIG_ATOMIC64 */
+
#endif /* QEMU_ATOMIC_H */
diff --git a/util/atomic64.c b/util/atomic64.c
new file mode 100644
index 0000000000..b198a6c9c8
--- /dev/null
+++ b/util/atomic64.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
+ *
+ * License: GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu/atomic.h"
+#include "qemu/thread.h"
+
+#ifdef CONFIG_ATOMIC64
+#error This file must only be compiled if !CONFIG_ATOMIC64
+#endif
+
+/*
+ * When !CONFIG_ATOMIC64, we serialize both reads and writes with spinlocks.
+ * We use an array of spinlocks, with padding computed at run-time based on
+ * the host's dcache line size.
+ * We point to the array with a void * to simplify the padding's computation.
+ * Each spinlock is located every lock_size bytes.
+ */
+static void *lock_array;
+static size_t lock_size;
+
+/*
+ * Systems without CONFIG_ATOMIC64 are unlikely to have many cores, so we use a
+ * small array of locks.
+ */
+#define NR_LOCKS 16
+
+static QemuSpin *addr_to_lock(const void *addr)
+{
+ uintptr_t a = (uintptr_t)addr;
+ uintptr_t idx;
+
+ idx = a >> qemu_dcache_linesize_log;
+ idx ^= (idx >> 8) ^ (idx >> 16);
+ idx &= NR_LOCKS - 1;
+ return lock_array + idx * lock_size;
+}
+
+#define GEN_READ(name, type) \
+ type name(const type *ptr) \
+ { \
+ QemuSpin *lock = addr_to_lock(ptr); \
+ type ret; \
+ \
+ qemu_spin_lock(lock); \
+ ret = *ptr; \
+ qemu_spin_unlock(lock); \
+ return ret; \
+ }
+
+GEN_READ(atomic_read_i64, int64_t)
+GEN_READ(atomic_read_u64, uint64_t)
+#undef GEN_READ
+
+#define GEN_SET(name, type) \
+ void name(type *ptr, type val) \
+ { \
+ QemuSpin *lock = addr_to_lock(ptr); \
+ \
+ qemu_spin_lock(lock); \
+ *ptr = val; \
+ qemu_spin_unlock(lock); \
+ }
+
+GEN_SET(atomic_set_i64, int64_t)
+GEN_SET(atomic_set_u64, uint64_t)
+#undef GEN_SET
+
+void atomic64_init(void)
+{
+ int i;
+
+ lock_size = ROUND_UP(sizeof(QemuSpin), qemu_dcache_linesize);
+ lock_array = qemu_memalign(qemu_dcache_linesize, lock_size * NR_LOCKS);
+ for (i = 0; i < NR_LOCKS; i++) {
+ QemuSpin *lock = lock_array + i * lock_size;
+
+ qemu_spin_init(lock);
+ }
+}
diff --git a/util/cacheinfo.c b/util/cacheinfo.c
index 57c7d58159..6c6cbdb25d 100644
--- a/util/cacheinfo.c
+++ b/util/cacheinfo.c
@@ -8,6 +8,7 @@
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
+#include "qemu/atomic.h"
int qemu_icache_linesize = 0;
int qemu_icache_linesize_log;
@@ -179,4 +180,6 @@ static void __attribute__((constructor)) init_cache_info(void)
qemu_icache_linesize_log = 31 - clz32(isize);
qemu_dcache_linesize = dsize;
qemu_dcache_linesize_log = 31 - clz32(dsize);
+
+ atomic64_init();
}
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 0e88899011..0820923c18 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -3,6 +3,7 @@ util-obj-y += bufferiszero.o
util-obj-y += lockcnt.o
util-obj-y += aiocb.o async.o aio-wait.o thread-pool.o qemu-timer.o
util-obj-y += main-loop.o iohandler.o
+util-obj-$(call lnot,$(CONFIG_ATOMIC64)) += atomic64.o
util-obj-$(CONFIG_POSIX) += aio-posix.o
util-obj-$(CONFIG_POSIX) += compatfd.o
util-obj-$(CONFIG_POSIX) += event_notifier-posix.o
--
2.17.1
next prev parent reply other threads:[~2018-09-10 23:37 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-10 23:27 [Qemu-devel] [PATCH v2 00/12] i386 + x86_64 mttcg Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 01/12] cacheinfo: add i/d cache_linesize_log Emilio G. Cota
2018-09-11 12:16 ` Richard Henderson
2018-09-11 12:57 ` Paolo Bonzini
2018-09-10 23:27 ` Emilio G. Cota [this message]
2018-09-11 12:43 ` [Qemu-devel] [PATCH v2 02/12] util: add atomic64 Richard Henderson
2018-09-11 20:43 ` Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 03/12] tests: add atomic64-bench Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 04/12] qsp: use atomic64 accessors Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 05/12] test-rcu-list: access n_reclaims and n_nodes_removed with atomic64 Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 06/12] atomic: fix comment s/x64_64/x86_64/ Emilio G. Cota
2018-09-11 12:50 ` Richard Henderson
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 07/12] cpus: initialize timers_state.vm_clock_lock Emilio G. Cota
2018-09-11 12:50 ` Richard Henderson
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 08/12] cpus: always call seqlock_write in cpu_update_icount Emilio G. Cota
2018-09-11 12:53 ` Richard Henderson
2018-09-11 12:55 ` Paolo Bonzini
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 09/12] cpus: access .qemu_icount with atomic64 Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 10/12] cpus: access .qemu_icount_bias " Emilio G. Cota
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 11/12] target/i386/translate: use thread-local storage in !user-mode Emilio G. Cota
2018-09-11 12:57 ` Richard Henderson
2018-09-10 23:27 ` [Qemu-devel] [PATCH v2 12/12] configure: enable mttcg for i386 and x86_64 Emilio G. Cota
2018-09-11 12:58 ` Richard Henderson
2018-09-11 13:00 ` [Qemu-devel] [PATCH v2 00/12] i386 + x86_64 mttcg Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180910232752.31565-3-cota@braap.org \
--to=cota@braap.org \
--cc=alex.bennee@linaro.org \
--cc=crosthwaite.peter@gmail.com \
--cc=ehabkost@redhat.com \
--cc=muriloo@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.