atomic.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * @brief Atomically set a bit.
  3. *
  4. * Atomically set bit number @a bit of @a target.
  5. * The target may be a single atomic variable or an array of them.
  6. *
  7. * @param target Address of atomic variable or array.
  8. * @param bit Bit number (starting from 0).
  9. *
  10. * @return N/A
  11. */
  12. /*
  13. * SPDX-FileCopyrightText: 2016 Intel Corporation
  14. * SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
  15. * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
  16. *
  17. * SPDX-License-Identifier: Apache-2.0
  18. */
  19. #include "mesh/atomic.h"
  20. #include "mesh/mutex.h"
  21. #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN
  22. /**
  23. *
  24. * @brief Atomic get primitive
  25. *
  26. * @param target memory location to read from
  27. *
  28. * This routine provides the atomic get primitive to atomically read
  29. * a value from <target>. It simply does an ordinary load. Note that <target>
  30. * is expected to be aligned to a 4-byte boundary.
  31. *
  32. * @return The value read from <target>
  33. */
  34. bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target)
  35. {
  36. return *target;
  37. }
  38. /**
  39. *
  40. * @brief Atomic get-and-set primitive
  41. *
  42. * This routine provides the atomic set operator. The <value> is atomically
  43. * written at <target> and the previous value at <target> is returned.
  44. *
  45. * @param target the memory location to write to
  46. * @param value the value to write
  47. *
  48. * @return The previous value from <target>
  49. */
  50. bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
  51. {
  52. bt_mesh_atomic_val_t ret = 0;
  53. bt_mesh_atomic_lock();
  54. ret = *target;
  55. *target = value;
  56. bt_mesh_atomic_unlock();
  57. return ret;
  58. }
  59. /**
  60. *
  61. * @brief Atomic bitwise inclusive OR primitive
  62. *
  63. * This routine provides the atomic bitwise inclusive OR operator. The <value>
  64. * is atomically bitwise OR'ed with the value at <target>, placing the result
  65. * at <target>, and the previous value at <target> is returned.
  66. *
  67. * @param target the memory location to be modified
  68. * @param value the value to OR
  69. *
  70. * @return The previous value from <target>
  71. */
  72. bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
  73. {
  74. bt_mesh_atomic_val_t ret = 0;
  75. bt_mesh_atomic_lock();
  76. ret = *target;
  77. *target |= value;
  78. bt_mesh_atomic_unlock();
  79. return ret;
  80. }
  81. /**
  82. *
  83. * @brief Atomic bitwise AND primitive
  84. *
  85. * This routine provides the atomic bitwise AND operator. The <value> is
  86. * atomically bitwise AND'ed with the value at <target>, placing the result
  87. * at <target>, and the previous value at <target> is returned.
  88. *
  89. * @param target the memory location to be modified
  90. * @param value the value to AND
  91. *
  92. * @return The previous value from <target>
  93. */
  94. bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
  95. {
  96. bt_mesh_atomic_val_t ret = 0;
  97. bt_mesh_atomic_lock();
  98. ret = *target;
  99. *target &= value;
  100. bt_mesh_atomic_unlock();
  101. return ret;
  102. }
  103. /**
  104. *
  105. * @brief Atomic decrement primitive
  106. *
  107. * @param target memory location to decrement
  108. *
  109. * This routine provides the atomic decrement operator. The value at <target>
  110. * is atomically decremented by 1, and the old value from <target> is returned.
  111. *
  112. * @return The value from <target> prior to the decrement
  113. */
  114. bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target)
  115. {
  116. bt_mesh_atomic_val_t ret = 0;
  117. bt_mesh_atomic_lock();
  118. ret = *target;
  119. (*target)--;
  120. bt_mesh_atomic_unlock();
  121. return ret;
  122. }
  123. /**
  124. *
  125. * @brief Atomic increment primitive
  126. *
  127. * @param target memory location to increment
  128. *
  129. * This routine provides the atomic increment operator. The value at <target>
  130. * is atomically incremented by 1, and the old value from <target> is returned.
  131. *
  132. * @return The value from <target> before the increment
  133. */
  134. bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
  135. {
  136. bt_mesh_atomic_val_t ret = 0;
  137. bt_mesh_atomic_lock();
  138. ret = *target;
  139. (*target)++;
  140. bt_mesh_atomic_unlock();
  141. return ret;
  142. }
  143. #endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */