< prev index next >

src/os_cpu/linux_s390/vm/atomic_linux_s390.hpp

Print this page
rev 13452 : [mq]: coleen_review1
rev 13453 : [mq]: dholmes_review1


 461 //
 462 // The return value is the (unchanged) value from memory as it was when the
 463 // compare-and-swap instruction completed. A successful exchange operation
 464 // is indicated by (return value == compare_value). If unsuccessful, a new
 465 // exchange value can be calculated based on the return value which is the
 466 // latest contents of the memory location.
 467 //
 468 // Inspecting the return value is the only way for the caller to determine
 469 // if the compare-and-swap instruction was successful:
 470 // - If return value and compare value compare equal, the compare-and-swap
 471 //   instruction was successful and the value in memory was replaced by the
 472 //   exchange value.
 473 // - If return value and compare value compare unequal, the compare-and-swap
 474 //   instruction was not successful. The value in memory was left unchanged.
 475 //
 476 // The s390 processors always fence before and after the csg instructions.
 477 // Thus we ignore the memory ordering argument. The docu says: "A serialization
 478 // function is performed before the operand is fetched and again after the
 479 // operation is completed."
 480 

 481 template<>
 482 struct Atomic::PlatformCmpxchg<1> : Atomic::CmpxchgByteUsingInt {};
 483 
 484 template<>
 485 template<typename T>
 486 inline T Atomic::PlatformCmpxchg<4>::operator()(T xchg_val,
 487                                                 T volatile* dest,
 488                                                 T cmp_val,
 489                                                 cmpxchg_memory_order unused) const {

 490   unsigned long old;
 491 
 492   __asm__ __volatile__ (
 493     "   CS       %[old],%[upd],%[mem]    \n\t" // Try to xchg upd with mem.
 494     // outputs
 495     : [old] "=&d" (old)      // Write-only, prev value irrelevant.
 496     , [mem] "+Q"  (*dest)    // Read/write, memory to be updated atomically.
 497     // inputs
 498     : [upd] "d"   (xchg_val)
 499     ,       "0"   (cmp_val)  // Read-only, initial value for [old] (operand #0).
 500     // clobbered
 501     : "cc"
 502   );
 503 
 504   return IntegerTypes::cast<T>((uint32_t)old);
 505 }
 506 
 507 template<>
 508 template<typename T>
 509 inline T Atomic::PlatformCmpxchg<8>::operator()(T xchg_val,
 510                                                 T volatile* dest,
 511                                                 T cmp_val,
 512                                                 cmpxchg_memory_order unused) const {
 513   unsigned long old;

 514 
 515   __asm__ __volatile__ (
 516     "   CSG      %[old],%[upd],%[mem]    \n\t" // Try to xchg upd with mem.
 517     // outputs
 518     : [old] "=&d" (old)      // Write-only, prev value irrelevant.
 519     , [mem] "+Q"  (*dest)    // Read/write, memory to be updated atomically.
 520     // inputs
 521     : [upd] "d"   (xchg_val)
 522     ,       "0"   (cmp_val)  // Read-only, initial value for [old] (operand #0).
 523     // clobbered
 524     : "cc"
 525   );
 526 
 527   return IntegerTypes::cast<T>(old);
 528 }
 529 
 530 inline jlong Atomic::load(const volatile jlong* src) { return *src; }
 531 
 532 #endif // OS_CPU_LINUX_S390_VM_ATOMIC_LINUX_S390_INLINE_HPP


 461 //
 462 // The return value is the (unchanged) value from memory as it was when the
 463 // compare-and-swap instruction completed. A successful exchange operation
 464 // is indicated by (return value == compare_value). If unsuccessful, a new
 465 // exchange value can be calculated based on the return value which is the
 466 // latest contents of the memory location.
 467 //
 468 // Inspecting the return value is the only way for the caller to determine
 469 // if the compare-and-swap instruction was successful:
 470 // - If return value and compare value compare equal, the compare-and-swap
 471 //   instruction was successful and the value in memory was replaced by the
 472 //   exchange value.
 473 // - If return value and compare value compare unequal, the compare-and-swap
 474 //   instruction was not successful. The value in memory was left unchanged.
 475 //
 476 // The s390 processors always fence before and after the csg instructions.
 477 // Thus we ignore the memory ordering argument. The docu says: "A serialization
 478 // function is performed before the operand is fetched and again after the
 479 // operation is completed."
 480 
 481 // No direct support for cmpxchg of bytes; emulate using int.
 482 template<>
 483 struct Atomic::PlatformCmpxchg<1> : Atomic::CmpxchgByteUsingInt {};
 484 
 485 template<>
 486 template<typename T>
 487 inline T Atomic::PlatformCmpxchg<4>::operator()(T xchg_val,
 488                                                 T volatile* dest,
 489                                                 T cmp_val,
 490                                                 cmpxchg_memory_order unused) const {
 491   STATIC_ASSERT(4 == sizeof(T));
 492   unsigned long old;
 493 
 494   __asm__ __volatile__ (
 495     "   CS       %[old],%[upd],%[mem]    \n\t" // Try to xchg upd with mem.
 496     // outputs
 497     : [old] "=&d" (old)      // Write-only, prev value irrelevant.
 498     , [mem] "+Q"  (*dest)    // Read/write, memory to be updated atomically.
 499     // inputs
 500     : [upd] "d"   (xchg_val)
 501     ,       "0"   (cmp_val)  // Read-only, initial value for [old] (operand #0).
 502     // clobbered
 503     : "cc"
 504   );
 505 
 506   return IntegerTypes::cast<T>((uint32_t)old);
 507 }
 508 
 509 template<>
 510 template<typename T>
 511 inline T Atomic::PlatformCmpxchg<8>::operator()(T xchg_val,
 512                                                 T volatile* dest,
 513                                                 T cmp_val,
 514                                                 cmpxchg_memory_order unused) const {
 515   STATIC_ASSERT(8 == sizeof(T));
 516   T old;
 517 
 518   __asm__ __volatile__ (
 519     "   CSG      %[old],%[upd],%[mem]    \n\t" // Try to xchg upd with mem.
 520     // outputs
 521     : [old] "=&d" (old)      // Write-only, prev value irrelevant.
 522     , [mem] "+Q"  (*dest)    // Read/write, memory to be updated atomically.
 523     // inputs
 524     : [upd] "d"   (xchg_val)
 525     ,       "0"   (cmp_val)  // Read-only, initial value for [old] (operand #0).
 526     // clobbered
 527     : "cc"
 528   );
 529 
 530   return old;
 531 }
 532 
 533 inline jlong Atomic::load(const volatile jlong* src) { return *src; }
 534 
 535 #endif // OS_CPU_LINUX_S390_VM_ATOMIC_LINUX_S390_INLINE_HPP
< prev index next >