summaryrefslogtreecommitdiff
path: root/src/gc/env
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc/env')
-rw-r--r--src/gc/env/gcenv.base.h28
-rw-r--r--src/gc/env/gcenv.interlocked.inl6
2 files changed, 26 insertions, 8 deletions
diff --git a/src/gc/env/gcenv.base.h b/src/gc/env/gcenv.base.h
index 351f4f300a..e99149eb6f 100644
--- a/src/gc/env/gcenv.base.h
+++ b/src/gc/env/gcenv.base.h
@@ -14,13 +14,17 @@
#define REDHAWK_PALIMPORT extern "C"
#define REDHAWK_PALAPI __stdcall
+#if !defined(_MSC_VER)
+#define _alloca alloca
+#endif //_MSC_VER
+
#ifndef _MSC_VER
#define __stdcall
-#ifdef __clang__
+#ifdef __GNUC__
#define __forceinline __attribute__((always_inline)) inline
-#else // __clang__
+#else // __GNUC__
#define __forceinline inline
-#endif // __clang__
+#endif // __GNUC__
// [LOCALGC TODO] is there a better place for this?
#define NOINLINE __attribute__((noinline))
#else // !_MSC_VER
@@ -178,18 +182,26 @@ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(void* lpThreadParameter);
#endif
#else // _MSC_VER
+#ifdef __llvm__
+#define HAS_IA32_PAUSE __has_builtin(__builtin_ia32_pause)
+#define HAS_IA32_MFENCE __has_builtin(__builtin_ia32_mfence)
+#else
+#define HAS_IA32_PAUSE 0
+#define HAS_IA32_MFENCE 0
+#endif
+
// Only clang defines __has_builtin, so we first test for a GCC define
// before using __has_builtin.
#if defined(__i386__) || defined(__x86_64__)
-#if (__GNUC__ > 4 && __GNUC_MINOR > 7) || __has_builtin(__builtin_ia32_pause)
+#if (__GNUC__ > 4 && __GNUC_MINOR > 7) || HAS_IA32_PAUSE
// clang added this intrinsic in 3.8
// gcc added this intrinsic by 4.7.1
#define YieldProcessor __builtin_ia32_pause
#endif // __has_builtin(__builtin_ia32_pause)
-#if defined(__GNUC__) || __has_builtin(__builtin_ia32_mfence)
+#if defined(__GNUC__) || HAS_IA32_MFENCE
// clang has had this intrinsic since at least 3.0
// gcc has had this intrinsic since forever
#define MemoryBarrier __builtin_ia32_mfence
@@ -455,7 +467,13 @@ typedef DPTR(uint8_t) PTR_uint8_t;
#define DATA_ALIGNMENT sizeof(uintptr_t)
#define RAW_KEYWORD(x) x
+
+#ifdef _MSC_VER
#define DECLSPEC_ALIGN(x) __declspec(align(x))
+#else
+#define DECLSPEC_ALIGN(x) __attribute__((aligned(x)))
+#endif
+
#ifndef _ASSERTE
#define _ASSERTE(_expr) ASSERT(_expr)
#endif
diff --git a/src/gc/env/gcenv.interlocked.inl b/src/gc/env/gcenv.interlocked.inl
index 3eaaa3ae59..1df2700d7f 100644
--- a/src/gc/env/gcenv.interlocked.inl
+++ b/src/gc/env/gcenv.interlocked.inl
@@ -70,7 +70,7 @@ __forceinline T Interlocked::Exchange(T volatile *destination, T value)
static_assert(sizeof(long) == sizeof(T), "Size of long must be the same as size of T");
return _InterlockedExchange((long*)destination, value);
#else
- T result = __sync_swap(destination, value);
+ T result = __atomic_exchange_n(destination, value, __ATOMIC_ACQ_REL);
ArmInterlockedOperationBarrier();
return result;
#endif
@@ -164,7 +164,7 @@ __forceinline T Interlocked::ExchangePointer(T volatile * destination, T value)
return (T)(TADDR)_InterlockedExchange((long volatile *)(void* volatile *)destination, (long)(void*)value);
#endif
#else
- T result = (T)(TADDR)__sync_swap((void* volatile *)destination, value);
+ T result = (T)(TADDR)__atomic_exchange_n((void* volatile *)destination, value, __ATOMIC_ACQ_REL);
ArmInterlockedOperationBarrier();
return result;
#endif
@@ -180,7 +180,7 @@ __forceinline T Interlocked::ExchangePointer(T volatile * destination, std::null
return (T)(TADDR)_InterlockedExchange((long volatile *)(void* volatile *)destination, (long)(void*)value);
#endif
#else
- T result = (T)(TADDR)__sync_swap((void* volatile *)destination, value);
+ T result = (T)(TADDR)__atomic_exchange_n((void* volatile *)destination, value, __ATOMIC_ACQ_REL);
ArmInterlockedOperationBarrier();
return result;
#endif