root/opal/include/opal/sys/atomic_impl.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. opal_atomic_fetch_min_32
  2. opal_atomic_fetch_max_32
  3. opal_atomic_swap_32
  4. OPAL_ATOMIC_DEFINE_CMPXCG_OP
  5. opal_atomic_fetch_max_64
  6. opal_atomic_swap_64
  7. opal_atomic_add_xx
  8. opal_atomic_sub_xx
  9. OPAL_ATOMIC_DEFINE_OP_FETCH
  10. opal_atomic_max_fetch_32
  11. OPAL_ATOMIC_DEFINE_OP_FETCH
  12. opal_atomic_max_fetch_64
  13. opal_atomic_fetch_add_ptr
  14. opal_atomic_add_fetch_ptr
  15. opal_atomic_fetch_sub_ptr
  16. opal_atomic_sub_fetch_ptr
  17. opal_atomic_lock_init
  18. opal_atomic_trylock
  19. opal_atomic_lock
  20. opal_atomic_unlock

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2014 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2010-2014 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2012-2018 Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 /* Inline C implementation of the functions defined in atomic.h */
  24 
  25 #include <stdlib.h>
  26 
  27 /**********************************************************************
  28  *
  29  * Atomic math operations
  30  *
  31  * All the architectures provide a compare_and_set atomic operations. If
  32  * they dont provide atomic additions and/or substractions then we can
  33  * define these operations using the atomic compare_and_set.
  34  *
  35  * Some architectures do not provide support for the 64 bits
  36  * atomic operations. Until we find a better solution let's just
  37  * undefine all those functions if there is no 64 bit compare-exchange
  38  *
  39  *********************************************************************/
  40 #if OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32
  41 
  42 #if !defined(OPAL_HAVE_ATOMIC_MIN_32)
  43 static inline int32_t opal_atomic_fetch_min_32 (opal_atomic_int32_t *addr, int32_t value)
  44 {
  45     int32_t old = *addr;
  46     do {
  47         if (old <= value) {
  48             break;
  49         }
  50     } while (!opal_atomic_compare_exchange_strong_32 (addr, &old, value));
  51 
  52     return old;
  53 }
  54 
  55 #define OPAL_HAVE_ATOMIC_MIN_32 1
  56 
  57 #endif /* OPAL_HAVE_ATOMIC_MIN_32 */
  58 
  59 #if !defined(OPAL_HAVE_ATOMIC_MAX_32)
  60 static inline int32_t opal_atomic_fetch_max_32 (opal_atomic_int32_t *addr, int32_t value)
  61 {
  62     int32_t old = *addr;
  63     do {
  64         if (old >= value) {
  65             break;
  66         }
  67     } while (!opal_atomic_compare_exchange_strong_32 (addr, &old, value));
  68 
  69     return old;
  70 }
  71 
  72 #define OPAL_HAVE_ATOMIC_MAX_32 1
  73 #endif /* OPAL_HAVE_ATOMIC_MAX_32 */
  74 
  75 #define OPAL_ATOMIC_DEFINE_CMPXCG_OP(type, bits, operation, name)  \
  76     static inline type opal_atomic_fetch_ ## name ## _ ## bits (opal_atomic_ ## type *addr, type value) \
  77     {                                                                   \
  78         type oldval;                                                    \
  79         do {                                                            \
  80             oldval = *addr;                                             \
  81         } while (!opal_atomic_compare_exchange_strong_ ## bits (addr, &oldval, oldval operation value)); \
  82                                                                         \
  83         return oldval;                                                  \
  84     }
  85 
  86 #if !defined(OPAL_HAVE_ATOMIC_SWAP_32)
  87 #define OPAL_HAVE_ATOMIC_SWAP_32 1
  88 static inline int32_t opal_atomic_swap_32(opal_atomic_int32_t *addr,
  89                                           int32_t newval)
  90 {
  91     int32_t old = *addr;
  92     do {
  93     } while (!opal_atomic_compare_exchange_strong_32 (addr, &old, newval));
  94 
  95     return old;
  96 }
  97 #endif /* OPAL_HAVE_ATOMIC_SWAP_32 */
  98 
  99 #if !defined(OPAL_HAVE_ATOMIC_ADD_32)
 100 #define OPAL_HAVE_ATOMIC_ADD_32 1
 101 
 102 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int32_t, 32, +, add)
 103 
 104 #endif  /* OPAL_HAVE_ATOMIC_ADD_32 */
 105 
 106 #if !defined(OPAL_HAVE_ATOMIC_AND_32)
 107 #define OPAL_HAVE_ATOMIC_AND_32 1
 108 
 109 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int32_t, 32, &, and)
 110 
 111 #endif  /* OPAL_HAVE_ATOMIC_AND_32 */
 112 
 113 #if !defined(OPAL_HAVE_ATOMIC_OR_32)
 114 #define OPAL_HAVE_ATOMIC_OR_32 1
 115 
 116 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int32_t, 32, |, or)
 117 
 118 #endif  /* OPAL_HAVE_ATOMIC_OR_32 */
 119 
 120 #if !defined(OPAL_HAVE_ATOMIC_XOR_32)
 121 #define OPAL_HAVE_ATOMIC_XOR_32 1
 122 
 123 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int32_t, 32, ^, xor)
 124 
 125 #endif  /* OPAL_HAVE_ATOMIC_XOR_32 */
 126 
 127 
 128 #if !defined(OPAL_HAVE_ATOMIC_SUB_32)
 129 #define OPAL_HAVE_ATOMIC_SUB_32 1
 130 
 131 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int32_t, 32, -, sub)
 132 
 133 #endif  /* OPAL_HAVE_ATOMIC_SUB_32 */
 134 
 135 #endif /* OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 */
 136 
 137 
 138 #if OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64
 139 
 140 #if !defined(OPAL_HAVE_ATOMIC_MIN_64)
 141 static inline int64_t opal_atomic_fetch_min_64 (opal_atomic_int64_t *addr, int64_t value)
 142 {
 143     int64_t old = *addr;
 144     do {
 145         if (old <= value) {
 146             break;
 147         }
 148     } while (!opal_atomic_compare_exchange_strong_64 (addr, &old, value));
 149 
 150     return old;
 151 }
 152 
 153 #define OPAL_HAVE_ATOMIC_MIN_64 1
 154 
 155 #endif /* OPAL_HAVE_ATOMIC_MIN_64 */
 156 
 157 #if !defined(OPAL_HAVE_ATOMIC_MAX_64)
 158 static inline int64_t opal_atomic_fetch_max_64 (opal_atomic_int64_t *addr, int64_t value)
 159 {
 160     int64_t old = *addr;
 161     do {
 162         if (old >= value) {
 163             break;
 164         }
 165     } while (!opal_atomic_compare_exchange_strong_64 (addr, &old, value));
 166 
 167     return old;
 168 }
 169 
 170 #define OPAL_HAVE_ATOMIC_MAX_64 1
 171 #endif /* OPAL_HAVE_ATOMIC_MAX_64 */
 172 
 173 #if !defined(OPAL_HAVE_ATOMIC_SWAP_64)
 174 #define OPAL_HAVE_ATOMIC_SWAP_64 1
 175 static inline int64_t opal_atomic_swap_64(opal_atomic_int64_t *addr,
 176                                           int64_t newval)
 177 {
 178     int64_t old = *addr;
 179     do {
 180     } while (!opal_atomic_compare_exchange_strong_64 (addr, &old, newval));
 181 
 182     return old;
 183 }
 184 #endif /* OPAL_HAVE_ATOMIC_SWAP_64 */
 185 
 186 #if !defined(OPAL_HAVE_ATOMIC_ADD_64)
 187 #define OPAL_HAVE_ATOMIC_ADD_64 1
 188 
 189 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int64_t, 64, +, add)
 190 
 191 #endif  /* OPAL_HAVE_ATOMIC_ADD_64 */
 192 
 193 #if !defined(OPAL_HAVE_ATOMIC_AND_64)
 194 #define OPAL_HAVE_ATOMIC_AND_64 1
 195 
 196 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int64_t, 64, &, and)
 197 
 198 #endif  /* OPAL_HAVE_ATOMIC_AND_64 */
 199 
 200 #if !defined(OPAL_HAVE_ATOMIC_OR_64)
 201 #define OPAL_HAVE_ATOMIC_OR_64 1
 202 
 203 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int64_t, 64, |, or)
 204 
 205 #endif  /* OPAL_HAVE_ATOMIC_OR_64 */
 206 
 207 #if !defined(OPAL_HAVE_ATOMIC_XOR_64)
 208 #define OPAL_HAVE_ATOMIC_XOR_64 1
 209 
 210 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int64_t, 64, ^, xor)
 211 
 212 #endif  /* OPAL_HAVE_ATOMIC_XOR_64 */
 213 
 214 #if !defined(OPAL_HAVE_ATOMIC_SUB_64)
 215 #define OPAL_HAVE_ATOMIC_SUB_64 1
 216 
 217 OPAL_ATOMIC_DEFINE_CMPXCG_OP(int64_t, 64, -, sub)
 218 
 219 #endif  /* OPAL_HAVE_ATOMIC_SUB_64 */
 220 
 221 #else
 222 
 223 #if !defined(OPAL_HAVE_ATOMIC_ADD_64)
 224 #define OPAL_HAVE_ATOMIC_ADD_64 0
 225 #endif
 226 
 227 #if !defined(OPAL_HAVE_ATOMIC_SUB_64)
 228 #define OPAL_HAVE_ATOMIC_SUB_64 0
 229 #endif
 230 
 231 #endif  /* OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64 */
 232 
 233 #if (OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 || OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64)
 234 
 235 #if OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 && OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64
 236 #define OPAL_ATOMIC_DEFINE_CMPXCG_XX(semantics)                         \
 237     static inline bool                                                  \
 238     opal_atomic_compare_exchange_strong ## semantics ## xx (opal_atomic_intptr_t* addr, intptr_t *oldval, \
 239                                                             int64_t newval, const size_t length) \
 240     {                                                                   \
 241         switch (length) {                                               \
 242         case 4:                                                         \
 243             return opal_atomic_compare_exchange_strong_32 ((opal_atomic_int32_t *) addr, \
 244                                                            (int32_t *) oldval, (int32_t) newval); \
 245         case 8:                                                         \
 246             return opal_atomic_compare_exchange_strong_64 ((opal_atomic_int64_t *) addr, \
 247                                                            (int64_t *) oldval, (int64_t) newval); \
 248         }                                                               \
 249         abort();                                                        \
 250     }
 251 #elif OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32
 252 #define OPAL_ATOMIC_DEFINE_CMPXCG_XX(semantics)                         \
 253     static inline bool                                                  \
 254     opal_atomic_compare_exchange_strong ## semantics ## xx (opal_atomic_intptr_t* addr, intptr_t *oldval, \
 255                                                             int64_t newval, const size_t length) \
 256     {                                                                   \
 257         switch (length) {                                               \
 258         case 4:                                                         \
 259             return opal_atomic_compare_exchange_strong_32 ((opal_atomic_int32_t *) addr, \
 260                                                            (int32_t *) oldval, (int32_t) newval); \
 261         }                                                               \
 262         abort();                                                        \
 263     }
 264 #else
 265 #error "Platform does not have required atomic compare-and-swap functionality"
 266 #endif
 267 
 268 OPAL_ATOMIC_DEFINE_CMPXCG_XX(_)
 269 OPAL_ATOMIC_DEFINE_CMPXCG_XX(_acq_)
 270 OPAL_ATOMIC_DEFINE_CMPXCG_XX(_rel_)
 271 
 272 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32
 273 #define OPAL_ATOMIC_DEFINE_CMPXCG_PTR_XX(semantics)                     \
 274     static inline bool                                                  \
 275         opal_atomic_compare_exchange_strong ## semantics ## ptr (opal_atomic_intptr_t* addr, intptr_t *oldval, intptr_t newval) \
 276     {                                                                   \
 277         return opal_atomic_compare_exchange_strong_32 ((opal_atomic_int32_t *) addr, (int32_t *) oldval, (int32_t) newval); \
 278     }
 279 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64
 280 #define OPAL_ATOMIC_DEFINE_CMPXCG_PTR_XX(semantics)                     \
 281     static inline bool                                                  \
 282         opal_atomic_compare_exchange_strong ## semantics ## ptr (opal_atomic_intptr_t* addr, intptr_t *oldval, intptr_t newval) \
 283     {                                                                   \
 284         return opal_atomic_compare_exchange_strong_64 ((opal_atomic_int64_t *) addr, (int64_t *) oldval, (int64_t) newval); \
 285     }
 286 #else
 287 #error "Can not define opal_atomic_compare_exchange_strong_ptr with existing atomics"
 288 #endif
 289 
 290 OPAL_ATOMIC_DEFINE_CMPXCG_PTR_XX(_)
 291 OPAL_ATOMIC_DEFINE_CMPXCG_PTR_XX(_acq_)
 292 OPAL_ATOMIC_DEFINE_CMPXCG_PTR_XX(_rel_)
 293 
 294 #endif /* (OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 || OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64) */
 295 
 296 
 297 #if (OPAL_HAVE_ATOMIC_SWAP_32 || OPAL_HAVE_ATOMIC_SWAP_64)
 298 
 299 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_SWAP_32
 300 #define opal_atomic_swap_ptr(addr, value) (intptr_t) opal_atomic_swap_32((opal_atomic_int32_t *) addr, (int32_t) value)
 301 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_SWAP_64
 302 #define opal_atomic_swap_ptr(addr, value) (intptr_t) opal_atomic_swap_64((opal_atomic_int64_t *) addr, (int64_t) value)
 303 #endif
 304 
 305 #endif /* (OPAL_HAVE_ATOMIC_SWAP_32 || OPAL_HAVE_ATOMIC_SWAP_64) */
 306 
 307 #if (OPAL_HAVE_ATOMIC_LLSC_32 || OPAL_HAVE_ATOMIC_LLSC_64)
 308 
 309 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_LLSC_32
 310 
 311 #define opal_atomic_ll_ptr(addr, ret) opal_atomic_ll_32((opal_atomic_int32_t *) (addr), ret)
 312 #define opal_atomic_sc_ptr(addr, value, ret) opal_atomic_sc_32((opal_atomic_int32_t *) (addr), (intptr_t) (value), ret)
 313 
 314 #define OPAL_HAVE_ATOMIC_LLSC_PTR 1
 315 
 316 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_LLSC_64
 317 
 318 #define opal_atomic_ll_ptr(addr, ret) opal_atomic_ll_64((opal_atomic_int64_t *) (addr), ret)
 319 #define opal_atomic_sc_ptr(addr, value, ret) opal_atomic_sc_64((opal_atomic_int64_t *) (addr), (intptr_t) (value), ret)
 320 
 321 #define OPAL_HAVE_ATOMIC_LLSC_PTR 1
 322 
 323 #endif
 324 
 325 #endif /* (OPAL_HAVE_ATOMIC_LLSC_32 || OPAL_HAVE_ATOMIC_LLSC_64)*/
 326 
 327 #if !defined(OPAL_HAVE_ATOMIC_LLSC_PTR)
 328 #define OPAL_HAVE_ATOMIC_LLSC_PTR 0
 329 #endif
 330 
 331 #if OPAL_HAVE_ATOMIC_MATH_32 || OPAL_HAVE_ATOMIC_MATH_64
 332 
 333 static inline void
 334     opal_atomic_add_xx(opal_atomic_intptr_t* addr, int32_t value, size_t length)
 335 {
 336    switch( length ) {
 337 #if OPAL_HAVE_ATOMIC_ADD_32
 338    case 4:
 339        (void) opal_atomic_fetch_add_32( (opal_atomic_int32_t*)addr, (int32_t)value );
 340       break;
 341 #endif  /* OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 */
 342 
 343 #if OPAL_HAVE_ATOMIC_ADD_64
 344    case 8:
 345        (void) opal_atomic_fetch_add_64( (opal_atomic_int64_t*)addr, (int64_t)value );
 346       break;
 347 #endif  /* OPAL_HAVE_ATOMIC_ADD_64 */
 348    default:
 349        /* This should never happen, so deliberately abort (hopefully
 350           leaving a corefile for analysis) */
 351        abort();
 352    }
 353 }
 354 
 355 
 356 static inline void
 357 opal_atomic_sub_xx(opal_atomic_intptr_t* addr, int32_t value, size_t length)
 358 {
 359    switch( length ) {
 360 #if OPAL_HAVE_ATOMIC_SUB_32
 361    case 4:
 362        (void) opal_atomic_fetch_sub_32( (opal_atomic_int32_t*)addr, (int32_t)value );
 363       break;
 364 #endif  /* OPAL_HAVE_ATOMIC_SUB_32 */
 365 
 366 #if OPAL_HAVE_ATOMIC_SUB_64
 367    case 8:
 368        (void) opal_atomic_fetch_sub_64( (opal_atomic_int64_t*)addr, (int64_t)value );
 369       break;
 370 #endif  /* OPAL_HAVE_ATOMIC_SUB_64 */
 371    default:
 372        /* This should never happen, so deliberately abort (hopefully
 373           leaving a corefile for analysis) */
 374        abort();
 375    }
 376 }
 377 
 378 #define OPAL_ATOMIC_DEFINE_OP_FETCH(op, operation, type, ptr_type, suffix) \
 379     static inline type opal_atomic_ ## op ## _fetch_ ## suffix (opal_atomic_ ## ptr_type *addr, type value) \
 380     {                                                                   \
 381         return opal_atomic_fetch_ ## op ## _ ## suffix (addr, value) operation value; \
 382     }
 383 
 384 OPAL_ATOMIC_DEFINE_OP_FETCH(add, +, int32_t, int32_t, 32)
 385 OPAL_ATOMIC_DEFINE_OP_FETCH(and, &, int32_t, int32_t, 32)
 386 OPAL_ATOMIC_DEFINE_OP_FETCH(or, |, int32_t, int32_t, 32)
 387 OPAL_ATOMIC_DEFINE_OP_FETCH(xor, ^, int32_t, int32_t, 32)
 388 OPAL_ATOMIC_DEFINE_OP_FETCH(sub, -, int32_t, int32_t, 32)
 389 
 390 static inline int32_t opal_atomic_min_fetch_32 (opal_atomic_int32_t *addr, int32_t value)
 391 {
 392     int32_t old = opal_atomic_fetch_min_32 (addr, value);
 393     return old <= value ? old : value;
 394 }
 395 
 396 static inline int32_t opal_atomic_max_fetch_32 (opal_atomic_int32_t *addr, int32_t value)
 397 {
 398     int32_t old = opal_atomic_fetch_max_32 (addr, value);
 399     return old >= value ? old : value;
 400 }
 401 
 402 #if OPAL_HAVE_ATOMIC_MATH_64
 403 OPAL_ATOMIC_DEFINE_OP_FETCH(add, +, int64_t, int64_t, 64)
 404 OPAL_ATOMIC_DEFINE_OP_FETCH(and, &, int64_t, int64_t, 64)
 405 OPAL_ATOMIC_DEFINE_OP_FETCH(or, |, int64_t, int64_t, 64)
 406 OPAL_ATOMIC_DEFINE_OP_FETCH(xor, ^, int64_t, int64_t, 64)
 407 OPAL_ATOMIC_DEFINE_OP_FETCH(sub, -, int64_t, int64_t, 64)
 408 
 409 static inline int64_t opal_atomic_min_fetch_64 (opal_atomic_int64_t *addr, int64_t value)
 410 {
 411     int64_t old = opal_atomic_fetch_min_64 (addr, value);
 412     return old <= value ? old : value;
 413 }
 414 
 415 static inline int64_t opal_atomic_max_fetch_64 (opal_atomic_int64_t *addr, int64_t value)
 416 {
 417     int64_t old = opal_atomic_fetch_max_64 (addr, value);
 418     return old >= value ? old : value;
 419 }
 420 
 421 #endif
 422 
 423 static inline intptr_t opal_atomic_fetch_add_ptr( opal_atomic_intptr_t* addr,
 424                                            void* delta )
 425 {
 426 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_ADD_32
 427     return opal_atomic_fetch_add_32((opal_atomic_int32_t*) addr, (unsigned long) delta);
 428 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_ADD_64
 429     return opal_atomic_fetch_add_64((opal_atomic_int64_t*) addr, (unsigned long) delta);
 430 #else
 431     abort ();
 432     return 0;
 433 #endif
 434 }
 435 
 436 static inline intptr_t opal_atomic_add_fetch_ptr( opal_atomic_intptr_t* addr,
 437                                            void* delta )
 438 {
 439 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_ADD_32
 440     return opal_atomic_add_fetch_32((opal_atomic_int32_t*) addr, (unsigned long) delta);
 441 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_ADD_64
 442     return opal_atomic_add_fetch_64((opal_atomic_int64_t*) addr, (unsigned long) delta);
 443 #else
 444     abort ();
 445     return 0;
 446 #endif
 447 }
 448 
 449 static inline intptr_t opal_atomic_fetch_sub_ptr( opal_atomic_intptr_t* addr,
 450                                            void* delta )
 451 {
 452 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_SUB_32
 453     return opal_atomic_fetch_sub_32((opal_atomic_int32_t*) addr, (unsigned long) delta);
 454 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_SUB_32
 455     return opal_atomic_fetch_sub_64((opal_atomic_int64_t*) addr, (unsigned long) delta);
 456 #else
 457     abort();
 458     return 0;
 459 #endif
 460 }
 461 
 462 static inline intptr_t opal_atomic_sub_fetch_ptr( opal_atomic_intptr_t* addr,
 463                                            void* delta )
 464 {
 465 #if SIZEOF_VOID_P == 4 && OPAL_HAVE_ATOMIC_SUB_32
 466     return opal_atomic_sub_fetch_32((opal_atomic_int32_t*) addr, (unsigned long) delta);
 467 #elif SIZEOF_VOID_P == 8 && OPAL_HAVE_ATOMIC_SUB_32
 468     return opal_atomic_sub_fetch_64((opal_atomic_int64_t*) addr, (unsigned long) delta);
 469 #else
 470     abort();
 471     return 0;
 472 #endif
 473 }
 474 
 475 #endif /* OPAL_HAVE_ATOMIC_MATH_32 || OPAL_HAVE_ATOMIC_MATH_64 */
 476 
 477 /**********************************************************************
 478  *
 479  * Atomic spinlocks
 480  *
 481  *********************************************************************/
 482 #ifdef OPAL_NEED_INLINE_ATOMIC_SPINLOCKS
 483 
 484 /*
 485  * Lock initialization function. It set the lock to UNLOCKED.
 486  */
 487 static inline void
 488 opal_atomic_lock_init( opal_atomic_lock_t* lock, int32_t value )
 489 {
 490    lock->u.lock = value;
 491 }
 492 
 493 
 494 static inline int
 495 opal_atomic_trylock(opal_atomic_lock_t *lock)
 496 {
 497     int32_t unlocked = OPAL_ATOMIC_LOCK_UNLOCKED;
 498     bool ret = opal_atomic_compare_exchange_strong_acq_32 (&lock->u.lock, &unlocked, OPAL_ATOMIC_LOCK_LOCKED);
 499     return (ret == false) ? 1 : 0;
 500 }
 501 
 502 
 503 static inline void
 504 opal_atomic_lock(opal_atomic_lock_t *lock)
 505 {
 506     while (opal_atomic_trylock (lock)) {
 507         while (lock->u.lock == OPAL_ATOMIC_LOCK_LOCKED) {
 508             /* spin */ ;
 509         }
 510     }
 511 }
 512 
 513 
 514 static inline void
 515 opal_atomic_unlock(opal_atomic_lock_t *lock)
 516 {
 517    opal_atomic_wmb();
 518    lock->u.lock=OPAL_ATOMIC_LOCK_UNLOCKED;
 519 }
 520 
 521 #endif /* OPAL_HAVE_ATOMIC_SPINLOCKS */

/* [<][>][^][v][top][bottom][index][help] */