aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/include
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2000-09-06 11:21:14 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2000-09-06 11:21:14 +0000
commit819e370c3b26fcce03dc7d3693e861a522304c95 (patch)
tree815d1ae89da4c2ca0ef5ed3791c4850a6fa0ee65 /sys/amd64/include
parentaada671ef0cc0f7deaf57b36514f6ad3af0566a2 (diff)
Notes
Diffstat (limited to 'sys/amd64/include')
-rw-r--r--sys/amd64/include/atomic.h72
1 files changed, 72 insertions, 0 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index e6af303d3a87..35a710e15542 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -65,9 +65,15 @@
#define ATOMIC_ASM(NAME, TYPE, OP, V) \
extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v);
+extern int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
+
#else /* !KLD_MODULE */
#if defined(SMP)
+#if defined(LOCORE)
+#define MPLOCKED lock ;
+#else
#define MPLOCKED "lock ; "
+#endif
#else
#define MPLOCKED
#endif
@@ -87,6 +93,62 @@ atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
: "0" (*p), "ir" (V)); \
}
+/*
+ * Atomic compare and set, used by the mutex functions
+ *
+ * if (*dst == exp) *dst = src (all 32 bit words)
+ *
+ * Returns 0 on failure, non-zero on success
+ */
+
+#if defined(I386_CPU)
+static __inline int
+atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
+{
+ int res = exp;
+
+ __asm __volatile(
+ " pushfl ; "
+ " cli ; "
+ " cmpl %1,%3 ; "
+ " jne 1f ; "
+ " movl %2,%3 ; "
+ "1: "
+ " sete %%al; "
+ " movzbl %%al,%0 ; "
+ " popfl ; "
+ "# atomic_cmpset_int"
+ : "=a" (res) /* 0 (result) */
+ : "0" (exp), /* 1 */
+ "r" (src), /* 2 */
+ "m" (*(dst)) /* 3 */
+ : "memory");
+
+ return (res);
+}
+#else /* defined(I386_CPU) */
+static __inline int
+atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
+{
+ int res = exp;
+
+ __asm __volatile (
+ " " MPLOCKED " "
+ " cmpxchgl %2,%3 ; "
+ " setz %%al ; "
+ " movzbl %%al,%0 ; "
+ "1: "
+ "# atomic_cmpset_int"
+ : "=a" (res) /* 0 (result) */
+ : "0" (exp), /* 1 */
+ "r" (src), /* 2 */
+ "m" (*(dst)) /* 3 */
+ : "memory");
+
+ return (res);
+}
+#endif /* defined(I386_CPU) */
+
#else
/* gcc <= 2.8 version */
#define ATOMIC_ASM(NAME, TYPE, OP, V) \
@@ -148,4 +210,14 @@ ATOMIC_ASM(subtract, long, "subl %1,%0", v)
#endif
+#ifndef WANT_FUNCTIONS
+static __inline int
+atomic_cmpset_ptr(volatile void *dst, void *exp, void *src)
+{
+
+ return (
+ atomic_cmpset_int((volatile u_int *)dst, (u_int)exp, (u_int)src));
+}
+#endif
+
#endif /* ! _MACHINE_ATOMIC_H_ */