Преглед изворни кода

libobs/util: Compiler barriers for ARM64 atomics

Unsure if the intrinsics imply ordering. Safer to assume they don't.
jpark37 пре 4 година
родитељ
комит
a20b4c67eb
1 измењених фајлова са 10 додато и 3 уклоњено
  1. 10 3
      libobs/util/threading-windows.h

+ 10 - 3
libobs/util/threading-windows.h

@@ -37,7 +37,9 @@ static inline long os_atomic_dec_long(volatile long *val)
 static inline void os_atomic_store_long(volatile long *ptr, long val)
 static inline void os_atomic_store_long(volatile long *ptr, long val)
 {
 {
 #if defined(_M_ARM64)
 #if defined(_M_ARM64)
+	_ReadWriteBarrier();
 	__stlr32((volatile unsigned *)ptr, val);
 	__stlr32((volatile unsigned *)ptr, val);
+	_ReadWriteBarrier();
 #elif defined(_M_ARM)
 #elif defined(_M_ARM)
 	__dmb(_ARM_BARRIER_ISH);
 	__dmb(_ARM_BARRIER_ISH);
 	__iso_volatile_store32((volatile __int32 *)ptr, val);
 	__iso_volatile_store32((volatile __int32 *)ptr, val);
@@ -60,16 +62,18 @@ static inline long os_atomic_exchange_long(volatile long *ptr, long val)
 static inline long os_atomic_load_long(const volatile long *ptr)
 static inline long os_atomic_load_long(const volatile long *ptr)
 {
 {
 #if defined(_M_ARM64)
 #if defined(_M_ARM64)
-	return __ldar32((volatile unsigned *)ptr);
+	const long val = __ldar32((volatile unsigned *)ptr);
 #else
 #else
 	const long val = __iso_volatile_load32((const volatile __int32 *)ptr);
 	const long val = __iso_volatile_load32((const volatile __int32 *)ptr);
+#endif
+
 #if defined(_M_ARM)
 #if defined(_M_ARM)
 	__dmb(_ARM_BARRIER_ISH);
 	__dmb(_ARM_BARRIER_ISH);
 #else
 #else
 	_ReadWriteBarrier();
 	_ReadWriteBarrier();
 #endif
 #endif
+
 	return val;
 	return val;
-#endif
 }
 }
 
 
 static inline bool os_atomic_compare_swap_long(volatile long *val, long old_val,
 static inline bool os_atomic_compare_swap_long(volatile long *val, long old_val,
@@ -91,7 +95,9 @@ static inline bool os_atomic_compare_exchange_long(volatile long *val,
 static inline void os_atomic_store_bool(volatile bool *ptr, bool val)
 static inline void os_atomic_store_bool(volatile bool *ptr, bool val)
 {
 {
 #if defined(_M_ARM64)
 #if defined(_M_ARM64)
+	_ReadWriteBarrier();
 	__stlr8((volatile unsigned char *)ptr, val);
 	__stlr8((volatile unsigned char *)ptr, val);
+	_ReadWriteBarrier();
 #elif defined(_M_ARM)
 #elif defined(_M_ARM)
 	__dmb(_ARM_BARRIER_ISH);
 	__dmb(_ARM_BARRIER_ISH);
 	__iso_volatile_store8((volatile char *)ptr, val);
 	__iso_volatile_store8((volatile char *)ptr, val);
@@ -125,11 +131,12 @@ static inline bool os_atomic_load_bool(const volatile bool *ptr)
 	const unsigned char c = __ldar8((volatile unsigned char *)ptr);
 	const unsigned char c = __ldar8((volatile unsigned char *)ptr);
 #else
 #else
 	const char c = __iso_volatile_load8((const volatile char *)ptr);
 	const char c = __iso_volatile_load8((const volatile char *)ptr);
+#endif
+
 #if defined(_M_ARM)
 #if defined(_M_ARM)
 	__dmb(_ARM_BARRIER_ISH);
 	__dmb(_ARM_BARRIER_ISH);
 #else
 #else
 	_ReadWriteBarrier();
 	_ReadWriteBarrier();
-#endif
 #endif
 #endif
 
 
 	/* Avoid unnecesary char to bool conversion. Value known 0 or 1. */
 	/* Avoid unnecesary char to bool conversion. Value known 0 or 1. */