src/hotspot/os_cpu/solaris_sparc/atomic_solaris_sparc.hpp
changeset 47578 09c41c4913d9
parent 47552 8a3599d60996
child 47593 2d56326b98f0
equal deleted inserted replaced
47577:14aa557af8ba 47578:09c41c4913d9
    41 
    41 
    42 inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; }
    42 inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; }
    43 inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; }
    43 inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; }
    44 inline jlong Atomic::load(const volatile jlong* src) { return *src; }
    44 inline jlong Atomic::load(const volatile jlong* src) { return *src; }
    45 
    45 
    46 
       
    47 // This is the interface to the atomic instructions in solaris_sparc.il.
       
    48 // It's very messy because we need to support v8 and these instructions
       
    49 // are illegal there.  When sparc v8 is dropped, we can drop out lots of
       
    50 // this code.  Also compiler2 does not support v8 so the conditional code
       
    51 // omits the instruction set check.
       
    52 
       
    53 extern "C" jint     _Atomic_swap32(jint     exchange_value, volatile jint*     dest);
       
    54 extern "C" intptr_t _Atomic_swap64(intptr_t exchange_value, volatile intptr_t* dest);
       
    55 
       
    56 // Implement ADD using a CAS loop.
    46 // Implement ADD using a CAS loop.
    57 template<size_t byte_size>
    47 template<size_t byte_size>
    58 struct Atomic::PlatformAdd VALUE_OBJ_CLASS_SPEC {
    48 struct Atomic::PlatformAdd VALUE_OBJ_CLASS_SPEC {
    59   template<typename I, typename D>
    49   template<typename I, typename D>
    60   inline D operator()(I add_value, D volatile* dest) const {
    50   inline D operator()(I add_value, D volatile* dest) const {
    67     }
    57     }
    68     return old_value + add_value;
    58     return old_value + add_value;
    69   }
    59   }
    70 };
    60 };
    71 
    61 
    72 inline jint     Atomic::xchg    (jint     exchange_value, volatile jint*     dest) {
    62 template<>
    73   return _Atomic_swap32(exchange_value, dest);
    63 template<typename T>
       
    64 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
       
    65                                              T volatile* dest) const {
       
    66   STATIC_ASSERT(4 == sizeof(T));
       
    67   __asm__ volatile (  "swap [%2],%0"
       
    68                     : "=r" (exchange_value)
       
    69                     : "0" (exchange_value), "r" (dest)
       
    70                     : "memory");
       
    71   return exchange_value;
    74 }
    72 }
    75 
    73 
    76 inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
    74 template<>
    77   return _Atomic_swap64(exchange_value, dest);
    75 template<typename T>
    78 }
    76 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value,
    79 
    77                                              T volatile* dest) const {
    80 inline void*    Atomic::xchg_ptr(void*    exchange_value, volatile void*     dest) {
    78   STATIC_ASSERT(8 == sizeof(T));
    81   return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
    79   T old_value = *dest;
       
    80   while (true) {
       
    81     T result = cmpxchg(exchange_value, dest, old_value);
       
    82     if (result == old_value) break;
       
    83     old_value = result;
       
    84   }
       
    85   return old_value;
    82 }
    86 }
    83 
    87 
    84 // No direct support for cmpxchg of bytes; emulate using int.
    88 // No direct support for cmpxchg of bytes; emulate using int.
    85 template<>
    89 template<>
    86 struct Atomic::PlatformCmpxchg<1> : Atomic::CmpxchgByteUsingInt {};
    90 struct Atomic::PlatformCmpxchg<1> : Atomic::CmpxchgByteUsingInt {};