| 464 | #elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX) |
| 465 | |
| 466 | #include <builtins.h> |
| 467 | |
| 468 | namespace boost { |
| 469 | namespace interprocess { |
| 470 | namespace detail{ |
| 471 | |
| 472 | //first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting |
| 473 | //all the functions with casts |
| 474 | |
| 475 | //! From XLC documenation : |
| 476 | //! This function can be used with a subsequent stwcxu call to implement a |
| 477 | //! read-modify-write on a specified memory location. The two functions work |
| 478 | //! together to ensure that if the store is successfully performed, no other |
| 479 | //! processor or mechanism can modify the target doubleword between the time |
| 480 | //! lwarxu function is executed and the time the stwcxu functio ncompletes. |
| 481 | //! "mem" : pointer to the object |
| 482 | //! Returns the value at pointed to by mem |
| 483 | inline boost::uint32_t lwarxu(volatile boost::uint32_t *mem) |
| 484 | { |
| 485 | return static_cast<boost::uint32_t>(__lwarx(reinterpret_cast<volatile int*>(mem))); |
| 486 | } |
| 487 | |
| 488 | //! "mem" : pointer to the object |
| 489 | //! "val" : the value to store |
| 490 | //! Returns true if the update of mem is successful and false if it is |
| 491 | //!unsuccessful |
| 492 | inline bool stwcxu(volatile boost::uint32_t* mem, boost::uint32_t val) |
| 493 | { |
| 494 | return (__stwcx(reinterpret_cast<volatile int*>(mem), static_cast<int>(val)) != 0); |
| 495 | } |
| 496 | |
| 497 | //! "mem": pointer to the object |
| 498 | //! "val": amount to add |
| 499 | //! Returns the old value pointed to by mem |
| 500 | inline boost::uint32_t atomic_add32 |
| 501 | (volatile boost::uint32_t *mem, boost::uint32_t val) |
| 502 | { |
| 503 | boost::uint32_t oldValue; |
| 504 | do |
| 505 | { |
| 506 | oldValue = lwarxu(mem); |
| 507 | }while (!stwcxu(mem, oldValue+val)); |
| 508 | return oldValue; |
| 509 | } |
| 510 | |
| 511 | //! Atomically increment an apr_uint32_t by 1 |
| 512 | //! "mem": pointer to the object |
| 513 | //! Returns the old value pointed to by mem |
| 514 | inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
| 515 | { return atomic_add32(mem, 1); } |
| 516 | |
| 517 | //! Atomically decrement an boost::uint32_t by 1 |
| 518 | //! "mem": pointer to the atomic value |
| 519 | //! Returns the old value pointed to by mem |
| 520 | inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
| 521 | { return atomic_add32(mem, (boost::uint32_t)-1); } |
| 522 | |
| 523 | //! Atomically read an boost::uint32_t from memory |
| 524 | inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
| 525 | { return *mem; } |
| 526 | |
| 527 | //! Compare an boost::uint32_t's value with "cmp". |
| 528 | //! If they are the same swap the value with "with" |
| 529 | //! "mem": pointer to the value |
| 530 | //! "with" what to swap it with |
| 531 | //! "cmp": the value to compare it to |
| 532 | //! Returns the old value of *mem |
| 533 | inline boost::uint32_t atomic_cas32 |
| 534 | (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
| 535 | { |
| 536 | boost::uint32_t oldValue; |
| 537 | boost::uint32_t valueToStore; |
| 538 | do |
| 539 | { |
| 540 | oldValue = lwarxu(mem); |
| 541 | } while (!stwcxu(mem, (oldValue == with) ? cmp : oldValue)); |
| 542 | |
| 543 | return oldValue; |
| 544 | } |
| 545 | |
| 546 | //! Atomically set an boost::uint32_t in memory |
| 547 | //! "mem": pointer to the object |
| 548 | //! "param": val value that the object will assume |
| 549 | inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
| 550 | { *mem = val; } |
| 551 | |
| 552 | } //namespace detail |
| 553 | } //namespace interprocess |
| 554 | } //namespace boost |
| 555 | |