svn commit: r252413 - head/sys/sys
Ed Schouten
ed at FreeBSD.org
Sun Jun 30 10:38:21 UTC 2013
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) \
More information about the svn-src-all
mailing list