diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 7cfdf4d949968..4e4287e834af8 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -3639,21 +3639,33 @@ Define_InterlockMethod( CHAR, InterlockedExchange8(IN OUT CHAR volatile *Target, CHAR Value), InterlockedExchange8(Target, Value), +#ifdef __clang__ + __sync_swap(Target, Value); +#else __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL) +#endif ) Define_InterlockMethod( SHORT, InterlockedExchange16(IN OUT SHORT volatile *Target, SHORT Value), InterlockedExchange16(Target, Value), +#ifdef __clang__ + __sync_swap(Target, Value); +#else __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL) +#endif ) Define_InterlockMethod( LONG, InterlockedExchange(IN OUT LONG volatile *Target, LONG Value), InterlockedExchange(Target, Value), +#ifdef __clang__ + __sync_swap(Target, Value); +#else __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL) +#endif ) #if defined(HOST_X86) @@ -3678,12 +3690,15 @@ Define_InterlockMethod( LONGLONG, InterlockedExchange64(IN OUT LONGLONG volatile *Target, IN LONGLONG Value), InterlockedExchange64(Target, Value), +#ifdef __clang__ + __sync_swap(Target, Value); +#else __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL) +#endif ) #endif - /*++ Function: InterlockedCompareExchange diff --git a/src/coreclr/pal/src/config.h.in b/src/coreclr/pal/src/config.h.in index b5ddd025f3eb1..e47aaa4d8a188 100644 --- a/src/coreclr/pal/src/config.h.in +++ b/src/coreclr/pal/src/config.h.in @@ -98,6 +98,7 @@ #cmakedefine01 HAVE__SC_PHYS_PAGES #cmakedefine01 HAVE__SC_AVPHYS_PAGES +#cmakedefine01 HAVE_LOCKFREE_ATOMICS #cmakedefine01 REALPATH_SUPPORTS_NONEXISTENT_FILES #cmakedefine01 SSCANF_SUPPORT_ll #cmakedefine01 HAVE_LARGE_SNPRINTF_SUPPORT diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index b8cdb3a4df413..ac9702a2f60f9 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -189,6 +189,23 @@ check_cxx_symbol_exists(_DEBUG sys/user.h USER_H_DEFINES_DEBUG) check_cxx_symbol_exists(_SC_PHYS_PAGES unistd.h HAVE__SC_PHYS_PAGES) check_cxx_symbol_exists(_SC_AVPHYS_PAGES unistd.h HAVE__SC_AVPHYS_PAGES) +check_c_source_compiles(" +#include + +int main(void) { +#if defined(__clang__) && __has_builtin(__sync_swap) && __has_builtin(__sync_val_compare_and_swap) + return 0; +#elif ATOMIC_CHAR_LOCK_FREE == 2 && ATOMIC_SHORT_LOCK_FREE == 2 && ATOMIC_INT_LOCK_FREE == 2 && ATOMIC_LLONG_LOCK_FREE == 2 + return 0; +#else +#error CoreCLR requires non-locking atomics +#endif +}" HAVE_LOCKFREE_ATOMICS) + +if(NOT HAVE_LOCKFREE_ATOMICS) +message( FATAL_ERROR "CoreCLR requires non-locking atomics" ) +endif(NOT HAVE_LOCKFREE_ATOMICS) + check_cxx_source_runs(" #include #include