Adjust atomic_cmpset_int/long - Faster version, fix amd64 issue.
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 15 Jul 2009 16:44:22 +0000 (09:44 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 15 Jul 2009 16:44:22 +0000 (09:44 -0700)
* Instead of using the condition code just compare %eax (or %rax)
  against the old value.  This is considerably faster then using
  sete/movzbl and GCC will also optimize the caller's test for
  both 0 or non-zero.

* AMD64.  long is 64 bits, use cmpxchgq (it was previously using cmpxchgl).

sys/cpu/amd64/include/atomic.h
sys/cpu/i386/include/atomic.h

index 25facb4..2f8e7df 100644 (file)
@@ -386,19 +386,22 @@ atomic_cmpset_int(volatile u_int *_dst, u_int _old, u_int _new)
        int res = _old;
 
        __asm __volatile(MPLOCKED "cmpxchgl %2,%1; " \
-                        "setz %%al; " \
-                        "movzbl %%al,%0; " \
                         : "+a" (res), "=m" (*_dst) \
                         : "r" (_new), "m" (*_dst) \
                         : "memory");
-       return res;
+       return (res == _old);
 }
 
-static __inline int
+static __inline long
 atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src)
 {
-        return (atomic_cmpset_int((volatile u_int *)dst, (u_int)exp,
-                                  (u_int)src));
+       int res = _old;
+
+       __asm __volatile(MPLOCKED "cmpxchgq %2,%1; " \
+                        : "+a" (res), "=m" (*_dst) \
+                        : "r" (_new), "m" (*_dst) \
+                        : "memory");
+       return (res == _old);
 }
 
 /*
index 19e6e1f..90ee4a3 100644 (file)
@@ -363,12 +363,10 @@ atomic_cmpset_int(volatile u_int *_dst, u_int _old, u_int _new)
        int res = _old;
 
        __asm __volatile(MPLOCKED "cmpxchgl %2,%1; " \
-                        "setz %%al; " \
-                        "movzbl %%al,%0; " \
                         : "+a" (res), "=m" (*_dst) \
                         : "r" (_new), "m" (*_dst) \
                         : "memory");
-       return res;
+       return (res == _old);
 }
 
 static __inline int