aboutsummaryrefslogtreecommitdiff
path: root/src/threadpool-atomics.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/threadpool-atomics.h')
-rw-r--r--src/threadpool-atomics.h106
1 files changed, 105 insertions, 1 deletions
diff --git a/src/threadpool-atomics.h b/src/threadpool-atomics.h
index f0ddd89..23f943a 100644
--- a/src/threadpool-atomics.h
+++ b/src/threadpool-atomics.h
@@ -130,7 +130,7 @@
static inline void pthreadpool_fence_release() {
__c11_atomic_thread_fence(__ATOMIC_RELEASE);
}
-#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)
#include <stdatomic.h>
typedef _Atomic(uint32_t) pthreadpool_atomic_uint32_t;
@@ -247,6 +247,110 @@
static inline void pthreadpool_fence_release() {
atomic_thread_fence(memory_order_release);
}
+#elif defined(__GNUC__)
+ typedef uint32_t volatile pthreadpool_atomic_uint32_t;
+ typedef size_t volatile pthreadpool_atomic_size_t;
+ typedef void* volatile pthreadpool_atomic_void_p;
+
+ static inline uint32_t pthreadpool_load_relaxed_uint32_t(
+ pthreadpool_atomic_uint32_t* address)
+ {
+ return *address;
+ }
+
+ static inline size_t pthreadpool_load_relaxed_size_t(
+ pthreadpool_atomic_size_t* address)
+ {
+ return *address;
+ }
+
+ static inline void* pthreadpool_load_relaxed_void_p(
+ pthreadpool_atomic_void_p* address)
+ {
+ return *address;
+ }
+
+ static inline uint32_t pthreadpool_load_acquire_uint32_t(
+ pthreadpool_atomic_uint32_t* address)
+ {
+ return *address;
+ }
+
+ static inline size_t pthreadpool_load_acquire_size_t(
+ pthreadpool_atomic_size_t* address)
+ {
+ return *address;
+ }
+
+ static inline void pthreadpool_store_relaxed_uint32_t(
+ pthreadpool_atomic_uint32_t* address,
+ uint32_t value)
+ {
+ *address = value;
+ }
+
+ static inline void pthreadpool_store_relaxed_size_t(
+ pthreadpool_atomic_size_t* address,
+ size_t value)
+ {
+ *address = value;
+ }
+
+ static inline void pthreadpool_store_relaxed_void_p(
+ pthreadpool_atomic_void_p* address,
+ void* value)
+ {
+ *address = value;
+ }
+
+ static inline void pthreadpool_store_release_uint32_t(
+ pthreadpool_atomic_uint32_t* address,
+ uint32_t value)
+ {
+ *address = value;
+ }
+
+ static inline void pthreadpool_store_release_size_t(
+ pthreadpool_atomic_size_t* address,
+ size_t value)
+ {
+ *address = value;
+ }
+
+ static inline size_t pthreadpool_decrement_fetch_relaxed_size_t(
+ pthreadpool_atomic_size_t* address)
+ {
+ return __sync_sub_and_fetch(address, 1);
+ }
+
+ static inline size_t pthreadpool_decrement_fetch_release_size_t(
+ pthreadpool_atomic_size_t* address)
+ {
+ return __sync_sub_and_fetch(address, 1);
+ }
+
+ static inline bool pthreadpool_try_decrement_relaxed_size_t(
+ pthreadpool_atomic_size_t* value)
+ {
+ size_t actual_value = *value;
+ while (actual_value != 0) {
+ const size_t new_value = actual_value - 1;
+ const size_t expected_value = actual_value;
+ actual_value = __sync_val_compare_and_swap(value, expected_value, new_value);
+ if (actual_value == expected_value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static inline void pthreadpool_fence_acquire() {
+ __sync_synchronize();
+ }
+
+ static inline void pthreadpool_fence_release() {
+ __sync_synchronize();
+ }
#elif defined(_MSC_VER) && defined(_M_X64)
typedef volatile uint32_t pthreadpool_atomic_uint32_t;
typedef volatile size_t pthreadpool_atomic_size_t;