Com: Adjust epicsAtomic conditionals for GCC

cf. https://bugs.launchpad.net/epics-base/+bug/1932118
This commit is contained in:
Michael Davidsaver
2021-06-24 10:05:42 -07:00
committed by Andrew Johnson
parent ec87b2a867
commit 78d2f20fa8
2 changed files with 20 additions and 58 deletions
@@ -23,50 +23,36 @@
#define EPICS_ATOMIC_CMPLR_NAME "GCC"
/* expands __GCC_HAVE_SYNC_COMPARE_AND_SWAP_ concatentating the numeric value __SIZEOF_*__ */
#define GCC_ATOMIC_CONCAT( A, B ) GCC_ATOMIC_CONCATR(A,B)
#define GCC_ATOMIC_CONCATR( A, B ) ( A ## B )
/*
* As of GCC 8, the __sync_synchronize() is inlined for all
* known targets (aarch64, arm, i386, powerpc, and x86_64)
* except for arm <=6.
* Note that i386 inlines __sync_synchronize() but does not
* define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_*
*/
#define GCC_ATOMIC_INTRINSICS_AVAIL_SYNC \
defined(GCC_ATOMIC_INTRINSICS_AVAIL_INT_T) || defined(GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T) || defined(__i386)
#define GCC_ATOMIC_INTRINSICS_AVAIL_INT_T \
GCC_ATOMIC_CONCAT ( \
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_, \
__SIZEOF_INT__ )
/* we assume __SIZEOF_POINTER__ == __SIZEOF_SIZE_T__ */
#define GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T \
GCC_ATOMIC_CONCAT ( \
__GCC_HAVE_SYNC_COMPARE_AND_SWAP_, \
__SIZEOF_SIZE_T__ )
#define GCC_ATOMIC_INTRINSICS_MIN_X86 \
( defined ( __i486 ) || defined ( __pentium ) || \
defined ( __pentiumpro ) || defined ( __MMX__ ) )
#define GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER \
( ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 401 )
#define GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER \
( GCC_ATOMIC_INTRINSICS_MIN_X86 && \
GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER )
#ifdef __cplusplus
extern "C" {
#endif
/*
* We are optimistic that __sync_synchronize is implemented
* in all version four gcc invariant of target. The gnu doc
* seems to say that when not supported by architecture a call
* to an external function is generated but in practice
* this isn`t the case for some of the atomic intrinsics, and
* so there is an undefined symbol. So far we have not seen
* that with __sync_synchronize, but we can only guess based
* on experimental evidence.
*
* For example we know that when generating object code for
* 386 most of the atomic intrinsics are not present and
* we see undefined symbols with mingw, but we don`t have
* troubles with __sync_synchronize.
*/
#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER
#if GCC_ATOMIC_INTRINSICS_AVAIL_SYNC
#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER
#define EPICS_ATOMIC_READ_MEMORY_BARRIER
@@ -84,32 +70,9 @@ EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void)
}
#endif
#else
#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER
#if GCC_ATOMIC_INTRINSICS_MIN_X86
#define EPICS_ATOMIC_READ_MEMORY_BARRIER
EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void)
{
asm("mfence;");
}
#endif
#endif
#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER
#if GCC_ATOMIC_INTRINSICS_MIN_X86
#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER
EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void)
{
asm("mfence;");
}
#endif
#endif
#endif /* if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER */
#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T \
|| GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER
#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T
#define EPICS_ATOMIC_INCR_INTT
EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget )
@@ -136,10 +99,9 @@ EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget,
return __sync_val_compare_and_swap ( pTarget, oldVal, newVal);
}
#endif /* if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T */
#endif
#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T \
|| GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER
#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T
#define EPICS_ATOMIC_INCR_SIZET
EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget )
@@ -180,7 +142,7 @@ EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT (
return __sync_val_compare_and_swap ( pTarget, oldVal, newVal);
}
#endif /* if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T */
#endif
#ifdef __cplusplus
} /* end of extern "C" */
+3 -3
View File
@@ -285,15 +285,15 @@ static void testClassify()
#endif
#ifdef __GNUC__
#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER
#if GCC_ATOMIC_INTRINSICS_AVAIL_SYNC
testDiag("GCC using atomic builtin memory barrier");
#else
testDiag("GCC using asm memory barrier");
#endif
#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER
#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T
testDiag("GCC use builtin for int");
#endif
#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER
#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T
testDiag("GCC use builtin for size_t");
#endif