]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2584. [bug] alpha: gcc optimization could break atomic operations.
authorTatuya JINMEI 神明達哉 <jinmei@isc.org>
Wed, 8 Apr 2009 05:49:44 +0000 (05:49 +0000)
committerTatuya JINMEI 神明達哉 <jinmei@isc.org>
Wed, 8 Apr 2009 05:49:44 +0000 (05:49 +0000)
[RT #19227]

CHANGES
lib/isc/alpha/include/isc/atomic.h

diff --git a/CHANGES b/CHANGES
index fe6810b9a8d565ce026d5e7f7a489578d7ce6496..93fc5c6fdd4d5e812cd5ea29f5eea67de04415e8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2584.  [bug]           alpha: gcc optimization could break atomic operations.
+                       [RT #19227]
+
 2583.  [port]          netbsd: provide a control to not add the compile
                        date to the version string, -DNO_VERSION_DATE.
 
index 8e9584650c52c32b6c74ea770b721c1232b3f89b..7c93d5847d16d9cf8c4fd9326b315d32e5be5fb3 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: atomic.h,v 1.2.2.2 2005/06/16 22:01:01 jinmei Exp $ */
+/* $Id: atomic.h,v 1.2.2.3 2009/04/08 05:49:44 jinmei Exp $ */
 
 /*
  * This code was written based on FreeBSD's kernel source whose copyright
 
 /*
  * This routine atomically increments the value stored in 'p' by 'val', and
- * returns the previous value.
+ * returns the previous value.  Memory access ordering around this function
+ * can be critical, so we add explicit memory block instructions at the
+ * beginning and the end of it (same for other functions).
  */
 static inline isc_int32_t 
 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
-       return (asm("1:"
+       return (asm("mb;"
+                   "1:"
                    "ldl_l %t0, 0(%a0);"        /* load old value */
                    "mov %t0, %v0;"             /* copy the old value */
                    "addl %t0, %a1, %t0;"       /* calculate new value */
                    "stl_c %t0, 0(%a0);"        /* attempt to store */
-                   "beq %t0, 1b;",             /* spin if failed */
+                   "beq %t0, 1b;"              /* spin if failed */
+                   "mb;",
                    p, val));
 }
 
@@ -80,11 +84,13 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
  */
 static inline void
 isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
-       (void)asm("1:"
+       (void)asm("mb;"
+                 "1:"
                  "ldl_l %t0, 0(%a0);"          /* load old value */
                  "mov %a1, %t0;"               /* value to store */
                  "stl_c %t0, 0(%a0);"          /* attempt to store */
-                 "beq %t0, 1b;",               /* spin if failed */
+                 "beq %t0, 1b;"                /* spin if failed */
+                 "mb;",
                  p, val);
 }
 
@@ -96,7 +102,8 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
 static inline isc_int32_t
 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
 
-       return(asm("1:"
+       return(asm("mb;"
+                  "1:"
                   "ldl_l %t0, 0(%a0);"         /* load old value */
                   "mov %t0, %v0;"              /* copy the old value */
                   "cmpeq %t0, %a1, %t0;"       /* compare */
@@ -104,7 +111,8 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
                   "mov %a2, %t0;"              /* value to store */
                   "stl_c %t0, 0(%a0);"         /* attempt to store */
                   "beq %t0, 1b;"               /* if it failed, spin */
-                  "2:",
+                  "2:"
+                  "mb;",
                   p, cmpval, val));
 }
 #elif defined (ISC_PLATFORM_USEGCCASM)
@@ -113,13 +121,15 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
        isc_int32_t temp, prev;
 
        __asm__ volatile(
+               "mb;"
                "1:"
                "ldl_l %0, %1;"                 /* load old value */
                "mov %0, %2;"                   /* copy the old value */
                "addl %0, %3, %0;"              /* calculate new value */
                "stl_c %0, %1;"                 /* attempt to store */
                "beq %0, 1b;"                   /* spin if failed */
-               : "=&r"(temp), "+m"(*p), "=r"(prev)
+               "mb;"
+               : "=&r"(temp), "+m"(*p), "=&r"(prev)
                : "r"(val)
                : "memory");
 
@@ -131,11 +141,13 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
        isc_int32_t temp;
 
        __asm__ volatile(
+               "mb;"
                "1:"
                "ldl_l %0, %1;"                 /* load old value */
                "mov %2, %0;"                   /* value to store */
                "stl_c %0, %1;"                 /* attempt to store */
                "beq %0, 1b;"                   /* if it failed, spin */
+               "mb;"
                : "=&r"(temp), "+m"(*p)
                : "r"(val)
                : "memory");
@@ -146,6 +158,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
        isc_int32_t temp, prev;
 
        __asm__ volatile(
+               "mb;"
                "1:"
                "ldl_l %0, %1;"                 /* load old value */
                "mov %0, %2;"                   /* copy the old value */
@@ -155,7 +168,8 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
                "stl_c %0, %1;"                 /* attempt to store */
                "beq %0, 1b;"                   /* if it failed, spin */
                "2:"
-               : "=&r"(temp), "+m"(*p), "=r"(prev)
+               "mb;"
+               : "=&r"(temp), "+m"(*p), "=&r"(prev)
                : "r"(cmpval), "r"(val)
                : "memory");