< prev index next >

src/os_cpu/linux_s390/vm/atomic_linux_s390.hpp

Print this page
rev 13447 : imported patch linux_s390
rev 13452 : [mq]: coleen_review1
rev 13453 : [mq]: dholmes_review1
rev 13459 : [mq]: s390_fix


 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 jint Atomic::cmpxchg(jint xchg_val, volatile jint* dest, jint cmp_val, cmpxchg_memory_order unused) {
 482   unsigned long old;










 483 
 484   __asm__ __volatile__ (
 485     "   CS       %[old],%[upd],%[mem]    \n\t" // Try to xchg upd with mem.
 486     // outputs
 487     : [old] "=&d" (old)      // Write-only, prev value irrelevant.
 488     , [mem] "+Q"  (*dest)    // Read/write, memory to be updated atomically.
 489     // inputs
 490     : [upd] "d"   (xchg_val)
 491     ,       "0"   (cmp_val)  // Read-only, initial value for [old] (operand #0).
 492     // clobbered
 493     : "cc"
 494   );
 495 
 496   return (jint)old;
 497 }
 498 
 499 jlong Atomic::cmpxchg(jlong xchg_val, volatile jlong* dest, jlong cmp_val, cmpxchg_memory_order unused) {
 500   unsigned long old;






 501 
 502   __asm__ __volatile__ (
 503     "   CSG      %[old],%[upd],%[mem]    \n\t" // Try to xchg upd with mem.
 504     // outputs
 505     : [old] "=&d" (old)      // Write-only, prev value irrelevant.
 506     , [mem] "+Q"  (*dest)    // Read/write, memory to be updated atomically.
 507     // inputs
 508     : [upd] "d"   (xchg_val)
 509     ,       "0"   (cmp_val)  // Read-only, initial value for [old] (operand #0).
 510     // clobbered
 511     : "cc"
 512   );
 513 
 514   return (jlong)old;
 515 }
 516 
 517 void* Atomic::cmpxchg_ptr(void *xchg_val, volatile void* dest, void* cmp_val, cmpxchg_memory_order unused) {
 518   return (void*)cmpxchg((jlong)xchg_val, (volatile jlong*)dest, (jlong)cmp_val, unused);
 519 }
 520 
 521 intptr_t Atomic::cmpxchg_ptr(intptr_t xchg_val, volatile intptr_t* dest, intptr_t cmp_val, cmpxchg_memory_order unused) {
 522   return (intptr_t)cmpxchg((jlong)xchg_val, (volatile jlong*)dest, (jlong)cmp_val, unused);
 523 }
 524 
 525 inline jlong Atomic::load(const volatile jlong* src) { return *src; }
 526 
 527 #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   T 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 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 >