generalize.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. /*
  23. * Generalize atomic operations for atomic_ops.h.
  24. * Should not be included directly.
  25. *
  26. * We make no attempt to define useless operations, such as
  27. * AO_nop_acquire
  28. * AO_nop_release
  29. *
  30. * We have also so far neglected to define some others, which
  31. * do not appear likely to be useful, e.g. stores with acquire
  32. * or read barriers.
  33. *
  34. * This file is sometimes included twice by atomic_ops.h.
  35. * All definitions include explicit checks that we are not replacing
  36. * an earlier definition. In general, more desirable expansions
  37. * appear earlier so that we are more likely to use them.
  38. *
  39. * We only make safe generalizations, except that by default we define
  40. * the ...dd_acquire_read operations to be equivalent to those without
  41. * a barrier. On platforms for which this is unsafe, the platform-specific
  42. * file must define AO_NO_DD_ORDERING.
  43. */
  44. #ifndef AO_ATOMIC_OPS_H
  45. # error This file should not be included directly.
  46. #endif
  47. /* Generate test_and_set_full, if necessary and possible. */
  48. #if !defined(AO_HAVE_test_and_set) && !defined(AO_HAVE_test_and_set_release) \
  49. && !defined(AO_HAVE_test_and_set_acquire) \
  50. && !defined(AO_HAVE_test_and_set_read) \
  51. && !defined(AO_HAVE_test_and_set_full)
  52. /* Emulate AO_compare_and_swap() via AO_fetch_compare_and_swap(). */
  53. # if defined(AO_HAVE_fetch_compare_and_swap) \
  54. && !defined(AO_HAVE_compare_and_swap)
  55. AO_INLINE int
  56. AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
  57. {
  58. return AO_fetch_compare_and_swap(addr, old_val, new_val) == old_val;
  59. }
  60. # define AO_HAVE_compare_and_swap
  61. # endif
  62. # if defined(AO_HAVE_fetch_compare_and_swap_full) \
  63. && !defined(AO_HAVE_compare_and_swap_full)
  64. AO_INLINE int
  65. AO_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t new_val)
  66. {
  67. return AO_fetch_compare_and_swap_full(addr, old_val, new_val)
  68. == old_val;
  69. }
  70. # define AO_HAVE_compare_and_swap_full
  71. # endif
  72. # if defined(AO_HAVE_fetch_compare_and_swap_acquire) \
  73. && !defined(AO_HAVE_compare_and_swap_acquire)
  74. AO_INLINE int
  75. AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val,
  76. AO_t new_val)
  77. {
  78. return AO_fetch_compare_and_swap_acquire(addr, old_val, new_val)
  79. == old_val;
  80. }
  81. # define AO_HAVE_compare_and_swap_acquire
  82. # endif
  83. # if defined(AO_HAVE_fetch_compare_and_swap_release) \
  84. && !defined(AO_HAVE_compare_and_swap_release)
  85. AO_INLINE int
  86. AO_compare_and_swap_release(volatile AO_t *addr, AO_t old_val,
  87. AO_t new_val)
  88. {
  89. return AO_fetch_compare_and_swap_release(addr, old_val, new_val)
  90. == old_val;
  91. }
  92. # define AO_HAVE_compare_and_swap_release
  93. # endif
  94. # if AO_CHAR_TS_T
  95. # define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \
  96. AO_char_compare_and_swap_full(a,o,n)
  97. # define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
  98. AO_char_compare_and_swap_acquire(a,o,n)
  99. # define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
  100. AO_char_compare_and_swap_release(a,o,n)
  101. # define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_char_compare_and_swap(a,o,n)
  102. # endif
  103. # if AO_AO_TS_T
  104. # define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) AO_compare_and_swap_full(a,o,n)
  105. # define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
  106. AO_compare_and_swap_acquire(a,o,n)
  107. # define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
  108. AO_compare_and_swap_release(a,o,n)
  109. # define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_compare_and_swap(a,o,n)
  110. # endif
  111. # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_full)) \
  112. || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_full))
  113. AO_INLINE AO_TS_VAL_t
  114. AO_test_and_set_full(volatile AO_TS_t *addr)
  115. {
  116. if (AO_TS_COMPARE_AND_SWAP_FULL(addr, AO_TS_CLEAR, AO_TS_SET))
  117. return AO_TS_CLEAR;
  118. else
  119. return AO_TS_SET;
  120. }
  121. # define AO_HAVE_test_and_set_full
  122. # endif /* AO_HAVE_compare_and_swap_full */
  123. # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_acquire)) \
  124. || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_acquire))
  125. AO_INLINE AO_TS_VAL_t
  126. AO_test_and_set_acquire(volatile AO_TS_t *addr)
  127. {
  128. if (AO_TS_COMPARE_AND_SWAP_ACQUIRE(addr, AO_TS_CLEAR, AO_TS_SET))
  129. return AO_TS_CLEAR;
  130. else
  131. return AO_TS_SET;
  132. }
  133. # define AO_HAVE_test_and_set_acquire
  134. # endif /* AO_HAVE_compare_and_swap_acquire */
  135. # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_release)) \
  136. || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_release))
  137. AO_INLINE AO_TS_VAL_t
  138. AO_test_and_set_release(volatile AO_TS_t *addr)
  139. {
  140. if (AO_TS_COMPARE_AND_SWAP_RELEASE(addr, AO_TS_CLEAR, AO_TS_SET))
  141. return AO_TS_CLEAR;
  142. else
  143. return AO_TS_SET;
  144. }
  145. # define AO_HAVE_test_and_set_release
  146. # endif /* AO_HAVE_compare_and_swap_release */
  147. # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap)) \
  148. || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap))
  149. AO_INLINE AO_TS_VAL_t
  150. AO_test_and_set(volatile AO_TS_t *addr)
  151. {
  152. if (AO_TS_COMPARE_AND_SWAP(addr, AO_TS_CLEAR, AO_TS_SET))
  153. return AO_TS_CLEAR;
  154. else
  155. return AO_TS_SET;
  156. }
  157. # define AO_HAVE_test_and_set
  158. # endif /* AO_HAVE_compare_and_swap */
  159. #endif /* No prior test and set */
  160. /* Nop */
  161. #if !defined(AO_HAVE_nop)
  162. AO_INLINE void AO_nop(void) {}
  163. # define AO_HAVE_nop
  164. #endif
  165. #if defined(AO_HAVE_test_and_set_full) && !defined(AO_HAVE_nop_full)
  166. AO_INLINE void
  167. AO_nop_full(void)
  168. {
  169. AO_TS_t dummy = AO_TS_INITIALIZER;
  170. AO_test_and_set_full(&dummy);
  171. }
  172. # define AO_HAVE_nop_full
  173. #endif
  174. #if defined(AO_HAVE_nop_acquire)
  175. # error AO_nop_acquire is useless: dont define.
  176. #endif
  177. #if defined(AO_HAVE_nop_release)
  178. # error AO_nop_release is useless: dont define.
  179. #endif
  180. #if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_read)
  181. # define AO_nop_read() AO_nop_full()
  182. # define AO_HAVE_nop_read
  183. #endif
  184. #if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_write)
  185. # define AO_nop_write() AO_nop_full()
  186. # define AO_HAVE_nop_write
  187. #endif
  188. /* Test_and_set */
  189. #if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \
  190. && !defined(AO_HAVE_test_and_set_release)
  191. # define AO_test_and_set_release(addr) (AO_nop_full(), AO_test_and_set(addr))
  192. # define AO_HAVE_test_and_set_release
  193. #endif
  194. #if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \
  195. && !defined(AO_HAVE_test_and_set_acquire)
  196. AO_INLINE AO_TS_VAL_t
  197. AO_test_and_set_acquire(volatile AO_TS_t *addr)
  198. {
  199. AO_TS_VAL_t result = AO_test_and_set(addr);
  200. AO_nop_full();
  201. return result;
  202. }
  203. # define AO_HAVE_test_and_set_acquire
  204. #endif
  205. #if defined(AO_HAVE_test_and_set_full)
  206. # if !defined(AO_HAVE_test_and_set_release)
  207. # define AO_test_and_set_release(addr) AO_test_and_set_full(addr)
  208. # define AO_HAVE_test_and_set_release
  209. # endif
  210. # if !defined(AO_HAVE_test_and_set_acquire)
  211. # define AO_test_and_set_acquire(addr) AO_test_and_set_full(addr)
  212. # define AO_HAVE_test_and_set_acquire
  213. # endif
  214. # if !defined(AO_HAVE_test_and_set_write)
  215. # define AO_test_and_set_write(addr) AO_test_and_set_full(addr)
  216. # define AO_HAVE_test_and_set_write
  217. # endif
  218. # if !defined(AO_HAVE_test_and_set_read)
  219. # define AO_test_and_set_read(addr) AO_test_and_set_full(addr)
  220. # define AO_HAVE_test_and_set_read
  221. # endif
  222. #endif /* AO_HAVE_test_and_set_full */
  223. #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_release)
  224. # define AO_test_and_set(addr) AO_test_and_set_release(addr)
  225. # define AO_HAVE_test_and_set
  226. #endif
  227. #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_acquire)
  228. # define AO_test_and_set(addr) AO_test_and_set_acquire(addr)
  229. # define AO_HAVE_test_and_set
  230. #endif
  231. #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_write)
  232. # define AO_test_and_set(addr) AO_test_and_set_write(addr)
  233. # define AO_HAVE_test_and_set
  234. #endif
  235. #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_read)
  236. # define AO_test_and_set(addr) AO_test_and_set_read(addr)
  237. # define AO_HAVE_test_and_set
  238. #endif
  239. #if defined(AO_HAVE_test_and_set_acquire) && defined(AO_HAVE_nop_full) \
  240. && !defined(AO_HAVE_test_and_set_full)
  241. # define AO_test_and_set_full(addr) \
  242. (AO_nop_full(), AO_test_and_set_acquire(addr))
  243. # define AO_HAVE_test_and_set_full
  244. #endif
  245. #if !defined(AO_HAVE_test_and_set_release_write) \
  246. && defined(AO_HAVE_test_and_set_write)
  247. # define AO_test_and_set_release_write(addr) AO_test_and_set_write(addr)
  248. # define AO_HAVE_test_and_set_release_write
  249. #endif
  250. #if !defined(AO_HAVE_test_and_set_release_write) \
  251. && defined(AO_HAVE_test_and_set_release)
  252. # define AO_test_and_set_release_write(addr) AO_test_and_set_release(addr)
  253. # define AO_HAVE_test_and_set_release_write
  254. #endif
  255. #if !defined(AO_HAVE_test_and_set_acquire_read) \
  256. && defined(AO_HAVE_test_and_set_read)
  257. # define AO_test_and_set_acquire_read(addr) AO_test_and_set_read(addr)
  258. # define AO_HAVE_test_and_set_acquire_read
  259. #endif
  260. #if !defined(AO_HAVE_test_and_set_acquire_read) \
  261. && defined(AO_HAVE_test_and_set_acquire)
  262. # define AO_test_and_set_acquire_read(addr) AO_test_and_set_acquire(addr)
  263. # define AO_HAVE_test_and_set_acquire_read
  264. #endif
  265. #ifdef AO_NO_DD_ORDERING
  266. # if defined(AO_HAVE_test_and_set_acquire_read)
  267. # define AO_test_and_set_dd_acquire_read(addr) \
  268. AO_test_and_set_acquire_read(addr)
  269. # define AO_HAVE_test_and_set_dd_acquire_read
  270. # endif
  271. #else
  272. # if defined(AO_HAVE_test_and_set)
  273. # define AO_test_and_set_dd_acquire_read(addr) AO_test_and_set(addr)
  274. # define AO_HAVE_test_and_set_dd_acquire_read
  275. # endif
  276. #endif /* !AO_NO_DD_ORDERING */
  277. #include "generalize-small.h"
  278. #include "generalize-arithm.h"
  279. /* Compare_double_and_swap_double based on double_compare_and_swap. */
  280. #ifdef AO_HAVE_DOUBLE_PTR_STORAGE
  281. # if defined(AO_HAVE_double_compare_and_swap) \
  282. && !defined(AO_HAVE_compare_double_and_swap_double)
  283. AO_INLINE int
  284. AO_compare_double_and_swap_double(volatile AO_double_t *addr,
  285. AO_t old_val1, AO_t old_val2,
  286. AO_t new_val1, AO_t new_val2)
  287. {
  288. AO_double_t old_w;
  289. AO_double_t new_w;
  290. old_w.AO_val1 = old_val1;
  291. old_w.AO_val2 = old_val2;
  292. new_w.AO_val1 = new_val1;
  293. new_w.AO_val2 = new_val2;
  294. return AO_double_compare_and_swap(addr, old_w, new_w);
  295. }
  296. # define AO_HAVE_compare_double_and_swap_double
  297. # endif
  298. # if defined(AO_HAVE_double_compare_and_swap_full) \
  299. && !defined(AO_HAVE_compare_double_and_swap_double_full)
  300. AO_INLINE int
  301. AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
  302. AO_t old_val1, AO_t old_val2,
  303. AO_t new_val1, AO_t new_val2)
  304. {
  305. AO_double_t old_w;
  306. AO_double_t new_w;
  307. old_w.AO_val1 = old_val1;
  308. old_w.AO_val2 = old_val2;
  309. new_w.AO_val1 = new_val1;
  310. new_w.AO_val2 = new_val2;
  311. return AO_double_compare_and_swap_full(addr, old_w, new_w);
  312. }
  313. # define AO_HAVE_compare_double_and_swap_double_full
  314. # endif
  315. #endif /* AO_HAVE_DOUBLE_PTR_STORAGE */
  316. /* Compare_double_and_swap_double */
  317. #if defined(AO_HAVE_compare_double_and_swap_double) \
  318. && defined(AO_HAVE_nop_full) \
  319. && !defined(AO_HAVE_compare_double_and_swap_double_acquire)
  320. AO_INLINE int
  321. AO_compare_double_and_swap_double_acquire(volatile AO_double_t *addr,
  322. AO_t o1, AO_t o2,
  323. AO_t n1, AO_t n2)
  324. {
  325. int result = AO_compare_double_and_swap_double(addr, o1, o2, n1, n2);
  326. AO_nop_full();
  327. return result;
  328. }
  329. # define AO_HAVE_compare_double_and_swap_double_acquire
  330. #endif
  331. #if defined(AO_HAVE_compare_double_and_swap_double) \
  332. && defined(AO_HAVE_nop_full) \
  333. && !defined(AO_HAVE_compare_double_and_swap_double_release)
  334. # define AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) \
  335. (AO_nop_full(), AO_compare_double_and_swap_double(addr,o1,o2,n1,n2))
  336. # define AO_HAVE_compare_double_and_swap_double_release
  337. #endif
  338. #if defined(AO_HAVE_compare_double_and_swap_double_full)
  339. # if !defined(AO_HAVE_compare_double_and_swap_double_release)
  340. # define AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) \
  341. AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
  342. # define AO_HAVE_compare_double_and_swap_double_release
  343. # endif
  344. # if !defined(AO_HAVE_compare_double_and_swap_double_acquire)
  345. # define AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2) \
  346. AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
  347. # define AO_HAVE_compare_double_and_swap_double_acquire
  348. # endif
  349. # if !defined(AO_HAVE_compare_double_and_swap_double_write)
  350. # define AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2) \
  351. AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
  352. # define AO_HAVE_compare_double_and_swap_double_write
  353. # endif
  354. # if !defined(AO_HAVE_compare_double_and_swap_double_read)
  355. # define AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2) \
  356. AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2)
  357. # define AO_HAVE_compare_double_and_swap_double_read
  358. # endif
  359. #endif /* AO_HAVE_compare_double_and_swap_double_full */
  360. #if !defined(AO_HAVE_compare_double_and_swap_double) \
  361. && defined(AO_HAVE_compare_double_and_swap_double_release)
  362. # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
  363. AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2)
  364. # define AO_HAVE_compare_double_and_swap_double
  365. #endif
  366. #if !defined(AO_HAVE_compare_double_and_swap_double) \
  367. && defined(AO_HAVE_compare_double_and_swap_double_acquire)
  368. # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
  369. AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2)
  370. # define AO_HAVE_compare_double_and_swap_double
  371. #endif
  372. #if !defined(AO_HAVE_compare_double_and_swap_double) \
  373. && defined(AO_HAVE_compare_double_and_swap_double_write)
  374. # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
  375. AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2)
  376. # define AO_HAVE_compare_double_and_swap_double
  377. #endif
  378. #if !defined(AO_HAVE_compare_double_and_swap_double) \
  379. && defined(AO_HAVE_compare_double_and_swap_double_read)
  380. # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \
  381. AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2)
  382. # define AO_HAVE_compare_double_and_swap_double
  383. #endif
  384. #if defined(AO_HAVE_compare_double_and_swap_double_acquire) \
  385. && defined(AO_HAVE_nop_full) \
  386. && !defined(AO_HAVE_compare_double_and_swap_double_full)
  387. # define AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) \
  388. (AO_nop_full(), \
  389. AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2))
  390. # define AO_HAVE_compare_double_and_swap_double_full
  391. #endif
  392. #if !defined(AO_HAVE_compare_double_and_swap_double_release_write) \
  393. && defined(AO_HAVE_compare_double_and_swap_double_write)
  394. # define AO_compare_double_and_swap_double_release_write(addr,o1,o2,n1,n2) \
  395. AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2)
  396. # define AO_HAVE_compare_double_and_swap_double_release_write
  397. #endif
  398. #if !defined(AO_HAVE_compare_double_and_swap_double_release_write) \
  399. && defined(AO_HAVE_compare_double_and_swap_double_release)
  400. # define AO_compare_double_and_swap_double_release_write(addr,o1,o2,n1,n2) \
  401. AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2)
  402. # define AO_HAVE_compare_double_and_swap_double_release_write
  403. #endif
  404. #if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \
  405. && defined(AO_HAVE_compare_double_and_swap_double_read)
  406. # define AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) \
  407. AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2)
  408. # define AO_HAVE_compare_double_and_swap_double_acquire_read
  409. #endif
  410. #if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \
  411. && defined(AO_HAVE_compare_double_and_swap_double_acquire)
  412. # define AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) \
  413. AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2)
  414. # define AO_HAVE_compare_double_and_swap_double_acquire_read
  415. #endif
  416. #ifdef AO_NO_DD_ORDERING
  417. # if defined(AO_HAVE_compare_double_and_swap_double_acquire_read)
  418. # define AO_compare_double_and_swap_double_dd_acquire_read(addr,o1,o2,n1,n2) \
  419. AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2)
  420. # define AO_HAVE_compare_double_and_swap_double_dd_acquire_read
  421. # endif
  422. #else
  423. # if defined(AO_HAVE_compare_double_and_swap_double)
  424. # define AO_compare_double_and_swap_double_dd_acquire_read(addr,o1,o2,n1,n2) \
  425. AO_compare_double_and_swap_double(addr,o1,o2,n1,n2)
  426. # define AO_HAVE_compare_double_and_swap_double_dd_acquire_read
  427. # endif
  428. #endif /* !AO_NO_DD_ORDERING */
  429. /* Compare_and_swap_double */
  430. #if defined(AO_HAVE_compare_and_swap_double) && defined(AO_HAVE_nop_full) \
  431. && !defined(AO_HAVE_compare_and_swap_double_acquire)
  432. AO_INLINE int
  433. AO_compare_and_swap_double_acquire(volatile AO_double_t *addr,
  434. AO_t o1,
  435. AO_t n1, AO_t n2)
  436. {
  437. int result = AO_compare_and_swap_double(addr, o1, n1, n2);
  438. AO_nop_full();
  439. return result;
  440. }
  441. # define AO_HAVE_compare_and_swap_double_acquire
  442. #endif
  443. #if defined(AO_HAVE_compare_and_swap_double) \
  444. && defined(AO_HAVE_nop_full) \
  445. && !defined(AO_HAVE_compare_and_swap_double_release)
  446. # define AO_compare_and_swap_double_release(addr,o1,n1,n2) \
  447. (AO_nop_full(), AO_compare_and_swap_double(addr,o1,n1,n2))
  448. # define AO_HAVE_compare_and_swap_double_release
  449. #endif
  450. #if defined(AO_HAVE_compare_and_swap_double_full)
  451. # if !defined(AO_HAVE_compare_and_swap_double_release)
  452. # define AO_compare_and_swap_double_release(addr,o1,n1,n2) \
  453. AO_compare_and_swap_double_full(addr,o1,n1,n2)
  454. # define AO_HAVE_compare_and_swap_double_release
  455. # endif
  456. # if !defined(AO_HAVE_compare_and_swap_double_acquire)
  457. # define AO_compare_and_swap_double_acquire(addr,o1,n1,n2) \
  458. AO_compare_and_swap_double_full(addr,o1,n1,n2)
  459. # define AO_HAVE_compare_and_swap_double_acquire
  460. # endif
  461. # if !defined(AO_HAVE_compare_and_swap_double_write)
  462. # define AO_compare_and_swap_double_write(addr,o1,n1,n2) \
  463. AO_compare_and_swap_double_full(addr,o1,n1,n2)
  464. # define AO_HAVE_compare_and_swap_double_write
  465. # endif
  466. # if !defined(AO_HAVE_compare_and_swap_double_read)
  467. # define AO_compare_and_swap_double_read(addr,o1,n1,n2) \
  468. AO_compare_and_swap_double_full(addr,o1,n1,n2)
  469. # define AO_HAVE_compare_and_swap_double_read
  470. # endif
  471. #endif /* AO_HAVE_compare_and_swap_double_full */
  472. #if !defined(AO_HAVE_compare_and_swap_double) \
  473. && defined(AO_HAVE_compare_and_swap_double_release)
  474. # define AO_compare_and_swap_double(addr,o1,n1,n2) \
  475. AO_compare_and_swap_double_release(addr,o1,n1,n2)
  476. # define AO_HAVE_compare_and_swap_double
  477. #endif
  478. #if !defined(AO_HAVE_compare_and_swap_double) \
  479. && defined(AO_HAVE_compare_and_swap_double_acquire)
  480. # define AO_compare_and_swap_double(addr,o1,n1,n2) \
  481. AO_compare_and_swap_double_acquire(addr,o1,n1,n2)
  482. # define AO_HAVE_compare_and_swap_double
  483. #endif
  484. #if !defined(AO_HAVE_compare_and_swap_double) \
  485. && defined(AO_HAVE_compare_and_swap_double_write)
  486. # define AO_compare_and_swap_double(addr,o1,n1,n2) \
  487. AO_compare_and_swap_double_write(addr,o1,n1,n2)
  488. # define AO_HAVE_compare_and_swap_double
  489. #endif
  490. #if !defined(AO_HAVE_compare_and_swap_double) \
  491. && defined(AO_HAVE_compare_and_swap_double_read)
  492. # define AO_compare_and_swap_double(addr,o1,n1,n2) \
  493. AO_compare_and_swap_double_read(addr,o1,n1,n2)
  494. # define AO_HAVE_compare_and_swap_double
  495. #endif
  496. #if defined(AO_HAVE_compare_and_swap_double_acquire) \
  497. && defined(AO_HAVE_nop_full) \
  498. && !defined(AO_HAVE_compare_and_swap_double_full)
  499. # define AO_compare_and_swap_double_full(addr,o1,n1,n2) \
  500. (AO_nop_full(), AO_compare_and_swap_double_acquire(addr,o1,n1,n2))
  501. # define AO_HAVE_compare_and_swap_double_full
  502. #endif
  503. #if !defined(AO_HAVE_compare_and_swap_double_release_write) \
  504. && defined(AO_HAVE_compare_and_swap_double_write)
  505. # define AO_compare_and_swap_double_release_write(addr,o1,n1,n2) \
  506. AO_compare_and_swap_double_write(addr,o1,n1,n2)
  507. # define AO_HAVE_compare_and_swap_double_release_write
  508. #endif
  509. #if !defined(AO_HAVE_compare_and_swap_double_release_write) \
  510. && defined(AO_HAVE_compare_and_swap_double_release)
  511. # define AO_compare_and_swap_double_release_write(addr,o1,n1,n2) \
  512. AO_compare_and_swap_double_release(addr,o1,n1,n2)
  513. # define AO_HAVE_compare_and_swap_double_release_write
  514. #endif
  515. #if !defined(AO_HAVE_compare_and_swap_double_acquire_read) \
  516. && defined(AO_HAVE_compare_and_swap_double_read)
  517. # define AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) \
  518. AO_compare_and_swap_double_read(addr,o1,n1,n2)
  519. # define AO_HAVE_compare_and_swap_double_acquire_read
  520. #endif
  521. #if !defined(AO_HAVE_compare_and_swap_double_acquire_read) \
  522. && defined(AO_HAVE_compare_and_swap_double_acquire)
  523. # define AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) \
  524. AO_compare_and_swap_double_acquire(addr,o1,n1,n2)
  525. # define AO_HAVE_compare_and_swap_double_acquire_read
  526. #endif
  527. #ifdef AO_NO_DD_ORDERING
  528. # if defined(AO_HAVE_compare_and_swap_double_acquire_read)
  529. # define AO_compare_and_swap_double_dd_acquire_read(addr,o1,n1,n2) \
  530. AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2)
  531. # define AO_HAVE_compare_and_swap_double_dd_acquire_read
  532. # endif
  533. #else
  534. # if defined(AO_HAVE_compare_and_swap_double)
  535. # define AO_compare_and_swap_double_dd_acquire_read(addr,o1,n1,n2) \
  536. AO_compare_and_swap_double(addr,o1,n1,n2)
  537. # define AO_HAVE_compare_and_swap_double_dd_acquire_read
  538. # endif
  539. #endif
  540. /* Convenience functions for AO_double compare-and-swap which types and */
  541. /* reads easier in code. */
  542. #if defined(AO_HAVE_compare_double_and_swap_double) \
  543. && !defined(AO_HAVE_double_compare_and_swap)
  544. AO_INLINE int
  545. AO_double_compare_and_swap(volatile AO_double_t *addr,
  546. AO_double_t old_val, AO_double_t new_val)
  547. {
  548. return AO_compare_double_and_swap_double(addr,
  549. old_val.AO_val1, old_val.AO_val2,
  550. new_val.AO_val1, new_val.AO_val2);
  551. }
  552. # define AO_HAVE_double_compare_and_swap
  553. #endif
  554. #if defined(AO_HAVE_compare_double_and_swap_double_release) \
  555. && !defined(AO_HAVE_double_compare_and_swap_release)
  556. AO_INLINE int
  557. AO_double_compare_and_swap_release(volatile AO_double_t *addr,
  558. AO_double_t old_val, AO_double_t new_val)
  559. {
  560. return AO_compare_double_and_swap_double_release(addr,
  561. old_val.AO_val1, old_val.AO_val2,
  562. new_val.AO_val1, new_val.AO_val2);
  563. }
  564. # define AO_HAVE_double_compare_and_swap_release
  565. #endif
  566. #if defined(AO_HAVE_compare_double_and_swap_double_acquire) \
  567. && !defined(AO_HAVE_double_compare_and_swap_acquire)
  568. AO_INLINE int
  569. AO_double_compare_and_swap_acquire(volatile AO_double_t *addr,
  570. AO_double_t old_val, AO_double_t new_val)
  571. {
  572. return AO_compare_double_and_swap_double_acquire(addr,
  573. old_val.AO_val1, old_val.AO_val2,
  574. new_val.AO_val1, new_val.AO_val2);
  575. }
  576. # define AO_HAVE_double_compare_and_swap_acquire
  577. #endif
  578. #if defined(AO_HAVE_compare_double_and_swap_double_read) \
  579. && !defined(AO_HAVE_double_compare_and_swap_read)
  580. AO_INLINE int
  581. AO_double_compare_and_swap_read(volatile AO_double_t *addr,
  582. AO_double_t old_val, AO_double_t new_val)
  583. {
  584. return AO_compare_double_and_swap_double_read(addr,
  585. old_val.AO_val1, old_val.AO_val2,
  586. new_val.AO_val1, new_val.AO_val2);
  587. }
  588. # define AO_HAVE_double_compare_and_swap_read
  589. #endif
  590. #if defined(AO_HAVE_compare_double_and_swap_double_write) \
  591. && !defined(AO_HAVE_double_compare_and_swap_write)
  592. AO_INLINE int
  593. AO_double_compare_and_swap_write(volatile AO_double_t *addr,
  594. AO_double_t old_val, AO_double_t new_val)
  595. {
  596. return AO_compare_double_and_swap_double_write(addr,
  597. old_val.AO_val1, old_val.AO_val2,
  598. new_val.AO_val1, new_val.AO_val2);
  599. }
  600. # define AO_HAVE_double_compare_and_swap_write
  601. #endif
  602. #if defined(AO_HAVE_compare_double_and_swap_double_release_write) \
  603. && !defined(AO_HAVE_double_compare_and_swap_release_write)
  604. AO_INLINE int
  605. AO_double_compare_and_swap_release_write(volatile AO_double_t *addr,
  606. AO_double_t old_val, AO_double_t new_val)
  607. {
  608. return AO_compare_double_and_swap_double_release_write(addr,
  609. old_val.AO_val1, old_val.AO_val2,
  610. new_val.AO_val1, new_val.AO_val2);
  611. }
  612. # define AO_HAVE_double_compare_and_swap_release_write
  613. #endif
  614. #if defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \
  615. && !defined(AO_HAVE_double_compare_and_swap_acquire_read)
  616. AO_INLINE int
  617. AO_double_compare_and_swap_acquire_read(volatile AO_double_t *addr,
  618. AO_double_t old_val, AO_double_t new_val)
  619. {
  620. return AO_compare_double_and_swap_double_acquire_read(addr,
  621. old_val.AO_val1, old_val.AO_val2,
  622. new_val.AO_val1, new_val.AO_val2);
  623. }
  624. # define AO_HAVE_double_compare_and_swap_acquire_read
  625. #endif
  626. #if defined(AO_HAVE_compare_double_and_swap_double_full) \
  627. && !defined(AO_HAVE_double_compare_and_swap_full)
  628. AO_INLINE int
  629. AO_double_compare_and_swap_full(volatile AO_double_t *addr,
  630. AO_double_t old_val, AO_double_t new_val)
  631. {
  632. return AO_compare_double_and_swap_double_full(addr,
  633. old_val.AO_val1, old_val.AO_val2,
  634. new_val.AO_val1, new_val.AO_val2);
  635. }
  636. # define AO_HAVE_double_compare_and_swap_full
  637. #endif