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 /* 24 * Generalize atomic operations for atomic_ops.h. 25 * Should not be included directly. 26 * 27 * We make no attempt to define useless operations, such as 28 * AO_nop_acquire 29 * AO_nop_release 30 * 31 * We have also so far neglected to define some others, which 32 * do not appear likely to be useful, e.g. stores with acquire 33 * or read barriers. 34 * 35 * This file is sometimes included twice by atomic_ops.h. 36 * All definitions include explicit checks that we are not replacing 37 * an earlier definition. In general, more desirable expansions 38 * appear earlier so that we are more likely to use them. 39 * 40 * We only make safe generalizations, except that by default we define 41 * the ...dd_acquire_read operations to be equivalent to those without 42 * a barrier. On platforms for which this is unsafe, the platform-specific 43 * file must define AO_NO_DD_ORDERING. 44 */ 45 46 #ifndef AO_ATOMIC_OPS_H 47 # error This file should not be included directly. 48 #endif 49 50 /* Generate test_and_set_full, if necessary and possible. */ 51 #if !defined(AO_HAVE_test_and_set) && !defined(AO_HAVE_test_and_set_release) \ 52 && !defined(AO_HAVE_test_and_set_acquire) \ 53 && !defined(AO_HAVE_test_and_set_read) \ 54 && !defined(AO_HAVE_test_and_set_full) 55 56 /* Emulate AO_compare_and_swap() via AO_fetch_compare_and_swap(). */ 57 # if defined(AO_HAVE_fetch_compare_and_swap) \ 58 && !defined(AO_HAVE_compare_and_swap) 59 AO_INLINE int AO_compare_and_swap(volatile AO_t * addr,AO_t old_val,AO_t new_val)60 AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val) 61 { 62 return AO_fetch_compare_and_swap(addr, old_val, new_val) == old_val; 63 } 64 # define AO_HAVE_compare_and_swap 65 # endif 66 67 # if defined(AO_HAVE_fetch_compare_and_swap_full) \ 68 && !defined(AO_HAVE_compare_and_swap_full) 69 AO_INLINE int AO_compare_and_swap_full(volatile AO_t * addr,AO_t old_val,AO_t new_val)70 AO_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t new_val) 71 { 72 return AO_fetch_compare_and_swap_full(addr, old_val, new_val) 73 == old_val; 74 } 75 # define AO_HAVE_compare_and_swap_full 76 # endif 77 78 # if defined(AO_HAVE_fetch_compare_and_swap_acquire) \ 79 && !defined(AO_HAVE_compare_and_swap_acquire) 80 AO_INLINE int AO_compare_and_swap_acquire(volatile AO_t * addr,AO_t old_val,AO_t new_val)81 AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val, 82 AO_t new_val) 83 { 84 return AO_fetch_compare_and_swap_acquire(addr, old_val, new_val) 85 == old_val; 86 } 87 # define AO_HAVE_compare_and_swap_acquire 88 # endif 89 90 # if defined(AO_HAVE_fetch_compare_and_swap_release) \ 91 && !defined(AO_HAVE_compare_and_swap_release) 92 AO_INLINE int AO_compare_and_swap_release(volatile AO_t * addr,AO_t old_val,AO_t new_val)93 AO_compare_and_swap_release(volatile AO_t *addr, AO_t old_val, 94 AO_t new_val) 95 { 96 return AO_fetch_compare_and_swap_release(addr, old_val, new_val) 97 == old_val; 98 } 99 # define AO_HAVE_compare_and_swap_release 100 # endif 101 102 # if defined(AO_CHAR_TS_T) 103 # define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \ 104 AO_char_compare_and_swap_full(a,o,n) 105 # define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \ 106 AO_char_compare_and_swap_acquire(a,o,n) 107 # define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \ 108 AO_char_compare_and_swap_release(a,o,n) 109 # define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_char_compare_and_swap(a,o,n) 110 # endif 111 112 # if defined(AO_AO_TS_T) 113 # define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) AO_compare_and_swap_full(a,o,n) 114 # define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \ 115 AO_compare_and_swap_acquire(a,o,n) 116 # define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \ 117 AO_compare_and_swap_release(a,o,n) 118 # define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_compare_and_swap(a,o,n) 119 # endif 120 121 # if (defined(AO_AO_TS_T) && defined(AO_HAVE_compare_and_swap_full)) \ 122 || (defined(AO_CHAR_TS_T) && defined(AO_HAVE_char_compare_and_swap_full)) 123 AO_INLINE AO_TS_VAL_t AO_test_and_set_full(volatile AO_TS_t * addr)124 AO_test_and_set_full(volatile AO_TS_t *addr) 125 { 126 if (AO_TS_COMPARE_AND_SWAP_FULL(addr, AO_TS_CLEAR, AO_TS_SET)) 127 return AO_TS_CLEAR; 128 else 129 return AO_TS_SET; 130 } 131 # define AO_HAVE_test_and_set_full 132 # endif /* AO_HAVE_compare_and_swap_full */ 133 134 # if (defined(AO_AO_TS_T) && defined(AO_HAVE_compare_and_swap_acquire)) \ 135 || (defined(AO_CHAR_TS_T) \ 136 && defined(AO_HAVE_char_compare_and_swap_acquire)) 137 AO_INLINE AO_TS_VAL_t AO_test_and_set_acquire(volatile AO_TS_t * addr)138 AO_test_and_set_acquire(volatile AO_TS_t *addr) 139 { 140 if (AO_TS_COMPARE_AND_SWAP_ACQUIRE(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_acquire 146 # endif /* AO_HAVE_compare_and_swap_acquire */ 147 148 # if (defined(AO_AO_TS_T) && defined(AO_HAVE_compare_and_swap_release)) \ 149 || (defined(AO_CHAR_TS_T) \ 150 && defined(AO_HAVE_char_compare_and_swap_release)) 151 AO_INLINE AO_TS_VAL_t AO_test_and_set_release(volatile AO_TS_t * addr)152 AO_test_and_set_release(volatile AO_TS_t *addr) 153 { 154 if (AO_TS_COMPARE_AND_SWAP_RELEASE(addr, AO_TS_CLEAR, AO_TS_SET)) 155 return AO_TS_CLEAR; 156 else 157 return AO_TS_SET; 158 } 159 # define AO_HAVE_test_and_set_release 160 # endif /* AO_HAVE_compare_and_swap_release */ 161 162 # if (defined(AO_AO_TS_T) && defined(AO_HAVE_compare_and_swap)) \ 163 || (defined(AO_CHAR_TS_T) && defined(AO_HAVE_char_compare_and_swap)) 164 AO_INLINE AO_TS_VAL_t AO_test_and_set(volatile AO_TS_t * addr)165 AO_test_and_set(volatile AO_TS_t *addr) 166 { 167 if (AO_TS_COMPARE_AND_SWAP(addr, AO_TS_CLEAR, AO_TS_SET)) 168 return AO_TS_CLEAR; 169 else 170 return AO_TS_SET; 171 } 172 # define AO_HAVE_test_and_set 173 # endif /* AO_HAVE_compare_and_swap */ 174 #endif /* No prior test and set */ 175 176 /* Nop */ 177 #if !defined(AO_HAVE_nop) AO_nop(void)178 AO_INLINE void AO_nop(void) {} 179 # define AO_HAVE_nop 180 #endif 181 182 #if defined(AO_HAVE_test_and_set_full) && !defined(AO_HAVE_nop_full) 183 AO_INLINE void AO_nop_full(void)184 AO_nop_full(void) 185 { 186 AO_TS_t dummy = AO_TS_INITIALIZER; 187 AO_test_and_set_full(&dummy); 188 } 189 # define AO_HAVE_nop_full 190 #endif 191 192 #if defined(AO_HAVE_nop_acquire) && !defined(CPPCHECK) 193 # error AO_nop_acquire is useless: do not define. 194 #endif 195 196 #if defined(AO_HAVE_nop_release) && !defined(CPPCHECK) 197 # error AO_nop_release is useless: do not define. 198 #endif 199 200 #if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_read) 201 # define AO_nop_read() AO_nop_full() 202 # define AO_HAVE_nop_read 203 #endif 204 205 #if defined(AO_HAVE_nop_full) && !defined(AO_HAVE_nop_write) 206 # define AO_nop_write() AO_nop_full() 207 # define AO_HAVE_nop_write 208 #endif 209 210 /* Test_and_set */ 211 #if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \ 212 && !defined(AO_HAVE_test_and_set_release) 213 # define AO_test_and_set_release(addr) (AO_nop_full(), AO_test_and_set(addr)) 214 # define AO_HAVE_test_and_set_release 215 #endif 216 217 #if defined(AO_HAVE_test_and_set) && defined(AO_HAVE_nop_full) \ 218 && !defined(AO_HAVE_test_and_set_acquire) 219 AO_INLINE AO_TS_VAL_t AO_test_and_set_acquire(volatile AO_TS_t * addr)220 AO_test_and_set_acquire(volatile AO_TS_t *addr) 221 { 222 AO_TS_VAL_t result = AO_test_and_set(addr); 223 AO_nop_full(); 224 return result; 225 } 226 # define AO_HAVE_test_and_set_acquire 227 #endif 228 229 #if defined(AO_HAVE_test_and_set_full) 230 # if !defined(AO_HAVE_test_and_set_release) 231 # define AO_test_and_set_release(addr) AO_test_and_set_full(addr) 232 # define AO_HAVE_test_and_set_release 233 # endif 234 # if !defined(AO_HAVE_test_and_set_acquire) 235 # define AO_test_and_set_acquire(addr) AO_test_and_set_full(addr) 236 # define AO_HAVE_test_and_set_acquire 237 # endif 238 # if !defined(AO_HAVE_test_and_set_write) 239 # define AO_test_and_set_write(addr) AO_test_and_set_full(addr) 240 # define AO_HAVE_test_and_set_write 241 # endif 242 # if !defined(AO_HAVE_test_and_set_read) 243 # define AO_test_and_set_read(addr) AO_test_and_set_full(addr) 244 # define AO_HAVE_test_and_set_read 245 # endif 246 #endif /* AO_HAVE_test_and_set_full */ 247 248 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_release) 249 # define AO_test_and_set(addr) AO_test_and_set_release(addr) 250 # define AO_HAVE_test_and_set 251 #endif 252 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_acquire) 253 # define AO_test_and_set(addr) AO_test_and_set_acquire(addr) 254 # define AO_HAVE_test_and_set 255 #endif 256 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_write) 257 # define AO_test_and_set(addr) AO_test_and_set_write(addr) 258 # define AO_HAVE_test_and_set 259 #endif 260 #if !defined(AO_HAVE_test_and_set) && defined(AO_HAVE_test_and_set_read) 261 # define AO_test_and_set(addr) AO_test_and_set_read(addr) 262 # define AO_HAVE_test_and_set 263 #endif 264 265 #if defined(AO_HAVE_test_and_set_acquire) && defined(AO_HAVE_nop_full) \ 266 && !defined(AO_HAVE_test_and_set_full) 267 # define AO_test_and_set_full(addr) \ 268 (AO_nop_full(), AO_test_and_set_acquire(addr)) 269 # define AO_HAVE_test_and_set_full 270 #endif 271 272 #if !defined(AO_HAVE_test_and_set_release_write) \ 273 && defined(AO_HAVE_test_and_set_write) 274 # define AO_test_and_set_release_write(addr) AO_test_and_set_write(addr) 275 # define AO_HAVE_test_and_set_release_write 276 #endif 277 #if !defined(AO_HAVE_test_and_set_release_write) \ 278 && defined(AO_HAVE_test_and_set_release) 279 # define AO_test_and_set_release_write(addr) AO_test_and_set_release(addr) 280 # define AO_HAVE_test_and_set_release_write 281 #endif 282 #if !defined(AO_HAVE_test_and_set_acquire_read) \ 283 && defined(AO_HAVE_test_and_set_read) 284 # define AO_test_and_set_acquire_read(addr) AO_test_and_set_read(addr) 285 # define AO_HAVE_test_and_set_acquire_read 286 #endif 287 #if !defined(AO_HAVE_test_and_set_acquire_read) \ 288 && defined(AO_HAVE_test_and_set_acquire) 289 # define AO_test_and_set_acquire_read(addr) AO_test_and_set_acquire(addr) 290 # define AO_HAVE_test_and_set_acquire_read 291 #endif 292 293 #ifdef AO_NO_DD_ORDERING 294 # if defined(AO_HAVE_test_and_set_acquire_read) 295 # define AO_test_and_set_dd_acquire_read(addr) \ 296 AO_test_and_set_acquire_read(addr) 297 # define AO_HAVE_test_and_set_dd_acquire_read 298 # endif 299 #else 300 # if defined(AO_HAVE_test_and_set) 301 # define AO_test_and_set_dd_acquire_read(addr) AO_test_and_set(addr) 302 # define AO_HAVE_test_and_set_dd_acquire_read 303 # endif 304 #endif /* !AO_NO_DD_ORDERING */ 305 306 #include "generalize-small.h" 307 308 #include "generalize-arithm.h" 309 310 /* Compare_double_and_swap_double based on double_compare_and_swap. */ 311 #ifdef AO_HAVE_DOUBLE_PTR_STORAGE 312 # if defined(AO_HAVE_double_compare_and_swap) \ 313 && !defined(AO_HAVE_compare_double_and_swap_double) 314 AO_INLINE int AO_compare_double_and_swap_double(volatile AO_double_t * addr,AO_t old_val1,AO_t old_val2,AO_t new_val1,AO_t new_val2)315 AO_compare_double_and_swap_double(volatile AO_double_t *addr, 316 AO_t old_val1, AO_t old_val2, 317 AO_t new_val1, AO_t new_val2) 318 { 319 AO_double_t old_w; 320 AO_double_t new_w; 321 old_w.AO_val1 = old_val1; 322 old_w.AO_val2 = old_val2; 323 new_w.AO_val1 = new_val1; 324 new_w.AO_val2 = new_val2; 325 return AO_double_compare_and_swap(addr, old_w, new_w); 326 } 327 # define AO_HAVE_compare_double_and_swap_double 328 # endif 329 # if defined(AO_HAVE_double_compare_and_swap_acquire) \ 330 && !defined(AO_HAVE_compare_double_and_swap_double_acquire) 331 AO_INLINE int AO_compare_double_and_swap_double_acquire(volatile AO_double_t * addr,AO_t old_val1,AO_t old_val2,AO_t new_val1,AO_t new_val2)332 AO_compare_double_and_swap_double_acquire(volatile AO_double_t *addr, 333 AO_t old_val1, AO_t old_val2, 334 AO_t new_val1, AO_t new_val2) 335 { 336 AO_double_t old_w; 337 AO_double_t new_w; 338 old_w.AO_val1 = old_val1; 339 old_w.AO_val2 = old_val2; 340 new_w.AO_val1 = new_val1; 341 new_w.AO_val2 = new_val2; 342 return AO_double_compare_and_swap_acquire(addr, old_w, new_w); 343 } 344 # define AO_HAVE_compare_double_and_swap_double_acquire 345 # endif 346 # if defined(AO_HAVE_double_compare_and_swap_release) \ 347 && !defined(AO_HAVE_compare_double_and_swap_double_release) 348 AO_INLINE int AO_compare_double_and_swap_double_release(volatile AO_double_t * addr,AO_t old_val1,AO_t old_val2,AO_t new_val1,AO_t new_val2)349 AO_compare_double_and_swap_double_release(volatile AO_double_t *addr, 350 AO_t old_val1, AO_t old_val2, 351 AO_t new_val1, AO_t new_val2) 352 { 353 AO_double_t old_w; 354 AO_double_t new_w; 355 old_w.AO_val1 = old_val1; 356 old_w.AO_val2 = old_val2; 357 new_w.AO_val1 = new_val1; 358 new_w.AO_val2 = new_val2; 359 return AO_double_compare_and_swap_release(addr, old_w, new_w); 360 } 361 # define AO_HAVE_compare_double_and_swap_double_release 362 # endif 363 # if defined(AO_HAVE_double_compare_and_swap_full) \ 364 && !defined(AO_HAVE_compare_double_and_swap_double_full) 365 AO_INLINE int AO_compare_double_and_swap_double_full(volatile AO_double_t * addr,AO_t old_val1,AO_t old_val2,AO_t new_val1,AO_t new_val2)366 AO_compare_double_and_swap_double_full(volatile AO_double_t *addr, 367 AO_t old_val1, AO_t old_val2, 368 AO_t new_val1, AO_t new_val2) 369 { 370 AO_double_t old_w; 371 AO_double_t new_w; 372 old_w.AO_val1 = old_val1; 373 old_w.AO_val2 = old_val2; 374 new_w.AO_val1 = new_val1; 375 new_w.AO_val2 = new_val2; 376 return AO_double_compare_and_swap_full(addr, old_w, new_w); 377 } 378 # define AO_HAVE_compare_double_and_swap_double_full 379 # endif 380 #endif /* AO_HAVE_DOUBLE_PTR_STORAGE */ 381 382 /* Compare_double_and_swap_double */ 383 #if defined(AO_HAVE_compare_double_and_swap_double) \ 384 && defined(AO_HAVE_nop_full) \ 385 && !defined(AO_HAVE_compare_double_and_swap_double_acquire) 386 AO_INLINE int AO_compare_double_and_swap_double_acquire(volatile AO_double_t * addr,AO_t o1,AO_t o2,AO_t n1,AO_t n2)387 AO_compare_double_and_swap_double_acquire(volatile AO_double_t *addr, 388 AO_t o1, AO_t o2, 389 AO_t n1, AO_t n2) 390 { 391 int result = AO_compare_double_and_swap_double(addr, o1, o2, n1, n2); 392 AO_nop_full(); 393 return result; 394 } 395 # define AO_HAVE_compare_double_and_swap_double_acquire 396 #endif 397 #if defined(AO_HAVE_compare_double_and_swap_double) \ 398 && defined(AO_HAVE_nop_full) \ 399 && !defined(AO_HAVE_compare_double_and_swap_double_release) 400 # define AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) \ 401 (AO_nop_full(), AO_compare_double_and_swap_double(addr,o1,o2,n1,n2)) 402 # define AO_HAVE_compare_double_and_swap_double_release 403 #endif 404 #if defined(AO_HAVE_compare_double_and_swap_double_full) 405 # if !defined(AO_HAVE_compare_double_and_swap_double_release) 406 # define AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) \ 407 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) 408 # define AO_HAVE_compare_double_and_swap_double_release 409 # endif 410 # if !defined(AO_HAVE_compare_double_and_swap_double_acquire) 411 # define AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2) \ 412 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) 413 # define AO_HAVE_compare_double_and_swap_double_acquire 414 # endif 415 # if !defined(AO_HAVE_compare_double_and_swap_double_write) 416 # define AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2) \ 417 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) 418 # define AO_HAVE_compare_double_and_swap_double_write 419 # endif 420 # if !defined(AO_HAVE_compare_double_and_swap_double_read) 421 # define AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2) \ 422 AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) 423 # define AO_HAVE_compare_double_and_swap_double_read 424 # endif 425 #endif /* AO_HAVE_compare_double_and_swap_double_full */ 426 427 #if !defined(AO_HAVE_compare_double_and_swap_double) \ 428 && defined(AO_HAVE_compare_double_and_swap_double_release) 429 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \ 430 AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) 431 # define AO_HAVE_compare_double_and_swap_double 432 #endif 433 #if !defined(AO_HAVE_compare_double_and_swap_double) \ 434 && defined(AO_HAVE_compare_double_and_swap_double_acquire) 435 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \ 436 AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2) 437 # define AO_HAVE_compare_double_and_swap_double 438 #endif 439 #if !defined(AO_HAVE_compare_double_and_swap_double) \ 440 && defined(AO_HAVE_compare_double_and_swap_double_write) 441 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \ 442 AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2) 443 # define AO_HAVE_compare_double_and_swap_double 444 #endif 445 #if !defined(AO_HAVE_compare_double_and_swap_double) \ 446 && defined(AO_HAVE_compare_double_and_swap_double_read) 447 # define AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) \ 448 AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2) 449 # define AO_HAVE_compare_double_and_swap_double 450 #endif 451 452 #if defined(AO_HAVE_compare_double_and_swap_double_acquire) \ 453 && defined(AO_HAVE_nop_full) \ 454 && !defined(AO_HAVE_compare_double_and_swap_double_full) 455 # define AO_compare_double_and_swap_double_full(addr,o1,o2,n1,n2) \ 456 (AO_nop_full(), \ 457 AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2)) 458 # define AO_HAVE_compare_double_and_swap_double_full 459 #endif 460 461 #if !defined(AO_HAVE_compare_double_and_swap_double_release_write) \ 462 && defined(AO_HAVE_compare_double_and_swap_double_write) 463 # define AO_compare_double_and_swap_double_release_write(addr,o1,o2,n1,n2) \ 464 AO_compare_double_and_swap_double_write(addr,o1,o2,n1,n2) 465 # define AO_HAVE_compare_double_and_swap_double_release_write 466 #endif 467 #if !defined(AO_HAVE_compare_double_and_swap_double_release_write) \ 468 && defined(AO_HAVE_compare_double_and_swap_double_release) 469 # define AO_compare_double_and_swap_double_release_write(addr,o1,o2,n1,n2) \ 470 AO_compare_double_and_swap_double_release(addr,o1,o2,n1,n2) 471 # define AO_HAVE_compare_double_and_swap_double_release_write 472 #endif 473 #if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \ 474 && defined(AO_HAVE_compare_double_and_swap_double_read) 475 # define AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) \ 476 AO_compare_double_and_swap_double_read(addr,o1,o2,n1,n2) 477 # define AO_HAVE_compare_double_and_swap_double_acquire_read 478 #endif 479 #if !defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \ 480 && defined(AO_HAVE_compare_double_and_swap_double_acquire) 481 # define AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) \ 482 AO_compare_double_and_swap_double_acquire(addr,o1,o2,n1,n2) 483 # define AO_HAVE_compare_double_and_swap_double_acquire_read 484 #endif 485 486 #ifdef AO_NO_DD_ORDERING 487 # if defined(AO_HAVE_compare_double_and_swap_double_acquire_read) 488 # define AO_compare_double_and_swap_double_dd_acquire_read(addr,o1,o2,n1,n2) \ 489 AO_compare_double_and_swap_double_acquire_read(addr,o1,o2,n1,n2) 490 # define AO_HAVE_compare_double_and_swap_double_dd_acquire_read 491 # endif 492 #else 493 # if defined(AO_HAVE_compare_double_and_swap_double) 494 # define AO_compare_double_and_swap_double_dd_acquire_read(addr,o1,o2,n1,n2) \ 495 AO_compare_double_and_swap_double(addr,o1,o2,n1,n2) 496 # define AO_HAVE_compare_double_and_swap_double_dd_acquire_read 497 # endif 498 #endif /* !AO_NO_DD_ORDERING */ 499 500 /* Compare_and_swap_double */ 501 #if defined(AO_HAVE_compare_and_swap_double) && defined(AO_HAVE_nop_full) \ 502 && !defined(AO_HAVE_compare_and_swap_double_acquire) 503 AO_INLINE int AO_compare_and_swap_double_acquire(volatile AO_double_t * addr,AO_t o1,AO_t n1,AO_t n2)504 AO_compare_and_swap_double_acquire(volatile AO_double_t *addr, 505 AO_t o1, 506 AO_t n1, AO_t n2) 507 { 508 int result = AO_compare_and_swap_double(addr, o1, n1, n2); 509 AO_nop_full(); 510 return result; 511 } 512 # define AO_HAVE_compare_and_swap_double_acquire 513 #endif 514 #if defined(AO_HAVE_compare_and_swap_double) \ 515 && defined(AO_HAVE_nop_full) \ 516 && !defined(AO_HAVE_compare_and_swap_double_release) 517 # define AO_compare_and_swap_double_release(addr,o1,n1,n2) \ 518 (AO_nop_full(), AO_compare_and_swap_double(addr,o1,n1,n2)) 519 # define AO_HAVE_compare_and_swap_double_release 520 #endif 521 #if defined(AO_HAVE_compare_and_swap_double_full) 522 # if !defined(AO_HAVE_compare_and_swap_double_release) 523 # define AO_compare_and_swap_double_release(addr,o1,n1,n2) \ 524 AO_compare_and_swap_double_full(addr,o1,n1,n2) 525 # define AO_HAVE_compare_and_swap_double_release 526 # endif 527 # if !defined(AO_HAVE_compare_and_swap_double_acquire) 528 # define AO_compare_and_swap_double_acquire(addr,o1,n1,n2) \ 529 AO_compare_and_swap_double_full(addr,o1,n1,n2) 530 # define AO_HAVE_compare_and_swap_double_acquire 531 # endif 532 # if !defined(AO_HAVE_compare_and_swap_double_write) 533 # define AO_compare_and_swap_double_write(addr,o1,n1,n2) \ 534 AO_compare_and_swap_double_full(addr,o1,n1,n2) 535 # define AO_HAVE_compare_and_swap_double_write 536 # endif 537 # if !defined(AO_HAVE_compare_and_swap_double_read) 538 # define AO_compare_and_swap_double_read(addr,o1,n1,n2) \ 539 AO_compare_and_swap_double_full(addr,o1,n1,n2) 540 # define AO_HAVE_compare_and_swap_double_read 541 # endif 542 #endif /* AO_HAVE_compare_and_swap_double_full */ 543 544 #if !defined(AO_HAVE_compare_and_swap_double) \ 545 && defined(AO_HAVE_compare_and_swap_double_release) 546 # define AO_compare_and_swap_double(addr,o1,n1,n2) \ 547 AO_compare_and_swap_double_release(addr,o1,n1,n2) 548 # define AO_HAVE_compare_and_swap_double 549 #endif 550 #if !defined(AO_HAVE_compare_and_swap_double) \ 551 && defined(AO_HAVE_compare_and_swap_double_acquire) 552 # define AO_compare_and_swap_double(addr,o1,n1,n2) \ 553 AO_compare_and_swap_double_acquire(addr,o1,n1,n2) 554 # define AO_HAVE_compare_and_swap_double 555 #endif 556 #if !defined(AO_HAVE_compare_and_swap_double) \ 557 && defined(AO_HAVE_compare_and_swap_double_write) 558 # define AO_compare_and_swap_double(addr,o1,n1,n2) \ 559 AO_compare_and_swap_double_write(addr,o1,n1,n2) 560 # define AO_HAVE_compare_and_swap_double 561 #endif 562 #if !defined(AO_HAVE_compare_and_swap_double) \ 563 && defined(AO_HAVE_compare_and_swap_double_read) 564 # define AO_compare_and_swap_double(addr,o1,n1,n2) \ 565 AO_compare_and_swap_double_read(addr,o1,n1,n2) 566 # define AO_HAVE_compare_and_swap_double 567 #endif 568 569 #if defined(AO_HAVE_compare_and_swap_double_acquire) \ 570 && defined(AO_HAVE_nop_full) \ 571 && !defined(AO_HAVE_compare_and_swap_double_full) 572 # define AO_compare_and_swap_double_full(addr,o1,n1,n2) \ 573 (AO_nop_full(), AO_compare_and_swap_double_acquire(addr,o1,n1,n2)) 574 # define AO_HAVE_compare_and_swap_double_full 575 #endif 576 577 #if !defined(AO_HAVE_compare_and_swap_double_release_write) \ 578 && defined(AO_HAVE_compare_and_swap_double_write) 579 # define AO_compare_and_swap_double_release_write(addr,o1,n1,n2) \ 580 AO_compare_and_swap_double_write(addr,o1,n1,n2) 581 # define AO_HAVE_compare_and_swap_double_release_write 582 #endif 583 #if !defined(AO_HAVE_compare_and_swap_double_release_write) \ 584 && defined(AO_HAVE_compare_and_swap_double_release) 585 # define AO_compare_and_swap_double_release_write(addr,o1,n1,n2) \ 586 AO_compare_and_swap_double_release(addr,o1,n1,n2) 587 # define AO_HAVE_compare_and_swap_double_release_write 588 #endif 589 #if !defined(AO_HAVE_compare_and_swap_double_acquire_read) \ 590 && defined(AO_HAVE_compare_and_swap_double_read) 591 # define AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) \ 592 AO_compare_and_swap_double_read(addr,o1,n1,n2) 593 # define AO_HAVE_compare_and_swap_double_acquire_read 594 #endif 595 #if !defined(AO_HAVE_compare_and_swap_double_acquire_read) \ 596 && defined(AO_HAVE_compare_and_swap_double_acquire) 597 # define AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) \ 598 AO_compare_and_swap_double_acquire(addr,o1,n1,n2) 599 # define AO_HAVE_compare_and_swap_double_acquire_read 600 #endif 601 602 #ifdef AO_NO_DD_ORDERING 603 # if defined(AO_HAVE_compare_and_swap_double_acquire_read) 604 # define AO_compare_and_swap_double_dd_acquire_read(addr,o1,n1,n2) \ 605 AO_compare_and_swap_double_acquire_read(addr,o1,n1,n2) 606 # define AO_HAVE_compare_and_swap_double_dd_acquire_read 607 # endif 608 #else 609 # if defined(AO_HAVE_compare_and_swap_double) 610 # define AO_compare_and_swap_double_dd_acquire_read(addr,o1,n1,n2) \ 611 AO_compare_and_swap_double(addr,o1,n1,n2) 612 # define AO_HAVE_compare_and_swap_double_dd_acquire_read 613 # endif 614 #endif 615 616 /* Convenience functions for AO_double compare-and-swap which types and */ 617 /* reads easier in code. */ 618 #if defined(AO_HAVE_compare_double_and_swap_double) \ 619 && !defined(AO_HAVE_double_compare_and_swap) 620 AO_INLINE int AO_double_compare_and_swap(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)621 AO_double_compare_and_swap(volatile AO_double_t *addr, 622 AO_double_t old_val, AO_double_t new_val) 623 { 624 return AO_compare_double_and_swap_double(addr, 625 old_val.AO_val1, old_val.AO_val2, 626 new_val.AO_val1, new_val.AO_val2); 627 } 628 # define AO_HAVE_double_compare_and_swap 629 #endif 630 #if defined(AO_HAVE_compare_double_and_swap_double_release) \ 631 && !defined(AO_HAVE_double_compare_and_swap_release) 632 AO_INLINE int AO_double_compare_and_swap_release(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)633 AO_double_compare_and_swap_release(volatile AO_double_t *addr, 634 AO_double_t old_val, AO_double_t new_val) 635 { 636 return AO_compare_double_and_swap_double_release(addr, 637 old_val.AO_val1, old_val.AO_val2, 638 new_val.AO_val1, new_val.AO_val2); 639 } 640 # define AO_HAVE_double_compare_and_swap_release 641 #endif 642 #if defined(AO_HAVE_compare_double_and_swap_double_acquire) \ 643 && !defined(AO_HAVE_double_compare_and_swap_acquire) 644 AO_INLINE int AO_double_compare_and_swap_acquire(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)645 AO_double_compare_and_swap_acquire(volatile AO_double_t *addr, 646 AO_double_t old_val, AO_double_t new_val) 647 { 648 return AO_compare_double_and_swap_double_acquire(addr, 649 old_val.AO_val1, old_val.AO_val2, 650 new_val.AO_val1, new_val.AO_val2); 651 } 652 # define AO_HAVE_double_compare_and_swap_acquire 653 #endif 654 #if defined(AO_HAVE_compare_double_and_swap_double_read) \ 655 && !defined(AO_HAVE_double_compare_and_swap_read) 656 AO_INLINE int AO_double_compare_and_swap_read(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)657 AO_double_compare_and_swap_read(volatile AO_double_t *addr, 658 AO_double_t old_val, AO_double_t new_val) 659 { 660 return AO_compare_double_and_swap_double_read(addr, 661 old_val.AO_val1, old_val.AO_val2, 662 new_val.AO_val1, new_val.AO_val2); 663 } 664 # define AO_HAVE_double_compare_and_swap_read 665 #endif 666 #if defined(AO_HAVE_compare_double_and_swap_double_write) \ 667 && !defined(AO_HAVE_double_compare_and_swap_write) 668 AO_INLINE int AO_double_compare_and_swap_write(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)669 AO_double_compare_and_swap_write(volatile AO_double_t *addr, 670 AO_double_t old_val, AO_double_t new_val) 671 { 672 return AO_compare_double_and_swap_double_write(addr, 673 old_val.AO_val1, old_val.AO_val2, 674 new_val.AO_val1, new_val.AO_val2); 675 } 676 # define AO_HAVE_double_compare_and_swap_write 677 #endif 678 #if defined(AO_HAVE_compare_double_and_swap_double_release_write) \ 679 && !defined(AO_HAVE_double_compare_and_swap_release_write) 680 AO_INLINE int AO_double_compare_and_swap_release_write(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)681 AO_double_compare_and_swap_release_write(volatile AO_double_t *addr, 682 AO_double_t old_val, AO_double_t new_val) 683 { 684 return AO_compare_double_and_swap_double_release_write(addr, 685 old_val.AO_val1, old_val.AO_val2, 686 new_val.AO_val1, new_val.AO_val2); 687 } 688 # define AO_HAVE_double_compare_and_swap_release_write 689 #endif 690 #if defined(AO_HAVE_compare_double_and_swap_double_acquire_read) \ 691 && !defined(AO_HAVE_double_compare_and_swap_acquire_read) 692 AO_INLINE int AO_double_compare_and_swap_acquire_read(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)693 AO_double_compare_and_swap_acquire_read(volatile AO_double_t *addr, 694 AO_double_t old_val, AO_double_t new_val) 695 { 696 return AO_compare_double_and_swap_double_acquire_read(addr, 697 old_val.AO_val1, old_val.AO_val2, 698 new_val.AO_val1, new_val.AO_val2); 699 } 700 # define AO_HAVE_double_compare_and_swap_acquire_read 701 #endif 702 #if defined(AO_HAVE_compare_double_and_swap_double_full) \ 703 && !defined(AO_HAVE_double_compare_and_swap_full) 704 AO_INLINE int AO_double_compare_and_swap_full(volatile AO_double_t * addr,AO_double_t old_val,AO_double_t new_val)705 AO_double_compare_and_swap_full(volatile AO_double_t *addr, 706 AO_double_t old_val, AO_double_t new_val) 707 { 708 return AO_compare_double_and_swap_double_full(addr, 709 old_val.AO_val1, old_val.AO_val2, 710 new_val.AO_val1, new_val.AO_val2); 711 } 712 # define AO_HAVE_double_compare_and_swap_full 713 #endif 714 715 #ifndef AO_HAVE_double_compare_and_swap_dd_acquire_read 716 /* Duplicated from generalize-small because double CAS might be */ 717 /* defined after the include. */ 718 # ifdef AO_NO_DD_ORDERING 719 # if defined(AO_HAVE_double_compare_and_swap_acquire_read) 720 # define AO_double_compare_and_swap_dd_acquire_read(addr, old, new_val) \ 721 AO_double_compare_and_swap_acquire_read(addr, old, new_val) 722 # define AO_HAVE_double_compare_and_swap_dd_acquire_read 723 # endif 724 # elif defined(AO_HAVE_double_compare_and_swap) 725 # define AO_double_compare_and_swap_dd_acquire_read(addr, old, new_val) \ 726 AO_double_compare_and_swap(addr, old, new_val) 727 # define AO_HAVE_double_compare_and_swap_dd_acquire_read 728 # endif /* !AO_NO_DD_ORDERING */ 729 #endif 730