< prev index next >

src/hotspot/os_cpu/linux_s390/atomic_linux_s390.hpp

Print this page




  61 // Both, memory value and increment, are treated as 32bit signed binary integers.
  62 // No overflow exceptions are recognized, and the condition code does not hold
  63 // information about the value in memory.
  64 //
  65 // The value in memory is updated by using a compare-and-swap instruction. The
  66 // instruction is retried as often as required.
  67 //
  68 // The return value of the method is the value that was successfully stored. At the
  69 // time the caller receives back control, the value in memory may have changed already.
  70 
  71 // New atomic operations only include specific-operand-serialization, not full
  72 // memory barriers. We can use the Fast-BCR-Serialization Facility for them.
  73 inline void z196_fast_sync() {
  74   __asm__ __volatile__ ("bcr 14, 0" : : : "memory");
  75 }
  76 
  77 template<size_t byte_size>
  78 struct Atomic::PlatformAdd
  79   : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
  80 {
  81   template<typename I, typename D>
  82   D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) const;
  83 };
  84 
  85 template<>
  86 template<typename I, typename D>
  87 inline D Atomic::PlatformAdd<4>::add_and_fetch(I inc, D volatile* dest,
  88                                                atomic_memory_order order) const {
  89   STATIC_ASSERT(4 == sizeof(I));
  90   STATIC_ASSERT(4 == sizeof(D));
  91 
  92   D old, upd;
  93 
  94   if (VM_Version::has_LoadAndALUAtomicV1()) {
  95     if (order == memory_order_conservative) { z196_fast_sync(); }
  96     __asm__ __volatile__ (
  97       "   LGFR     0,%[inc]                \n\t" // save increment
  98       "   LA       3,%[mem]                \n\t" // force data address into ARG2
  99 //    "   LAA      %[upd],%[inc],%[mem]    \n\t" // increment and get old value
 100 //    "   LAA      2,0,0(3)                \n\t" // actually coded instruction
 101       "   .byte    0xeb                    \n\t" // LAA main opcode
 102       "   .byte    0x20                    \n\t" // R1,R3
 103       "   .byte    0x30                    \n\t" // R2,disp1
 104       "   .byte    0x00                    \n\t" // disp2,disp3
 105       "   .byte    0x00                    \n\t" // disp4,disp5
 106       "   .byte    0xf8                    \n\t" // LAA minor opcode
 107       "   AR       2,0                     \n\t" // calc new value in register


 120       "   LLGF     %[old],%[mem]           \n\t" // get old value
 121       "0: LA       %[upd],0(%[inc],%[old]) \n\t" // calc result
 122       "   CS       %[old],%[upd],%[mem]    \n\t" // try to xchg res with mem
 123       "   JNE      0b                      \n\t" // no success? -> retry
 124       //---<  outputs  >---
 125       : [old] "=&a" (old)    // write-only, old counter value
 126       , [upd] "=&d" (upd)    // write-only, updated counter value
 127       , [mem] "+Q"  (*dest)  // read/write, memory to be updated atomically
 128       //---<  inputs  >---
 129       : [inc] "a"   (inc)    // read-only.
 130       //---<  clobbered  >---
 131       : "cc", "memory"
 132     );
 133   }
 134 
 135   return upd;
 136 }
 137 
 138 
 139 template<>
 140 template<typename I, typename D>
 141 inline D Atomic::PlatformAdd<8>::add_and_fetch(I inc, D volatile* dest,
 142                                                atomic_memory_order order) const {
 143   STATIC_ASSERT(8 == sizeof(I));
 144   STATIC_ASSERT(8 == sizeof(D));
 145 
 146   D old, upd;
 147 
 148   if (VM_Version::has_LoadAndALUAtomicV1()) {
 149     if (order == memory_order_conservative) { z196_fast_sync(); }
 150     __asm__ __volatile__ (
 151       "   LGR      0,%[inc]                \n\t" // save increment
 152       "   LA       3,%[mem]                \n\t" // force data address into ARG2
 153 //    "   LAAG     %[upd],%[inc],%[mem]    \n\t" // increment and get old value
 154 //    "   LAAG     2,0,0(3)                \n\t" // actually coded instruction
 155       "   .byte    0xeb                    \n\t" // LAA main opcode
 156       "   .byte    0x20                    \n\t" // R1,R3
 157       "   .byte    0x30                    \n\t" // R2,disp1
 158       "   .byte    0x00                    \n\t" // disp2,disp3
 159       "   .byte    0x00                    \n\t" // disp4,disp5
 160       "   .byte    0xe8                    \n\t" // LAA minor opcode
 161       "   AGR      2,0                     \n\t" // calc new value in register




  61 // Both, memory value and increment, are treated as 32bit signed binary integers.
  62 // No overflow exceptions are recognized, and the condition code does not hold
  63 // information about the value in memory.
  64 //
  65 // The value in memory is updated by using a compare-and-swap instruction. The
  66 // instruction is retried as often as required.
  67 //
  68 // The return value of the method is the value that was successfully stored. At the
  69 // time the caller receives back control, the value in memory may have changed already.
  70 
  71 // New atomic operations only include specific-operand-serialization, not full
  72 // memory barriers. We can use the Fast-BCR-Serialization Facility for them.
  73 inline void z196_fast_sync() {
  74   __asm__ __volatile__ ("bcr 14, 0" : : : "memory");
  75 }
  76 
  77 template<size_t byte_size>
  78 struct Atomic::PlatformAdd
  79   : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
  80 {
  81   template<typename D, typename I>
  82   D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const;
  83 };
  84 
  85 template<>
  86 template<typename D, typename I>
  87 inline D Atomic::PlatformAdd<4>::add_and_fetch(D volatile* dest, I inc,
  88                                                atomic_memory_order order) const {
  89   STATIC_ASSERT(4 == sizeof(I));
  90   STATIC_ASSERT(4 == sizeof(D));
  91 
  92   D old, upd;
  93 
  94   if (VM_Version::has_LoadAndALUAtomicV1()) {
  95     if (order == memory_order_conservative) { z196_fast_sync(); }
  96     __asm__ __volatile__ (
  97       "   LGFR     0,%[inc]                \n\t" // save increment
  98       "   LA       3,%[mem]                \n\t" // force data address into ARG2
  99 //    "   LAA      %[upd],%[inc],%[mem]    \n\t" // increment and get old value
 100 //    "   LAA      2,0,0(3)                \n\t" // actually coded instruction
 101       "   .byte    0xeb                    \n\t" // LAA main opcode
 102       "   .byte    0x20                    \n\t" // R1,R3
 103       "   .byte    0x30                    \n\t" // R2,disp1
 104       "   .byte    0x00                    \n\t" // disp2,disp3
 105       "   .byte    0x00                    \n\t" // disp4,disp5
 106       "   .byte    0xf8                    \n\t" // LAA minor opcode
 107       "   AR       2,0                     \n\t" // calc new value in register


 120       "   LLGF     %[old],%[mem]           \n\t" // get old value
 121       "0: LA       %[upd],0(%[inc],%[old]) \n\t" // calc result
 122       "   CS       %[old],%[upd],%[mem]    \n\t" // try to xchg res with mem
 123       "   JNE      0b                      \n\t" // no success? -> retry
 124       //---<  outputs  >---
 125       : [old] "=&a" (old)    // write-only, old counter value
 126       , [upd] "=&d" (upd)    // write-only, updated counter value
 127       , [mem] "+Q"  (*dest)  // read/write, memory to be updated atomically
 128       //---<  inputs  >---
 129       : [inc] "a"   (inc)    // read-only.
 130       //---<  clobbered  >---
 131       : "cc", "memory"
 132     );
 133   }
 134 
 135   return upd;
 136 }
 137 
 138 
 139 template<>
 140 template<typename D, typename I>
 141 inline D Atomic::PlatformAdd<8>::add_and_fetch(D volatile* dest, I inc,
 142                                                atomic_memory_order order) const {
 143   STATIC_ASSERT(8 == sizeof(I));
 144   STATIC_ASSERT(8 == sizeof(D));
 145 
 146   D old, upd;
 147 
 148   if (VM_Version::has_LoadAndALUAtomicV1()) {
 149     if (order == memory_order_conservative) { z196_fast_sync(); }
 150     __asm__ __volatile__ (
 151       "   LGR      0,%[inc]                \n\t" // save increment
 152       "   LA       3,%[mem]                \n\t" // force data address into ARG2
 153 //    "   LAAG     %[upd],%[inc],%[mem]    \n\t" // increment and get old value
 154 //    "   LAAG     2,0,0(3)                \n\t" // actually coded instruction
 155       "   .byte    0xeb                    \n\t" // LAA main opcode
 156       "   .byte    0x20                    \n\t" // R1,R3
 157       "   .byte    0x30                    \n\t" // R2,disp1
 158       "   .byte    0x00                    \n\t" // disp2,disp3
 159       "   .byte    0x00                    \n\t" // disp4,disp5
 160       "   .byte    0xe8                    \n\t" // LAA minor opcode
 161       "   AGR      2,0                     \n\t" // calc new value in register


< prev index next >