$OpenBSD: patch-core_safe_refcount_h,v 1.2 2020/07/19 13:02:38 thfr Exp $

hppa, ppc: use __atomic functions as 64-bit __sync operators
are not supported, from:
https://github.com/godotengine/godot/pull/31321 

Index: core/safe_refcount.h
--- core/safe_refcount.h.orig
+++ core/safe_refcount.h
@@ -55,33 +55,26 @@ static _ALWAYS_INLINE_ T atomic_conditional_increment(
 template <class T>
 static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
 
-	(*pw)--;
-
-	return *pw;
+	return __atomic_sub_fetch(pw, 1, __ATOMIC_SEQ_CST);
 }
 
 template <class T>
 static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
 
-	(*pw)++;
-
-	return *pw;
+	return __atomic_add_fetch(pw, 1, __ATOMIC_SEQ_CST);
 }
 
 template <class T, class V>
 static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
 
-	(*pw) -= val;
 
-	return *pw;
+	return __atomic_sub_fetch(pw, val, __ATOMIC_SEQ_CST);
 }
 
 template <class T, class V>
 static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
 
-	(*pw) += val;
-
-	return *pw;
+	return __atomic_add_fetch(pw, val, __ATOMIC_SEQ_CST);
 }
 
 template <class T, class V>
@@ -97,8 +90,8 @@ static _ALWAYS_INLINE_ T atomic_exchange_if_greater(vo
 
 /* Implementation for GCC & Clang */
 
-// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes.
-// Clang states it supports GCC atomic builtins.
+#include <stdbool.h>
+#include <atomic>
 
 template <class T>
 static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
@@ -107,7 +100,7 @@ static _ALWAYS_INLINE_ T atomic_conditional_increment(
 		T tmp = static_cast<T const volatile &>(*pw);
 		if (tmp == 0)
 			return 0; // if zero, can't add to it anymore
-		if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp)
+		if (__atomic_compare_exchange_n(pw, &tmp, tmp + 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) == true)
 			return tmp + 1;
 	}
 }
@@ -143,7 +136,7 @@ static _ALWAYS_INLINE_ T atomic_exchange_if_greater(vo
 		T tmp = static_cast<T const volatile &>(*pw);
 		if (tmp >= val)
 			return tmp; // already greater, or equal
-		if (__sync_val_compare_and_swap(pw, tmp, val) == tmp)
+		if (__atomic_compare_exchange_n(pw, &tmp, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) == true)
 			return val;
 	}
 }
