Date: Mon, 4 Feb 2002 12:24:44 +0100 (CET) From: Michal Mertl <mime@traveller.cz> To: audit@freebsd.org Cc: jhb@freebsd.org, <peter.jeremy@alcatel.com.au> Subject: request for review: i386 64bit atomic patch Message-ID: <Pine.BSF.4.41.0202041221370.14840-100000@prg.traveller.cz>
next in thread | raw e-mail | index | archive | help
--- atomic.h.ori Sat Feb 2 12:31:36 2002
+++ atomic.h Mon Feb 4 12:08:05 2002
@@ -407,5 +407,162 @@
return (result);
}
#endif /* !defined(WANT_FUNCTIONS) */
+
+#if 1
+#define _ATOMIC_HAVE_QUAD
+#endif
+
+#ifdef _ATOMIC_HAVE_QUAD
+#define atomic_set_acq_64 atomic_set_64
+#define atomic_set_rel_64 atomic_set_64
+#define atomic_clear_acq_64 atomic_clear_64
+#define atomic_clear_rel_64 atomic_clear_64
+#define atomic_add_acq_64 atomic_add_64
+#define atomic_add_rel_64 atomic_add_64
+#define atomic_subtract_acq_64 atomic_subtract_64
+#define atomic_subtract_rel_64 atomic_subtract_64
+#define atomic_cmpset_acq_64 atomic_cmpset_64
+#define atomic_cmpset_rel_64 atomic_cmpset_64
+#define atomic_readandclear_64 atomic_readandclear_64
+
+#if !defined(KLD_MODULE)
+
+static __inline int
+atomic_cmpset_64(volatile u_int64_t *dst, u_int64_t exp, u_int64_t src)
+{
+ int res;
+
+ __asm __volatile (
+ " " MPLOCKED " "
+ " cmpxchg8b %1 ; "
+ " setz %%al ; "
+ " movzbl %%al,%0 ; "
+ "#atomic_cmpset_64"
+ : "=a" (res), /* 0 */
+ "+m" (*(dst)) /* 1 */
+ : "a" ((u_long)exp),
+ "d" ((u_long)((u_long *)&exp)[1]),
+ "b" ((u_long)src),
+ "c" ((u_long)((u_long *)&src)[1])
+ : "memory" );
+ return res;
+}
+
+static __inline void
+atomic_store_rel_64(volatile u_int64_t *p, u_int64_t v)
+{
+ u_int64_t exp, src;
+
+ do {
+ exp = *p;
+ src = v;
+ } while (atomic_cmpset_64(p, exp, src) == 0);
+}
+
+
+static __inline void
+atomic_add_64(volatile u_int64_t *p, u_int64_t v)
+{
+#if 1
+/*
+ * Generic implementation (below) is about 20% slower on p2.
+ * We may need to use this function in time-critical contexts
+ * (e.g. 64-bit counters).
+ */
+ __asm __volatile (
+ " movl (%0),%%eax ; "
+ " movl 4(%0),%%edx ; "
+ " 1:movl (%1),%%ebx ; "
+ " movl 4(%1),%%ecx ; "
+ " addl %%eax,%%ebx ; "
+ " adcl %%edx,%%ecx ; "
+ " " MPLOCKED " "
+ " cmpxchg8b (%0) ; "
+ " jnz 1b ; "
+ "#atomic_add_64"
+ :
+ : "S" (p), /* 0 */
+ "D" (&v) /* 1 */
+ : "eax", "ebx", "ecx", "edx", "memory" );
+#else
+ u_int64_t exp, src;
+
+ do {
+ exp = *p;
+ src = exp + v;
+ } while (atomic_cmpset_64(p, exp, src) == 0);
+#endif
+}
+
+static __inline void
+atomic_subtract_64(volatile u_int64_t *p, u_int64_t v)
+{
+ u_int64_t exp, src;
+
+ do {
+ exp = *p;
+ src = exp - v;
+ } while (atomic_cmpset_64(p, exp, src) == 0);
+}
+
+static __inline void
+atomic_clear_64(volatile u_int64_t *p, u_int64_t v)
+{
+ u_int64_t exp, src, notv = ~v;
+
+ do {
+ exp = *p;
+ src = exp & notv;
+ } while (atomic_cmpset_64(p, exp, src) == 0);
+}
+
+static __inline void
+atomic_set_64(volatile u_int64_t *p, u_int64_t v)
+{
+ u_int64_t exp, src;
+
+ do {
+ exp = *p;
+ src = exp | v;
+ } while (atomic_cmpset_64(p, exp, src) == 0);
+}
+
+static __inline u_int64_t
+atomic_load_acq_64(volatile u_int64_t *p)
+{
+ u_int64_t exp;
+
+ do {
+ exp = *p;
+ } while (atomic_cmpset_64(p, exp, exp) == 0);
+ return (exp);
+}
+
+static __inline u_int64_t
+atomic_readandclear_64(volatile u_int64_t *p)
+{
+ u_int64_t exp;
+
+ do {
+ exp = *p;
+ } while (atomic_cmpset_64(p, exp, 0) == 0);
+ return (exp);
+}
+
+#else /* defined(KLD_MODULE) */
+
+void atomic_set_64(volatile u_int64_t *, u_int64_t);
+void atomic_store_rel_64(volatile u_int64_t *, u_int64_t);
+void atomic_clear_64(volatile u_int64_t *, u_int64_t);
+void atomic_add_64(volatile u_int64_t *, u_int64_t);
+void atomic_subtract_64(volatile u_int64_t *, u_int64_t);
+u_int64_t atomic_load_acq_64(volatile u_int64_t *);
+int atomic_cmpset_64(volatile u_int64_t *,u_int64_t,u_int64_t);
+u_int64_t atomic_readandclear_64(volatile u_int64_t *);
+#endif
+
+#endif /*defined(_ATOMIC_HAVE_QUAD)*/
+
#endif /* !defined(LOCORE) */
+
#endif /* ! _MACHINE_ATOMIC_H_ */
------------
Thank Peter and John for your advices. What do you think now? Can someone
commit it?
--
Michal Mertl
mime@traveller.cz
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.41.0202041221370.14840-100000>
