Author: ed
Date: Sun Jun 30 10:38:20 2013
New Revision: 252413
URL: http://svnweb.freebsd.org/changeset/base/252413

Log:
  Make atomic_fetch_add() and atomic_fetch_sub() work for pointers with GCC 4.2.
  
  According to the standard, atomic_fetch_*() has to behave identical to
  regular arithmetic. This means that for pointer types, we have to apply
  the stride when doing addition/subtraction.
  
  The GCC documentation seems to imply this is done for __sync_*() as
  well. Unfortunately, both tests and Googling seems to reveal this is not
  really the case. Fix this by performing the multiplication with the
  stride manually.

Modified:
  head/sys/sys/stdatomic.h

Modified: head/sys/sys/stdatomic.h
==============================================================================
--- head/sys/sys/stdatomic.h    Sun Jun 30 08:59:33 2013        (r252412)
+++ head/sys/sys/stdatomic.h    Sun Jun 30 10:38:20 2013        (r252413)
@@ -281,6 +281,8 @@ typedef _Atomic(__uintmax_t)                atomic_uin
 #define        atomic_store_explicit(object, desired, order)                   
\
        __atomic_store_n(&(object)->__val, desired, order)
 #else
+#define        __atomic_apply_stride(object, operand) \
+       (((__typeof__((object)->__val))0) + (operand))
 #define        atomic_compare_exchange_strong_explicit(object, expected,       
\
     desired, success, failure) __extension__ ({                        \
        __typeof__(expected) __ep = (expected);                         \
@@ -313,13 +315,15 @@ __extension__ ({                                          
        \
 })
 #endif
 #define        atomic_fetch_add_explicit(object, operand, order)               
\
-       ((void)(order), __sync_fetch_and_add(&(object)->__val, operand))
+       ((void)(order), __sync_fetch_and_add(&(object)->__val,          \
+           __atomic_apply_stride(object, operand)))
 #define        atomic_fetch_and_explicit(object, operand, order)               
\
        ((void)(order), __sync_fetch_and_and(&(object)->__val, operand))
 #define        atomic_fetch_or_explicit(object, operand, order)                
\
        ((void)(order), __sync_fetch_and_or(&(object)->__val, operand))
 #define        atomic_fetch_sub_explicit(object, operand, order)               
\
-       ((void)(order), __sync_fetch_and_sub(&(object)->__val, operand))
+       ((void)(order), __sync_fetch_and_sub(&(object)->__val,          \
+           __atomic_apply_stride(object, operand)))
 #define        atomic_fetch_xor_explicit(object, operand, order)               
\
        ((void)(order), __sync_fetch_and_xor(&(object)->__val, operand))
 #define        atomic_load_explicit(object, order)                             
\
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to