hatomic.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #ifndef HV_ATOMIC_H_
  2. #define HV_ATOMIC_H_
  3. #ifdef __cplusplus
  4. // c++11
  5. #include <atomic>
  6. using std::atomic_flag;
  7. using std::atomic_long;
  8. #define ATOMIC_FLAG_TEST_AND_SET(p) ((p)->test_and_set())
  9. #define ATOMIC_FLAG_CLEAR(p) ((p)->clear())
  10. #else
  11. #include "hplatform.h" // for HAVE_STDATOMIC_H
  12. #if HAVE_STDATOMIC_H
  13. // c11
  14. #include <stdatomic.h>
  15. #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
  16. #define ATOMIC_FLAG_CLEAR atomic_flag_clear
  17. #define ATOMIC_ADD atomic_fetch_add
  18. #define ATOMIC_SUB atomic_fetch_sub
  19. #define ATOMIC_INC(p) ATOMIC_ADD(p, 1)
  20. #define ATOMIC_DEC(p) ATOMIC_SUB(p, 1)
  21. #else
  22. typedef volatile bool atomic_bool;
  23. typedef volatile char atomic_char;
  24. typedef volatile unsigned char atomic_uchar;
  25. typedef volatile short atomic_short;
  26. typedef volatile unsigned short atomic_ushort;
  27. typedef volatile int atomic_int;
  28. typedef volatile unsigned int atomic_uint;
  29. typedef volatile long atomic_long;
  30. typedef volatile unsigned long atomic_ulong;
  31. typedef volatile long long atomic_llong;
  32. typedef volatile unsigned long long atomic_ullong;
  33. typedef volatile size_t atomic_size_t;
  34. typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
  35. #ifdef _WIN32
  36. #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
  37. static inline bool atomic_flag_test_and_set(atomic_flag* p) {
  38. // return InterlockedIncrement((LONG*)&p->_Value, 1);
  39. return InterlockedCompareExchange((LONG*)&p->_Value, 1, 0);
  40. }
  41. #define ATOMIC_ADD InterlockedAdd
  42. #define ATOMIC_SUB(p, n) InterlockedAdd(p, -n)
  43. #define ATOMIC_INC InterlockedIncrement
  44. #define ATOMIC_DEC InterlockedDecrement
  45. #elif defined(__GNUC__)
  46. #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
  47. static inline bool atomic_flag_test_and_set(atomic_flag* p) {
  48. return !__sync_bool_compare_and_swap(&p->_Value, 0, 1);
  49. }
  50. #define ATOMIC_ADD __sync_fetch_and_add
  51. #define ATOMIC_SUB __sync_fetch_and_sub
  52. #define ATOMIC_INC(p) ATOMIC_ADD(p, 1)
  53. #define ATOMIC_DEC(p) ATOMIC_SUB(p, 1)
  54. #endif
  55. #endif // HAVE_STDATOMIC_H
  56. #endif // __cplusplus
  57. #ifndef ATOMIC_FLAG_INIT
  58. #define ATOMIC_FLAG_INIT { 0 }
  59. #endif
  60. #ifndef ATOMIC_VAR_INIT
  61. #define ATOMIC_VAR_INIT(value) (value)
  62. #endif
  63. #ifndef ATOMIC_FLAG_TEST_AND_SET
  64. #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
  65. static inline bool atomic_flag_test_and_set(atomic_flag* p) {
  66. bool ret = p->_Value;
  67. p->_Value = 1;
  68. return ret;
  69. }
  70. #endif
  71. #ifndef ATOMIC_FLAG_CLEAR
  72. #define ATOMIC_FLAG_CLEAR atomic_flag_clear
  73. static inline void atomic_flag_clear(atomic_flag* p) {
  74. p->_Value = 0;
  75. }
  76. #endif
  77. #ifndef ATOMIC_ADD
  78. #define ATOMIC_ADD(p, n) (*(p) += (n))
  79. #endif
  80. #ifndef ATOMIC_SUB
  81. #define ATOMIC_SUB(p, n) (*(p) -= (n))
  82. #endif
  83. #ifndef ATOMIC_INC
  84. #define ATOMIC_INC(p) ((*(p))++)
  85. #endif
  86. #ifndef ATOMIC_DEC
  87. #define ATOMIC_DEC(p) ((*(p))--)
  88. #endif
  89. typedef atomic_flag hatomic_flag_t;
  90. #define HATOMIC_FLAG_INIT ATOMIC_FLAG_INIT
  91. #define hatomic_flag_test_and_set ATOMIC_FLAG_TEST_AND_SET
  92. #define hatomic_flag_clear ATOMIC_FLAG_CLEAR
  93. typedef atomic_long hatomic_t;
  94. #define HATOMIC_VAR_INIT ATOMIC_VAR_INIT
  95. #define hatomic_add ATOMIC_ADD
  96. #define hatomic_sub ATOMIC_SUB
  97. #define hatomic_inc ATOMIC_INC
  98. #define hatomic_dec ATOMIC_DEC
  99. #endif // HV_ATOMIC_H_