summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2018-02-25 10:14:35 +0000
committerhselasky <hselasky@FreeBSD.org>2018-02-25 10:14:35 +0000
commitfb5781987c0f951fabcb92ba190d03030fc7df77 (patch)
treeb4e28e00939940a3d1497ab90b349dd8da307a3c
parentcdf8c6144ce326759989ebcbc0d9b5195bd4f811 (diff)
downloadFreeBSD-src-fb5781987c0f951fabcb92ba190d03030fc7df77.zip
FreeBSD-src-fb5781987c0f951fabcb92ba190d03030fc7df77.tar.gz
MFC r329371:
Allow the cmpxchg() macro in the LinuxKPI to work on pointers without generating compiler warnings, -Wint-conversion . Requested by: Johannes Lundberg <johalun0@gmail.com> Sponsored by: Mellanox Technologies
-rw-r--r--sys/compat/linuxkpi/common/include/asm/atomic.h65
1 files changed, 35 insertions, 30 deletions
diff --git a/sys/compat/linuxkpi/common/include/asm/atomic.h b/sys/compat/linuxkpi/common/include/asm/atomic.h
index 7f25319..8ff0184 100644
--- a/sys/compat/linuxkpi/common/include/asm/atomic.h
+++ b/sys/compat/linuxkpi/common/include/asm/atomic.h
@@ -159,36 +159,41 @@ atomic_cmpxchg(atomic_t *v, int old, int new)
return (ret);
}
-#define cmpxchg(ptr, old, new) ({ \
- __typeof(*(ptr)) __ret; \
- \
- CTASSERT(sizeof(__ret) == 1 || sizeof(__ret) == 2 || \
- sizeof(__ret) == 4 || sizeof(__ret) == 8); \
- \
- __ret = (old); \
- switch (sizeof(__ret)) { \
- case 1: \
- while (!atomic_fcmpset_8((volatile int8_t *)(ptr), \
- (int8_t *)&__ret, (new)) && __ret == (old)) \
- ; \
- break; \
- case 2: \
- while (!atomic_fcmpset_16((volatile int16_t *)(ptr), \
- (int16_t *)&__ret, (new)) && __ret == (old)) \
- ; \
- break; \
- case 4: \
- while (!atomic_fcmpset_32((volatile int32_t *)(ptr), \
- (int32_t *)&__ret, (new)) && __ret == (old)) \
- ; \
- break; \
- case 8: \
- while (!atomic_fcmpset_64((volatile int64_t *)(ptr), \
- (int64_t *)&__ret, (new)) && __ret == (old)) \
- ; \
- break; \
- } \
- __ret; \
+#define cmpxchg(ptr, old, new) ({ \
+ union { \
+ __typeof(*(ptr)) val; \
+ u8 u8[]; \
+ u16 u16[]; \
+ u32 u32[]; \
+ u64 u64[]; \
+ } __ret = { .val = (old) }, __new = { .val = (new) }; \
+ \
+ CTASSERT(sizeof(__ret.val) == 1 || sizeof(__ret.val) == 2 || \
+ sizeof(__ret.val) == 4 || sizeof(__ret.val) == 8); \
+ \
+ switch (sizeof(__ret.val)) { \
+ case 1: \
+ while (!atomic_fcmpset_8((volatile u8 *)(ptr), \
+ __ret.u8, __new.u8[0]) && __ret.val == (old)) \
+ ; \
+ break; \
+ case 2: \
+ while (!atomic_fcmpset_16((volatile u16 *)(ptr), \
+ __ret.u16, __new.u16[0]) && __ret.val == (old)) \
+ ; \
+ break; \
+ case 4: \
+ while (!atomic_fcmpset_32((volatile u32 *)(ptr), \
+ __ret.u32, __new.u32[0]) && __ret.val == (old)) \
+ ; \
+ break; \
+ case 8: \
+ while (!atomic_fcmpset_64((volatile u64 *)(ptr), \
+ __ret.u64, __new.u64[0]) && __ret.val == (old)) \
+ ; \
+ break; \
+ } \
+ __ret.val; \
})
#define cmpxchg_relaxed(...) cmpxchg(__VA_ARGS__)
OpenPOWER on IntegriCloud