Kaynağa Gözat

libobs/util: ARM atomic fixes

Use native instructions on ARM64 (dmb is slow).

Use magic number for 32-bit ARM since _ARM64_BARRIER_ISH is for ARM64.
jpark37 4 yıl önce
ebeveyn
işleme
3df4a1109c
1 değiştirilmiş dosya ile 25 ekleme ve 10 silme
  1. 25 10
      libobs/util/threading-windows.h

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

@@ -36,10 +36,12 @@ static inline long os_atomic_dec_long(volatile long *val)
 
 static inline void os_atomic_store_long(volatile long *ptr, long val)
 {
-#if defined(_M_ARM) || defined(_M_ARM64)
-	__dmb(_ARM64_BARRIER_ISH);
+#if defined(_M_ARM64)
+	__stlr32((volatile unsigned *)ptr, val);
+#elif defined(_M_ARM)
+	__dmb(0xB);
 	__iso_volatile_store32((volatile __int32 *)ptr, val);
-	__dmb(_ARM64_BARRIER_ISH);
+	__dmb(0xB);
 #else
 	_InterlockedExchange(ptr, val);
 #endif
@@ -57,13 +59,17 @@ static inline long os_atomic_exchange_long(volatile long *ptr, long val)
 
 static inline long os_atomic_load_long(const volatile long *ptr)
 {
+#if defined(_M_ARM64)
+	return __ldar32((volatile unsigned *)ptr);
+#else
 	const long val = __iso_volatile_load32((const volatile __int32 *)ptr);
-#if defined(_M_ARM) || defined(_M_ARM64)
-	__dmb(_ARM64_BARRIER_ISH);
+#if defined(_M_ARM)
+	__dmb(0xB);
 #else
 	_ReadWriteBarrier();
 #endif
 	return val;
+#endif
 }
 
 static inline bool os_atomic_compare_swap_long(volatile long *val, long old_val,
@@ -84,10 +90,12 @@ static inline bool os_atomic_compare_exchange_long(volatile long *val,
 
 static inline void os_atomic_store_bool(volatile bool *ptr, bool val)
 {
-#if defined(_M_ARM) || defined(_M_ARM64)
-	__dmb(_ARM64_BARRIER_ISH);
+#if defined(_M_ARM64)
+	__stlr8((volatile unsigned char *)ptr, val);
+#elif defined(_M_ARM)
+	__dmb(0xB);
 	__iso_volatile_store8((volatile char *)ptr, val);
-	__dmb(_ARM64_BARRIER_ISH);
+	__dmb(0xB);
 #else
 	_InterlockedExchange8((volatile char *)ptr, (char)val);
 #endif
@@ -111,11 +119,18 @@ static inline bool os_atomic_exchange_bool(volatile bool *ptr, bool val)
 
 static inline bool os_atomic_load_bool(const volatile bool *ptr)
 {
+#if defined(_M_ARM64)
+	const unsigned char u = __ldar8((volatile unsigned char *)ptr);
+	bool b;
+	memcpy(&b, &u, sizeof(b));
+	return b;
+#else
 	const char val = __iso_volatile_load8((const volatile char *)ptr);
-#if defined(_M_ARM) || defined(_M_ARM64)
-	__dmb(_ARM64_BARRIER_ISH);
+#if defined(_M_ARM)
+	__dmb(0xB);
 #else
 	_ReadWriteBarrier();
 #endif
 	return val;
+#endif
 }