From: David Howells <dhowells@redhat.com>
To: linux-kernel@vger.kernel.org
Subject: [PATCH 10/45] C++: x86: Turn xchg(), xadd() & co. into inline template functions
Date: Sun, 01 Apr 2018 21:41:15 +0100 [thread overview]
Message-ID: <152261527543.30503.554397458877242700.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <152261521484.30503.16131389653845029164.stgit@warthog.procyon.org.uk>
Turn xchg(), xadd() and similar functions into inline C++ template
functions. This produces more robust source as the all the casting the C
macros require is then unnecessary.
Signed-off-by: David Howells <dhowells@redhat.com>
---
arch/x86/include/asm/cmpxchg.h | 109 ++++++++++++++++++++++++----------------
1 file changed, 65 insertions(+), 44 deletions(-)
diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h
index 56bd436ed01b..5e896c17476d 100644
--- a/arch/x86/include/asm/cmpxchg.h
+++ b/arch/x86/include/asm/cmpxchg.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0 -*- c++ -*- */
#ifndef ASM_X86_CMPXCHG_H
#define ASM_X86_CMPXCHG_H
@@ -39,43 +39,73 @@ extern void __add_wrong_size(void)
* An exchange-type operation, which takes a value and a pointer, and
* returns the old value.
*/
-#define __xchg_op(ptr, arg, op, lock) \
- ({ \
- __typeof__ (*(ptr)) __ret = (arg); \
- switch (sizeof(*(ptr))) { \
- case __X86_CASE_B: \
- asm volatile (lock #op "b %b0, %1\n" \
- : "+q" (__ret), "+m" (*(ptr)) \
- : : "memory", "cc"); \
- break; \
- case __X86_CASE_W: \
- asm volatile (lock #op "w %w0, %1\n" \
- : "+r" (__ret), "+m" (*(ptr)) \
- : : "memory", "cc"); \
- break; \
- case __X86_CASE_L: \
- asm volatile (lock #op "l %0, %1\n" \
- : "+r" (__ret), "+m" (*(ptr)) \
- : : "memory", "cc"); \
- break; \
- case __X86_CASE_Q: \
- asm volatile (lock #op "q %q0, %1\n" \
- : "+r" (__ret), "+m" (*(ptr)) \
- : : "memory", "cc"); \
- break; \
- default: \
- __ ## op ## _wrong_size(); \
- } \
- __ret; \
- })
+template <typename P, typename N>
+static inline P xchg(P *ptr, N rep)
+{
+ P v = rep;
+
+ if (sizeof(P) > sizeof(unsigned long))
+ __xchg_wrong_size();
+
+ /* Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
+ * Since this is generally used to protect other memory information, we
+ * use "asm volatile" and "memory" clobbers to prevent gcc from moving
+ * information around.
+ */
+ asm volatile("xchg %[v], %[ptr]"
+ : [ptr] "+m" (*ptr),
+ [v] "+a" (v)
+ :
+ : "memory");
+
+ return v;
+}
/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
- * Since this is generally used to protect other memory information, we
- * use "asm volatile" and "memory" clobbers to prevent gcc from moving
- * information around.
+ * __xadd() adds "inc" to "*ptr" and atomically returns the previous
+ * value of "*ptr".
+ *
+ * __xadd() is always locked.
*/
-#define xchg(ptr, v) __xchg_op((ptr), (v), xchg, "")
+template <typename P, typename N>
+static inline P __xadd(P *ptr, N inc)
+{
+ P v = inc;
+
+ if (sizeof(P) > sizeof(unsigned long))
+ __xadd_wrong_size();
+
+ asm volatile("lock; xadd %[v], %[ptr]"
+ : [ptr] "+m" (*ptr),
+ [v] "+a" (v)
+ :
+ : "memory");
+
+ return v;
+}
+
+/*
+ * xadd() adds "inc" to "*ptr" and atomically returns the previous
+ * value of "*ptr".
+ *
+ * xadd() is locked when multiple CPUs are online
+ */
+template <typename P, typename N>
+static inline P xadd(P *ptr, N inc)
+{
+ P v = inc;
+
+ if (sizeof(P) > sizeof(unsigned long))
+ __xadd_wrong_size();
+
+ asm volatile(LOCK_PREFIX "xadd %[v], %[ptr]"
+ : [ptr] "+m" (*ptr),
+ [v] "+a" (v)
+ :
+ : "memory");
+
+ return v;
+}
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
@@ -224,15 +254,6 @@ extern void __add_wrong_size(void)
#define try_cmpxchg(ptr, pold, new) \
__try_cmpxchg((ptr), (pold), (new), sizeof(*(ptr)))
-/*
- * xadd() adds "inc" to "*ptr" and atomically returns the previous
- * value of "*ptr".
- *
- * xadd() is locked when multiple CPUs are online
- */
-#define __xadd(ptr, inc, lock) __xchg_op((ptr), (inc), xadd, lock)
-#define xadd(ptr, inc) __xadd((ptr), (inc), LOCK_PREFIX)
-
#define __cmpxchg_double(pfx, p1, p2, o1, o2, n1, n2) \
({ \
bool __ret; \
next prev parent reply other threads:[~2018-04-01 20:41 UTC|newest]
Thread overview: 98+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-01 20:40 [PATCH 00/45] C++: Convert the kernel to C++ David Howells
2018-04-01 20:40 ` [PATCH 01/45] Use UINT_MAX, not -1, to represent an invalid UID, GID or project ID David Howells
2018-04-01 23:04 ` Randy Dunlap
2018-04-01 20:40 ` [PATCH 02/45] Fix exception_enter() return value David Howells
2018-04-05 1:34 ` Sasha Levin
2018-04-01 20:40 ` [PATCH 03/45] Fix loop var in be32_to_cpu_array() and cpu_to_be32_array() David Howells
2018-04-01 20:40 ` [PATCH 04/45] Fix use of ACPI_COMPANION_SET() David Howells
2018-04-01 20:40 ` [PATCH 05/45] C++: Set compilation as C++ for .c files David Howells
2018-04-02 6:10 ` kbuild test robot
2018-04-02 6:10 ` kbuild test robot
2018-04-03 13:16 ` David Howells
2018-04-03 13:27 ` Fengguang Wu
2018-04-10 8:44 ` David Howells
2018-04-10 9:45 ` Fengguang Wu
2018-04-11 1:13 ` Li, Philip
2018-04-01 20:40 ` [PATCH 06/45] C++: Do some basic C++ type definition David Howells
2018-04-02 4:37 ` kbuild test robot
2018-04-02 6:10 ` kbuild test robot
2018-04-01 20:40 ` [PATCH 07/45] C++: Define a header with some C++ type traits for type checking David Howells
2018-04-02 7:00 ` kbuild test robot
2018-04-01 20:41 ` [PATCH 08/45] C++: Implement abs() as an inline template function David Howells
2018-04-01 20:41 ` [PATCH 09/45] C++: x86: Fix the x86 syscall table production for C++ David Howells
2018-04-02 7:57 ` kbuild test robot
2018-04-01 20:41 ` David Howells [this message]
2018-04-01 20:41 ` [PATCH 11/45] C++: x86: Turn cmpxchg() & co. into inline template functions David Howells
2018-04-01 20:41 ` [PATCH 12/45] C++: x86: Turn cmpxchg_double() " David Howells
2018-04-01 20:41 ` [PATCH 13/45] C++: x86: Turn cmpxchg64() " David Howells
2018-04-01 20:41 ` [PATCH 14/45] C++: x86: Turn put_user(), get_user() " David Howells
2018-04-01 20:41 ` [PATCH 15/45] C++: Need space between string and symbol David Howells
2018-04-01 20:41 ` [PATCH 16/45] C++: Disable VERIFY_OCTAL_PERMISSIONS() for the moment David Howells
2018-04-01 20:41 ` [PATCH 17/45] C++: Turn READ_ONCE(), WRITE_ONCE() & co. into inline template functions David Howells
2018-04-01 20:42 ` [PATCH 18/45] C++: Turn RCU accessors " David Howells
2018-04-01 20:42 ` [PATCH 19/45] C++: Turn ktime_add/sub_ns() " David Howells
2018-04-01 20:42 ` [PATCH 20/45] C++: init/main: Constify pointers David Howells
2018-04-01 20:42 ` [PATCH 21/45] C++: Set the type of atomic64_t to s64 David Howells
2018-04-01 20:42 ` [PATCH 22/45] C++: Define apic_intr_mode after the enum definition, not before David Howells
2018-04-01 20:42 ` [PATCH 23/45] C++: Don't do "extern asmlinkage" David Howells
2018-04-01 20:42 ` [PATCH 24/45] C++: Fix BUILD_BUG_ON_ZERO() David Howells
2018-04-01 20:42 ` [PATCH 25/45] C++: Fix void variables David Howells
2018-04-01 20:42 ` [PATCH 26/45] C++: Can't have variable/member names the same as typedef names David Howells
2018-04-01 20:42 ` [PATCH 27/45] C++: Disable __same_type() for the moment David Howells
2018-04-01 20:43 ` [PATCH 28/45] C++: Move ctx_state enum out of struct context_tracking David Howells
2018-04-01 20:43 ` [PATCH 29/45] C++: Move the print_line_t enum before first use David Howells
2018-04-01 20:43 ` [PATCH 30/45] C++: Include linux/hrtimer.h from linux/timer.h David Howells
2018-04-01 20:43 ` [PATCH 31/45] C++: Avoid using 'compl' and 'and' as names David Howells
2018-04-02 7:57 ` kbuild test robot
2018-04-01 20:43 ` [PATCH 32/45] C++: __to_fd() needs to reduce the size of v for struct fd::flags David Howells
2018-04-01 20:43 ` [PATCH 33/45] C++: Move irqchip_irq_state enum David Howells
2018-04-01 20:43 ` [PATCH 34/45] C++: Fix up use of LIST_POISON* David Howells
2018-04-01 20:43 ` [PATCH 35/45] C++: Fix static_branch_likely/unlikely() David Howells
2018-04-01 20:43 ` [PATCH 36/45] C++: Fix kernfs_type() int->enum David Howells
2018-04-01 20:43 ` [PATCH 37/45] C++: Fix page_zonenum() int->enum David Howells
2018-04-01 20:44 ` [PATCH 38/45] C++: mutex_trylock_recursive_enum() int->enum David Howells
2018-04-01 23:10 ` Randy Dunlap
2018-04-01 20:44 ` [PATCH 39/45] C++: Fix spinlock initialisation David Howells
2018-04-01 20:44 ` [PATCH 40/45] C++: Fix sema_init() David Howells
2018-04-01 20:44 ` [PATCH 41/45] C++: Cast in bitops David Howells
2018-04-02 6:10 ` kbuild test robot
2018-04-01 20:44 ` [PATCH 42/45] C++: Hide C++ keywords David Howells
2018-04-02 7:32 ` kbuild test robot
2018-04-01 20:44 ` [PATCH 43/45] C++: Don't need to declare struct pgd_t after typedef David Howells
2018-04-01 20:44 ` [PATCH 44/45] C++: Can't declare unsized-array in struct cgroup David Howells
2018-04-01 20:44 ` [PATCH 45/45] C++: Move initcall_level_names[] to __initdata section David Howells
2018-04-01 22:20 ` [PATCH 00/45] C++: Convert the kernel to C++ Randy Dunlap
2018-04-02 9:28 ` Vegard Nossum
2024-01-09 19:57 ` H. Peter Anvin
2024-01-09 23:29 ` Andrew Pinski
2024-01-11 21:01 ` Arsen Arsenović
2024-01-10 0:29 ` David Howells
2024-01-10 8:58 ` Jiri Slaby
2024-01-10 13:04 ` Neal Gompa
2024-01-10 15:52 ` Jason Gunthorpe
2024-01-10 16:05 ` H. Peter Anvin
2024-01-10 16:25 ` Neal Gompa
2024-01-10 17:57 ` Theodore Ts'o
2024-01-12 2:23 ` H. Peter Anvin
2024-01-12 2:52 ` Kent Overstreet
2024-01-11 8:06 ` Andreas Herrmann
2024-01-10 15:01 ` Michael de Lang
[not found] ` <69fe1c0c-b5ec-4031-b719-d9c14742929c@metux.net>
2024-01-12 21:58 ` Michael de Lang
2024-01-11 4:24 ` John Hubbard
2024-01-11 5:09 ` Dave Airlie
2024-01-11 15:24 ` Eric Curtin
2024-01-11 21:37 ` David Laight
2024-01-11 12:39 ` Chris Down
2024-01-11 19:40 ` David Laight
2024-01-24 6:53 ` Jiri Slaby
2024-01-12 2:54 ` H. Peter Anvin
2024-01-12 8:52 ` David Howells
2024-01-12 23:53 ` H. Peter Anvin
2024-01-09 23:40 ` David Howells
2024-01-10 7:13 ` Alexey Dobriyan
2024-01-12 2:25 ` H. Peter Anvin
2024-01-12 2:40 ` H. Peter Anvin
2024-01-11 23:09 ` Arsen Arsenović
2024-01-12 9:20 ` David Howells
2024-01-12 21:35 ` Arsen Arsenović
2024-01-12 23:41 ` David Howells
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=152261527543.30503.554397458877242700.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).