|
|
@@ -6,6 +6,12 @@
|
|
|
// c++11
|
|
|
#include <atomic>
|
|
|
|
|
|
+using std::atomic_flag;
|
|
|
+using std::atomic_long;
|
|
|
+
|
|
|
+#define ATOMIC_FLAG_TEST_AND_SET(p) ((p)->test_and_set())
|
|
|
+#define ATOMIC_FLAG_CLEAR(p) ((p)->clear())
|
|
|
+
|
|
|
#else
|
|
|
|
|
|
#include "hconfig.h" // for HAVE_STDATOMIC_H
|
|
|
@@ -14,6 +20,13 @@
|
|
|
// c11
|
|
|
#include <stdatomic.h>
|
|
|
|
|
|
+#define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
|
|
|
+#define ATOMIC_FLAG_CLEAR atomic_flag_clear
|
|
|
+#define ATOMIC_ADD atomic_fetch_add
|
|
|
+#define ATOMIC_SUB atomic_fetch_sub
|
|
|
+#define ATOMIC_INC(p) ATOMIC_ADD(p, 1)
|
|
|
+#define ATOMIC_DEC(p) ATOMIC_SUB(p, 1)
|
|
|
+
|
|
|
#else
|
|
|
|
|
|
#include "hplatform.h" // for bool, size_t
|
|
|
@@ -33,56 +46,81 @@ typedef volatile size_t atomic_size_t;
|
|
|
|
|
|
typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
|
|
|
|
|
|
-#define ATOMIC_FLAG_INIT { 0 }
|
|
|
-#define ATOMIC_VAR_INIT(value) (value)
|
|
|
+#ifdef _WIN32
|
|
|
+
|
|
|
+#define ATOMIC_ADD InterlockedAdd
|
|
|
+#define ATOMIC_SUB(p, n) InterlockedAdd(p, -n)
|
|
|
+#define ATOMIC_INC InterlockedIncrement
|
|
|
+#define ATOMIC_DEC InterlockedDecrement
|
|
|
|
|
|
-#ifdef __GNUC__
|
|
|
+#elif defined(__GNUC__)
|
|
|
|
|
|
+#define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
|
|
|
static inline bool atomic_flag_test_and_set(atomic_flag* p) {
|
|
|
return !__sync_bool_compare_and_swap(&p->_Value, 0, 1);
|
|
|
}
|
|
|
|
|
|
-static inline void atomic_flag_clear(atomic_flag* p) {
|
|
|
- p->_Value = 0;
|
|
|
-}
|
|
|
+#define ATOMIC_ADD __sync_fetch_and_add
|
|
|
+#define ATOMIC_SUB __sync_fetch_and_sub
|
|
|
+#define ATOMIC_INC(p) ATOMIC_ADD(p, 1)
|
|
|
+#define ATOMIC_DEC(p) ATOMIC_SUB(p, 1)
|
|
|
+
|
|
|
+#endif
|
|
|
|
|
|
-#define atomic_fetch_add __sync_fetch_and_add
|
|
|
-#define atomic_fetch_sub __sync_fetch_add_sub
|
|
|
+#endif // HAVE_STDATOMIC_H
|
|
|
|
|
|
-#else
|
|
|
+#endif // __cplusplus
|
|
|
+
|
|
|
+#ifndef ATOMIC_FLAG_INIT
|
|
|
+#define ATOMIC_FLAG_INIT { 0 }
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef ATOMIC_VAR_INIT
|
|
|
+#define ATOMIC_VAR_INIT(value) (value)
|
|
|
+#endif
|
|
|
|
|
|
+#ifndef ATOMIC_FLAG_TEST_AND_SET
|
|
|
+#define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
|
|
|
static inline bool atomic_flag_test_and_set(atomic_flag* p) {
|
|
|
bool ret = p->_Value;
|
|
|
p->_Value = 1;
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
+#ifndef ATOMIC_FLAG_CLEAR
|
|
|
+#define ATOMIC_FLAG_CLEAR atomic_flag_clear
|
|
|
static inline void atomic_flag_clear(atomic_flag* p) {
|
|
|
p->_Value = 0;
|
|
|
}
|
|
|
-
|
|
|
-#define atomic_fetch_add(p, n) *(p); *(p) += (n)
|
|
|
-#define atomic_fetch_sub(p, n) *(p); *(p) -= (n)
|
|
|
-
|
|
|
-#endif // __GNUC__
|
|
|
-#endif // HAVE_STDATOMIC_H
|
|
|
+#endif
|
|
|
|
|
|
#ifndef ATOMIC_ADD
|
|
|
-#define ATOMIC_ADD atomic_fetch_add
|
|
|
+#define ATOMIC_ADD(p, n) (*(p) += (n))
|
|
|
#endif
|
|
|
|
|
|
#ifndef ATOMIC_SUB
|
|
|
-#define ATOMIC_SUB atomic_fetch_sub
|
|
|
+#define ATOMIC_SUB(p, n) (*(p) -= (n))
|
|
|
#endif
|
|
|
|
|
|
#ifndef ATOMIC_INC
|
|
|
-#define ATOMIC_INC(p) ATOMIC_ADD(p, 1)
|
|
|
+#define ATOMIC_INC(p) ((*(p))++)
|
|
|
#endif
|
|
|
|
|
|
#ifndef ATOMIC_DEC
|
|
|
-#define ATOMIC_DEC(p) ATOMIC_SUB(p, 1)
|
|
|
+#define ATOMIC_DEC(p) ((*(p))--)
|
|
|
#endif
|
|
|
|
|
|
-#endif // __cplusplus
|
|
|
+typedef atomic_flag hatomic_flag_t;
|
|
|
+#define HATOMIC_FLAG_INIT ATOMIC_FLAG_INIT
|
|
|
+#define hatomic_flag_test_and_set ATOMIC_FLAG_TEST_AND_SET
|
|
|
+#define hatomic_flag_clear ATOMIC_FLAG_CLEAR
|
|
|
+
|
|
|
+typedef atomic_long hatomic_t;
|
|
|
+#define HATOMIC_VAR_INIT ATOMIC_VAR_INIT
|
|
|
+#define hatomic_add ATOMIC_ADD
|
|
|
+#define hatomic_sub ATOMIC_SUB
|
|
|
+#define hatomic_inc ATOMIC_INC
|
|
|
+#define hatomic_dec ATOMIC_DEC
|
|
|
|
|
|
#endif // HV_ATOMIC_H_
|