/rel/chat/erts-8.0/include/internal/gcc/ethr_atomic.h

https://gitlab.com/wickchucked/wicklabs-auth · C Header · 569 lines · 392 code · 128 blank · 49 comment · 37 complexity · f3c5b6b6d60068e185808c524ad513a6 MD5 · raw file

  1. /*
  2. * %CopyrightBegin%
  3. *
  4. * Copyright Ericsson AB 2010-2015. All Rights Reserved.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * %CopyrightEnd%
  19. */
  20. /*
  21. * Description: Native atomics ethread support using gcc's __atomic
  22. * and __sync builtins
  23. * Author: Rickard Green
  24. *
  25. * Note: The C11 memory model implemented by gcc's __atomic
  26. * builtins does not match the ethread API very well.
  27. *
  28. * Due to this we cannot use the __ATOMIC_SEQ_CST
  29. * memory model. For more information see the comment
  30. * in the begining of ethr_membar.h in this directory.
  31. */
  32. #undef ETHR_INCLUDE_ATOMIC_IMPL__
  33. #if !defined(ETHR_GCC_ATOMIC_ATOMIC32_H__) \
  34. && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__) \
  35. && ((ETHR_HAVE___sync_val_compare_and_swap & 4) \
  36. || (ETHR_HAVE___atomic_compare_exchange_n & 4))
  37. #define ETHR_GCC_ATOMIC_ATOMIC32_H__
  38. #define ETHR_INCLUDE_ATOMIC_IMPL__ 4
  39. #undef ETHR_ATOMIC_WANT_32BIT_IMPL__
  40. #elif !defined(ETHR_GCC_ATOMIC64_H__) \
  41. && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__) \
  42. && ((ETHR_HAVE___sync_val_compare_and_swap & 8) \
  43. || (ETHR_HAVE___atomic_compare_exchange_n & 8))
  44. #define ETHR_GCC_ATOMIC64_H__
  45. #define ETHR_INCLUDE_ATOMIC_IMPL__ 8
  46. #undef ETHR_ATOMIC_WANT_64BIT_IMPL__
  47. #endif
  48. #ifdef ETHR_INCLUDE_ATOMIC_IMPL__
  49. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  50. #define ETHR_HAVE_NATIVE_ATOMIC32 1
  51. #define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
  52. #define ETHR_ATMC_T__ ethr_native_atomic32_t
  53. #define ETHR_AINT_T__ ethr_sint32_t
  54. #if ((ETHR_HAVE___sync_val_compare_and_swap & 4) \
  55. && (ETHR_HAVE___atomic_compare_exchange_n & 4))
  56. # define ETHR_NATIVE_ATOMIC32_IMPL "gcc_atomic_and_sync_builtins"
  57. #elif (ETHR_HAVE___atomic_compare_exchange_n & 4)
  58. # define ETHR_NATIVE_ATOMIC32_IMPL "gcc_atomic_builtins"
  59. #elif (ETHR_HAVE___sync_val_compare_and_swap & 4)
  60. # define ETHR_NATIVE_ATOMIC32_IMPL "gcc_sync_builtins"
  61. #else
  62. # error "!?"
  63. #endif
  64. #elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
  65. #define ETHR_HAVE_NATIVE_ATOMIC64 1
  66. #define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
  67. #define ETHR_ATMC_T__ ethr_native_atomic64_t
  68. #define ETHR_AINT_T__ ethr_sint64_t
  69. #if ((ETHR_HAVE___sync_val_compare_and_swap & 8) \
  70. && (ETHR_HAVE___atomic_compare_exchange_n & 8))
  71. # define ETHR_NATIVE_ATOMIC64_IMPL "gcc_atomic_and_sync_builtins"
  72. #elif (ETHR_HAVE___atomic_compare_exchange_n & 8)
  73. # define ETHR_NATIVE_ATOMIC64_IMPL "gcc_atomic_builtins"
  74. #elif (ETHR_HAVE___sync_val_compare_and_swap & 8)
  75. # define ETHR_NATIVE_ATOMIC64_IMPL "gcc_sync_builtins"
  76. #else
  77. # error "!?"
  78. #endif
  79. #else
  80. #error "Unsupported integer size"
  81. #endif
  82. #undef ETHR_NATIVE_ATOMIC_IMPL__
  83. typedef struct {
  84. volatile ETHR_AINT_T__ value;
  85. } ETHR_ATMC_T__;
  86. #if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
  87. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  88. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADDR 1
  89. #else
  90. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADDR 1
  91. #endif
  92. static ETHR_INLINE ETHR_AINT_T__ *
  93. ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
  94. {
  95. return (ETHR_AINT_T__ *) &var->value;
  96. }
  97. /*
  98. * set()
  99. */
  100. #if (ETHR_HAVE___atomic_store_n & ETHR_INCLUDE_ATOMIC_IMPL__)
  101. #if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  102. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  103. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET 1
  104. #else
  105. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET 1
  106. #endif
  107. static ETHR_INLINE void
  108. ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
  109. {
  110. __atomic_store_n(&var->value, value, __ATOMIC_RELAXED);
  111. }
  112. #endif /* ETHR_GCC_RELAXED_VERSIONS__ */
  113. #if (ETHR_GCC_RELB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  114. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  115. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET_RELB 1
  116. #else
  117. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET_RELB 1
  118. #endif
  119. static ETHR_INLINE void
  120. ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
  121. {
  122. __atomic_store_n(&var->value, value, __ATOMIC_RELEASE);
  123. }
  124. #endif /* ETHR_GCC_RELB_VERSIONS__ */
  125. #elif (ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  126. #if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  127. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  128. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET 1
  129. #else
  130. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET 1
  131. #endif
  132. static ETHR_INLINE void
  133. ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
  134. {
  135. var->value = value;
  136. }
  137. #endif /* ETHR_GCC_RELAXED_VERSIONS__ */
  138. #if (ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  139. #if (ETHR_GCC_RELB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  140. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  141. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET_RELB 1
  142. #else
  143. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET_RELB 1
  144. #endif
  145. static ETHR_INLINE void
  146. ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
  147. {
  148. var->value = value;
  149. }
  150. #endif /* ETHR_GCC_RELB_VERSIONS__ */
  151. #endif /* ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE_RELB__ */
  152. #endif /* ETHR_GCC_VOLATILE_STORE_IS_ATOMIC_STORE__ */
  153. /*
  154. * read()
  155. */
  156. #if (ETHR_HAVE___atomic_load_n & ETHR_INCLUDE_ATOMIC_IMPL__)
  157. #if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  158. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  159. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ 1
  160. #else
  161. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ 1
  162. #endif
  163. static ETHR_INLINE ETHR_AINT_T__
  164. ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
  165. {
  166. return __atomic_load_n(&var->value, __ATOMIC_RELAXED);
  167. }
  168. #endif /* ETHR_GCC_RELAXED_VERSIONS__ */
  169. #if ((ETHR_GCC_ACQB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__) \
  170. & ~ETHR___atomic_load_ACQUIRE_barrier_bug)
  171. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  172. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ_ACQB 1
  173. #else
  174. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ_ACQB 1
  175. #endif
  176. static ETHR_INLINE ETHR_AINT_T__
  177. ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
  178. {
  179. return __atomic_load_n(&var->value, __ATOMIC_ACQUIRE);
  180. }
  181. #endif /* ETHR_GCC_ACQB_VERSIONS__ */
  182. #elif (ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  183. #if (ETHR_GCC_RELAXED_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  184. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  185. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ 1
  186. #else
  187. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ 1
  188. #endif
  189. static ETHR_INLINE ETHR_AINT_T__
  190. ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
  191. {
  192. return var->value;
  193. }
  194. #endif /* ETHR_GCC_RELAXED_VERSIONS__ */
  195. #if (ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  196. #if (ETHR_GCC_ACQB_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  197. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  198. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ_ACQB 1
  199. #else
  200. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ_ACQB 1
  201. #endif
  202. static ETHR_INLINE ETHR_AINT_T__
  203. ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
  204. {
  205. return var->value;
  206. }
  207. #endif /* ETHR_GCC_ACQB_VERSIONS__ */
  208. #endif /* ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD_ACQB__ */
  209. #endif /* ETHR_GCC_VOLATILE_LOAD_IS_ATOMIC_LOAD__ */
  210. /*
  211. * add_return()
  212. */
  213. #if (ETHR_HAVE___atomic_add_fetch & ETHR_INCLUDE_ATOMIC_IMPL__)
  214. #if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  215. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  216. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN 1
  217. #else
  218. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN 1
  219. #endif
  220. static ETHR_INLINE ETHR_AINT_T__
  221. ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
  222. {
  223. return __atomic_add_fetch(&var->value, incr, __ATOMIC_RELAXED);
  224. }
  225. #endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
  226. #if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  227. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  228. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_ACQB 1
  229. #else
  230. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_ACQB 1
  231. #endif
  232. static ETHR_INLINE ETHR_AINT_T__
  233. ETHR_NATMC_FUNC__(add_return_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
  234. {
  235. return __atomic_add_fetch(&var->value, incr, __ATOMIC_ACQUIRE);
  236. }
  237. #endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
  238. #if (ETHR_GCC_RELB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  239. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  240. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_RELB 1
  241. #else
  242. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_RELB 1
  243. #endif
  244. static ETHR_INLINE ETHR_AINT_T__
  245. ETHR_NATMC_FUNC__(add_return_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
  246. {
  247. return __atomic_add_fetch(&var->value, incr, __ATOMIC_RELEASE);
  248. }
  249. #endif /* ETHR_GCC_RELB_MOD_VERSIONS__ */
  250. #endif /* ETHR_HAVE___atomic_add_fetch */
  251. #if ((ETHR_HAVE___sync_add_and_fetch & ETHR_INCLUDE_ATOMIC_IMPL__) \
  252. & ETHR_GCC_MB_MOD_VERSIONS__)
  253. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  254. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_MB 1
  255. #else
  256. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_MB 1
  257. #endif
  258. static ETHR_INLINE ETHR_AINT_T__
  259. ETHR_NATMC_FUNC__(add_return_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
  260. {
  261. return __sync_add_and_fetch(&var->value, incr);
  262. }
  263. #endif /* ETHR_HAVE___sync_add_and_fetch */
  264. /*
  265. * and_retold()
  266. */
  267. #if (ETHR_HAVE___atomic_fetch_and & ETHR_INCLUDE_ATOMIC_IMPL__)
  268. #if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  269. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  270. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD 1
  271. #else
  272. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD 1
  273. #endif
  274. static ETHR_INLINE ETHR_AINT_T__
  275. ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  276. {
  277. return __atomic_fetch_and(&var->value, mask, __ATOMIC_RELAXED);
  278. }
  279. #endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
  280. #if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  281. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  282. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_ACQB 1
  283. #else
  284. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD_ACQB 1
  285. #endif
  286. static ETHR_INLINE ETHR_AINT_T__
  287. ETHR_NATMC_FUNC__(and_retold_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  288. {
  289. return __atomic_fetch_and(&var->value, mask, __ATOMIC_ACQUIRE);
  290. }
  291. #endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
  292. #if (ETHR_GCC_RELB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  293. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  294. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_RELB 1
  295. #else
  296. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD_RELB 1
  297. #endif
  298. static ETHR_INLINE ETHR_AINT_T__
  299. ETHR_NATMC_FUNC__(and_retold_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  300. {
  301. return __atomic_fetch_and(&var->value, mask, __ATOMIC_RELEASE);
  302. }
  303. #endif /* ETHR_GCC_RELB_MOD_VERSIONS__ */
  304. #endif /* ETHR_HAVE___atomic_fetch_and */
  305. #if ((ETHR_HAVE___sync_fetch_and_and & ETHR_INCLUDE_ATOMIC_IMPL__) \
  306. & ETHR_GCC_MB_MOD_VERSIONS__)
  307. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  308. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_MB 1
  309. #else
  310. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD_MB 1
  311. #endif
  312. static ETHR_INLINE ETHR_AINT_T__
  313. ETHR_NATMC_FUNC__(and_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  314. {
  315. return __sync_fetch_and_and(&var->value, mask);
  316. }
  317. #endif /* ETHR_HAVE___sync_fetch_and_and */
  318. /*
  319. * or_retold()
  320. */
  321. #if (ETHR_HAVE___atomic_fetch_or & ETHR_INCLUDE_ATOMIC_IMPL__)
  322. #if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  323. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  324. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD 1
  325. #else
  326. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD 1
  327. #endif
  328. static ETHR_INLINE ETHR_AINT_T__
  329. ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  330. {
  331. return __atomic_fetch_or(&var->value, mask, __ATOMIC_RELAXED);
  332. }
  333. #endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
  334. #if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  335. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  336. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_ACQB 1
  337. #else
  338. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD_ACQB 1
  339. #endif
  340. static ETHR_INLINE ETHR_AINT_T__
  341. ETHR_NATMC_FUNC__(or_retold_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  342. {
  343. return __atomic_fetch_or(&var->value, mask, __ATOMIC_ACQUIRE);
  344. }
  345. #endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
  346. #if (ETHR_GCC_RELB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  347. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  348. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_RELB 1
  349. #else
  350. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD_RELB 1
  351. #endif
  352. static ETHR_INLINE ETHR_AINT_T__
  353. ETHR_NATMC_FUNC__(or_retold_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  354. {
  355. return __atomic_fetch_or(&var->value, mask, __ATOMIC_RELEASE);
  356. }
  357. #endif /* ETHR_GCC_RELB_MOD_VERSIONS__ */
  358. #endif /* ETHR_HAVE___atomic_fetch_or */
  359. #if ((ETHR_HAVE___sync_fetch_and_or & ETHR_INCLUDE_ATOMIC_IMPL__) \
  360. & ETHR_GCC_MB_MOD_VERSIONS__)
  361. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  362. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_MB 1
  363. #else
  364. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD_MB 1
  365. #endif
  366. static ETHR_INLINE ETHR_AINT_T__
  367. ETHR_NATMC_FUNC__(or_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
  368. {
  369. return (ETHR_AINT_T__) __sync_fetch_and_or(&var->value, mask);
  370. }
  371. #endif /* ETHR_HAVE___sync_fetch_and_or */
  372. /*
  373. * cmpxchg()
  374. */
  375. #if (ETHR_HAVE___atomic_compare_exchange_n & ETHR_INCLUDE_ATOMIC_IMPL__)
  376. #if (ETHR_GCC_RELAXED_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  377. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  378. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG 1
  379. #else
  380. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG 1
  381. #endif
  382. static ETHR_INLINE ETHR_AINT_T__
  383. ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var,
  384. ETHR_AINT_T__ new,
  385. ETHR_AINT_T__ exp)
  386. {
  387. ETHR_AINT_T__ xchg = exp;
  388. if (__atomic_compare_exchange_n(&var->value,
  389. &xchg,
  390. new,
  391. 0, /* No spurious failures, please */
  392. __ATOMIC_RELAXED,
  393. __ATOMIC_RELAXED))
  394. return exp;
  395. return xchg;
  396. }
  397. #endif /* ETHR_GCC_RELAXED_MOD_VERSIONS__ */
  398. #if (ETHR_GCC_ACQB_MOD_VERSIONS__ & ETHR_INCLUDE_ATOMIC_IMPL__)
  399. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  400. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_ACQB 1
  401. #else
  402. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_ACQB 1
  403. #endif
  404. static ETHR_INLINE ETHR_AINT_T__
  405. ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var,
  406. ETHR_AINT_T__ new,
  407. ETHR_AINT_T__ exp)
  408. {
  409. ETHR_AINT_T__ xchg = exp;
  410. if (__atomic_compare_exchange_n(&var->value,
  411. &xchg,
  412. new,
  413. 0, /* No spurious failures, please */
  414. __ATOMIC_ACQUIRE,
  415. __ATOMIC_ACQUIRE))
  416. return exp;
  417. return xchg;
  418. }
  419. #endif /* ETHR_GCC_ACQB_MOD_VERSIONS__ */
  420. #endif /* ETHR_HAVE___atomic_compare_exchange_n */
  421. #if ((ETHR_HAVE___sync_val_compare_and_swap & ETHR_INCLUDE_ATOMIC_IMPL__) \
  422. & ETHR_GCC_MB_MOD_VERSIONS__)
  423. #if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
  424. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_MB 1
  425. #else
  426. # define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_MB 1
  427. #endif
  428. static ETHR_INLINE ETHR_AINT_T__
  429. ETHR_NATMC_FUNC__(cmpxchg_mb)(ETHR_ATMC_T__ *var,
  430. ETHR_AINT_T__ new,
  431. ETHR_AINT_T__ old)
  432. {
  433. return __sync_val_compare_and_swap(&var->value, old, new);
  434. }
  435. #endif /* ETHR_HAVE___sync_val_compare_and_swap */
  436. #endif /* ETHR_TRY_INLINE_FUNCS */
  437. #undef ETHR_NATMC_FUNC__
  438. #undef ETHR_ATMC_T__
  439. #undef ETHR_AINT_T__
  440. #undef ETHR_AINT_SUFFIX__
  441. #endif