diff options
author | attilio <attilio@FreeBSD.org> | 2009-10-09 15:51:40 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2009-10-09 15:51:40 +0000 |
commit | 615a58802f06ef3e957ea7ecc91290dbcc5b0157 (patch) | |
tree | d6ad44aa37bf891c77a3d73ac0b8862e1d1ec5d1 /sys/amd64/include | |
parent | 98d1caad622f502d371da7167c39347470e2d3a7 (diff) | |
download | FreeBSD-src-615a58802f06ef3e957ea7ecc91290dbcc5b0157.zip FreeBSD-src-615a58802f06ef3e957ea7ecc91290dbcc5b0157.tar.gz |
atomic_cmpset_barr_* was added in order to cope with compilers willing to
specify their own version of atomic_cmpset_* which could have been
different than the membar version.
Right now, however, FreeBSD is bound mostly to GCC-like compilers and
it is desired to add new support and compat shim mostly when there is
a real necessity, in order to avoid too much compatibility bloats.
In this optic, bring back atomic_cmpset_{acq, rel}_* to be the same as
atomic_cmpset_* and unwind the atomic_cmpset_barr_* introduction.
Requested by: jhb
Reviewed by: jhb
Tested by: Giovanni Trematerra <giovanni dot trematerra at
gmail dot com>
Diffstat (limited to 'sys/amd64/include')
-rw-r--r-- | sys/amd64/include/atomic.h | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index 7d7199c..a2bd930 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -78,8 +78,6 @@ void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src); int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src); -int atomic_cmpset_barr_int(volatile u_int *dst, u_int exp, u_int src); -int atomic_cmpset_barr_long(volatile u_long *dst, u_long exp, u_long src); u_int atomic_fetchadd_int(volatile u_int *p, u_int v); u_long atomic_fetchadd_long(volatile u_long *p, u_long v); @@ -131,33 +129,47 @@ struct __hack * Returns 0 on failure, non-zero on success */ -#define DEFINE_CMPSET_GEN(NAME, TYPE, OP) \ -static __inline int \ -atomic_cmpset_##NAME(volatile u_##TYPE *dst, u_##TYPE exp, u_##TYPE src)\ -{ \ - u_char res; \ - \ - __asm __volatile( \ - " " MPLOCKED " " \ - " " OP " %2,%1 ; " \ - " sete %0 ; " \ - "1: " \ - "# atomic_cmpset_##NAME" \ - : "=a" (res), /* 0 */ \ - "=m" (*dst) /* 1 */ \ - : "r" (src), /* 2 */ \ - "a" (exp), /* 3 */ \ - "m" (*dst) /* 4 */ \ - : "memory"); \ - \ - return (res); \ -} \ -struct __hack +static __inline int +atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src) +{ + u_char res; + + __asm __volatile( + " " MPLOCKED " " + " cmpxchgl %2,%1 ; " + " sete %0 ; " + "1: " + "# atomic_cmpset_int" + : "=a" (res), /* 0 */ + "=m" (*dst) /* 1 */ + : "r" (src), /* 2 */ + "a" (exp), /* 3 */ + "m" (*dst) /* 4 */ + : "memory"); + + return (res); +} + +static __inline int +atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src) +{ + u_char res; -DEFINE_CMPSET_GEN(int, int, "cmpxchgl"); -DEFINE_CMPSET_GEN(long, long, "cmpxchgq"); -DEFINE_CMPSET_GEN(barr_int, int, "cmpxchgl"); -DEFINE_CMPSET_GEN(barr_long, long, "cmpxchgq"); + __asm __volatile( + " " MPLOCKED " " + " cmpxchgq %2,%1 ; " + " sete %0 ; " + "1: " + "# atomic_cmpset_long" + : "=a" (res), /* 0 */ + "=m" (*dst) /* 1 */ + : "r" (src), /* 2 */ + "a" (exp), /* 3 */ + "m" (*dst) /* 4 */ + : "memory"); + + return (res); +} /* * Atomically add the value of v to the integer pointed to by p and return @@ -358,8 +370,8 @@ u_long atomic_readandclear_long(volatile u_long *addr); #define atomic_add_rel_int atomic_add_barr_int #define atomic_subtract_acq_int atomic_subtract_barr_int #define atomic_subtract_rel_int atomic_subtract_barr_int -#define atomic_cmpset_acq_int atomic_cmpset_barr_int -#define atomic_cmpset_rel_int atomic_cmpset_barr_int +#define atomic_cmpset_acq_int atomic_cmpset_int +#define atomic_cmpset_rel_int atomic_cmpset_int #define atomic_set_acq_long atomic_set_barr_long #define atomic_set_rel_long atomic_set_barr_long @@ -369,8 +381,8 @@ u_long atomic_readandclear_long(volatile u_long *addr); #define atomic_add_rel_long atomic_add_barr_long #define atomic_subtract_acq_long atomic_subtract_barr_long #define atomic_subtract_rel_long atomic_subtract_barr_long -#define atomic_cmpset_acq_long atomic_cmpset_barr_long -#define atomic_cmpset_rel_long atomic_cmpset_barr_long +#define atomic_cmpset_acq_long atomic_cmpset_long +#define atomic_cmpset_rel_long atomic_cmpset_long /* Operations on 8-bit bytes. */ #define atomic_set_8 atomic_set_char |