]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Avoid misaligned atomic operations
authorAndrew Waterman <waterman@cs.berkeley.edu>
Wed, 21 Jan 2015 17:20:05 +0000 (17:20 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 21 Jan 2015 17:20:05 +0000 (09:20 -0800)
 Andrew Waterman <waterman@cs.berkeley.edu>

 * fop_n.c (libat_fetch_op): Align address to word boundary.
 (libat_op_fetch): Likewise.

From-SVN: r219956

libatomic/ChangeLog
libatomic/fop_n.c

index 1630dc0d84c74bf390c12a38009f6d42bd50b79d..858b6ea896060f90cfcb058c41d6060e0242da76 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-21  Andrew Waterman <waterman@cs.berkeley.edu>
+
+       * fop_n.c (libat_fetch_op): Align address to word boundary.
+       (libat_op_fetch): Likewise.
+
 2014-12-19  Release Manager
 
        * GCC 4.8.4 released.
index 5e4b224aa5a43bfe49148f59e36d84bbeb65287e..2328e52e6d1a58edb0c0f8846249e3b56965be0f 100644 (file)
@@ -112,9 +112,9 @@ SIZE(C2(libat_fetch_,NAME)) (UTYPE *mptr, UTYPE opval, int smodel)
 
   pre_barrier (smodel);
 
-  wptr = (UWORD *)mptr;
-  shift = 0;
-  mask = -1;
+  wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
+  shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ SIZE(INVERT_MASK);
+  mask = SIZE(MASK) << shift;
 
   wopval = (UWORD)opval << shift;
   woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);
@@ -136,9 +136,9 @@ SIZE(C3(libat_,NAME,_fetch)) (UTYPE *mptr, UTYPE opval, int smodel)
 
   pre_barrier (smodel);
 
-  wptr = (UWORD *)mptr;
-  shift = 0;
-  mask = -1;
+  wptr = (UWORD *)((uintptr_t)mptr & -WORDSIZE);
+  shift = (((uintptr_t)mptr % WORDSIZE) * CHAR_BIT) ^ SIZE(INVERT_MASK);
+  mask = SIZE(MASK) << shift;
 
   wopval = (UWORD)opval << shift;
   woldval = __atomic_load_n (wptr, __ATOMIC_RELAXED);