atomic.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #ifndef _GENERIC_ATOMIC_H
  2. #define _GENERIC_ATOMIC_H
  3. /* Check GCC version, just to be safe */
  4. #if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 1)
  5. # error atomic.h works only with GCC newer than version 4.1
  6. #endif /* GNUC >= 4.1 */
  7. /**
  8. * Atomic type.
  9. */
  10. typedef struct {
  11. volatile int counter;
  12. } atomic_t;
  13. #define ATOMIC_INIT(i) { (i) }
  14. /**
  15. * Read atomic variable
  16. * @param v pointer of type atomic_t
  17. *
  18. * Atomically reads the value of @v.
  19. */
  20. #define atomic_read(v) ((v)->counter)
  21. /**
  22. * Set atomic variable
  23. * @param v pointer of type atomic_t
  24. * @param i required value
  25. */
  26. #define atomic_set(v,i) (((v)->counter) = (i))
  27. /**
  28. * Add to the atomic variable
  29. * @param i integer value to add
  30. * @param v pointer of type atomic_t
  31. */
  32. static inline void atomic_add( int i, atomic_t *v )
  33. {
  34. (void)__sync_add_and_fetch(&v->counter, i);
  35. }
  36. /**
  37. * Subtract the atomic variable
  38. * @param i integer value to subtract
  39. * @param v pointer of type atomic_t
  40. *
  41. * Atomically subtracts @i from @v.
  42. */
  43. static inline void atomic_sub( int i, atomic_t *v )
  44. {
  45. (void)__sync_sub_and_fetch(&v->counter, i);
  46. }
  47. /**
  48. * Subtract value from variable and test result
  49. * @param i integer value to subtract
  50. * @param v pointer of type atomic_t
  51. *
  52. * Atomically subtracts @i from @v and returns
  53. * true if the result is zero, or false for all
  54. * other cases.
  55. */
  56. static inline int atomic_sub_and_test( int i, atomic_t *v )
  57. {
  58. return !(__sync_sub_and_fetch(&v->counter, i));
  59. }
  60. /**
  61. * Increment atomic variable
  62. * @param v pointer of type atomic_t
  63. *
  64. * Atomically increments @v by 1.
  65. */
  66. static inline void atomic_inc( atomic_t *v )
  67. {
  68. (void)__sync_add_and_fetch(&v->counter, 1);
  69. }
  70. /**
  71. * @brief decrement atomic variable
  72. * @param v: pointer of type atomic_t
  73. *
  74. * Atomically decrements @v by 1. Note that the guaranteed
  75. * useful range of an atomic_t is only 24 bits.
  76. */
  77. static inline void atomic_dec( atomic_t *v )
  78. {
  79. (void)__sync_sub_and_fetch(&v->counter, 1);
  80. }
  81. /**
  82. * Increment atomic variable
  83. * @param v pointer of type atomic_t
  84. *
  85. * Atomically increments @v by 1.
  86. */
  87. static inline int atomic_inc_return( atomic_t *v )
  88. {
  89. return __sync_add_and_fetch(&v->counter, 1);
  90. }
  91. /**
  92. * @brief decrement atomic variable
  93. * @param v: pointer of type atomic_t
  94. *
  95. * Atomically decrements @v by 1. Note that the guaranteed
  96. * useful range of an atomic_t is only 24 bits.
  97. */
  98. static inline int atomic_dec_return( atomic_t *v )
  99. {
  100. return __sync_sub_and_fetch(&v->counter, 1);
  101. }
  102. /**
  103. * @brief Decrement and test
  104. * @param v pointer of type atomic_t
  105. *
  106. * Atomically decrements @v by 1 and
  107. * returns true if the result is 0, or false for all other
  108. * cases.
  109. */
  110. static inline int atomic_dec_and_test( atomic_t *v )
  111. {
  112. return !(__sync_sub_and_fetch(&v->counter, 1));
  113. }
  114. /**
  115. * @brief Increment and test
  116. * @param v pointer of type atomic_t
  117. *
  118. * Atomically increments @v by 1
  119. * and returns true if the result is zero, or false for all
  120. * other cases.
  121. */
  122. static inline int atomic_inc_and_test( atomic_t *v )
  123. {
  124. return !(__sync_add_and_fetch(&v->counter, 1));
  125. }
  126. /**
  127. * @brief add and test if negative
  128. * @param v pointer of type atomic_t
  129. * @param i integer value to add
  130. *
  131. * Atomically adds @i to @v and returns true
  132. * if the result is negative, or false when
  133. * result is greater than or equal to zero.
  134. */
  135. static inline int atomic_add_negative( int i, atomic_t *v )
  136. {
  137. return (__sync_add_and_fetch(&v->counter, i) < 0);
  138. }
  139. #endif