summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-06-23 02:21:37 +0000
committersephe <sephe@FreeBSD.org>2016-06-23 02:21:37 +0000
commitee9748f41f5818197d95b210279c755ad824dba7 (patch)
tree2a57196e39be8e665ce0e0b939e6b203603778ab /sys/amd64
parentd5f44be4cd4d07380dce8e2eea32f6a97306d468 (diff)
downloadFreeBSD-src-ee9748f41f5818197d95b210279c755ad824dba7.zip
FreeBSD-src-ee9748f41f5818197d95b210279c755ad824dba7.tar.gz
MFC 299912
atomic: Add testandclear on i386/amd64 Reviewed by: kib Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6381
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/include/atomic.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index bb93835..cdcc7b8 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -84,6 +84,8 @@ u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
u_long atomic_fetchadd_long(volatile u_long *p, u_long v);
int atomic_testandset_int(volatile u_int *p, u_int v);
int atomic_testandset_long(volatile u_long *p, u_int v);
+int atomic_testandclear_int(volatile u_int *p, u_int v);
+int atomic_testandclear_long(volatile u_long *p, u_int v);
#define ATOMIC_LOAD(TYPE, LOP) \
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p)
@@ -241,6 +243,40 @@ atomic_testandset_long(volatile u_long *p, u_int v)
return (res);
}
+static __inline int
+atomic_testandclear_int(volatile u_int *p, u_int v)
+{
+ u_char res;
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " btrl %2,%1 ; "
+ " setc %0 ; "
+ "# atomic_testandclear_int"
+ : "=q" (res), /* 0 */
+ "+m" (*p) /* 1 */
+ : "Ir" (v & 0x1f) /* 2 */
+ : "cc");
+ return (res);
+}
+
+static __inline int
+atomic_testandclear_long(volatile u_long *p, u_int v)
+{
+ u_char res;
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " btrq %2,%1 ; "
+ " setc %0 ; "
+ "# atomic_testandclear_long"
+ : "=q" (res), /* 0 */
+ "+m" (*p) /* 1 */
+ : "Jr" ((u_long)(v & 0x3f)) /* 2 */
+ : "cc");
+ return (res);
+}
+
/*
* We assume that a = b will do atomic loads and stores. Due to the
* IA32 memory model, a simple store guarantees release semantics.
@@ -462,6 +498,7 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_readandclear_32 atomic_readandclear_int
#define atomic_fetchadd_32 atomic_fetchadd_int
#define atomic_testandset_32 atomic_testandset_int
+#define atomic_testandclear_32 atomic_testandclear_int
/* Operations on 64-bit quad words. */
#define atomic_set_64 atomic_set_long
@@ -485,6 +522,7 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_readandclear_64 atomic_readandclear_long
#define atomic_fetchadd_64 atomic_fetchadd_long
#define atomic_testandset_64 atomic_testandset_long
+#define atomic_testandclear_64 atomic_testandclear_long
/* Operations on pointers. */
#define atomic_set_ptr atomic_set_long
OpenPOWER on IntegriCloud