1 /* 2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP 26 #define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP 27 28 inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } 29 inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } 30 inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } 31 32 33 inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } 34 inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } 35 36 inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } 37 inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } 38 inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } 39 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } 40 inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } 41 42 inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); } 43 inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); } 44 inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); } 45 46 inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); } 47 inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } 48 inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } 49 50 // For Sun Studio - implementation is in solaris_x86_64.il. 51 52 extern "C" { 53 jint _Atomic_add(jint add_value, volatile jint* dest); 54 jint _Atomic_xchg(jint exchange_value, volatile jint* dest); 55 jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, 56 jbyte compare_value); 57 jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, 58 jint compare_value); 59 jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, 60 jlong compare_value); 61 } 62 63 inline jint Atomic::add (jint add_value, volatile jint* dest) { 64 return _Atomic_add(add_value, dest); 65 } 66 67 inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { 68 return _Atomic_xchg(exchange_value, dest); 69 } 70 71 // Not using cmpxchg_using_helper here, because some configurations of 72 // Solaris compiler don't deal well with passing a "defined in .il" 73 // function as an argument. We *should* switch to using gcc-style 74 // inline assembly, but attempting to do so with Studio 12.4 ran into 75 // segfaults. 76 77 template<> 78 template<typename T> 79 inline T Atomic::PlatformCmpxchg<1>::operator()(T exchange_value, 80 T volatile* dest, 81 T compare_value, 82 cmpxchg_memory_order order) const { 83 STATIC_ASSERT(1 == sizeof(T)); 84 return PrimitiveConversions::cast<T>( 85 _Atomic_cmpxchg_byte(PrimitiveConversions::cast<jbyte>(exchange_value), 86 reinterpret_cast<jbyte volatile*>(dest), 87 PrimitiveConversions::cast<jbyte>(compare_value))); 88 } 89 90 template<> 91 template<typename T> 92 inline T Atomic::PlatformCmpxchg<4>::operator()(T exchange_value, 93 T volatile* dest, 94 T compare_value, 95 cmpxchg_memory_order order) const { 96 STATIC_ASSERT(4 == sizeof(T)); 97 return PrimitiveConversions::cast<T>( 98 _Atomic_cmpxchg(PrimitiveConversions::cast<jint>(exchange_value), 99 reinterpret_cast<jint volatile*>(dest), 100 PrimitiveConversions::cast<jint>(compare_value))); 101 } 102 103 template<> 104 template<typename T> 105 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value, 106 T volatile* dest, 107 T compare_value, 108 cmpxchg_memory_order order) const { 109 STATIC_ASSERT(8 == sizeof(T)); 110 return PrimitiveConversions::cast<T>( 111 _Atomic_cmpxchg_long(PrimitiveConversions::cast<jlong>(exchange_value), 112 reinterpret_cast<jlong volatile*>(dest), 113 PrimitiveConversions::cast<jlong>(compare_value))); 114 } 115 116 inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } 117 inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } 118 extern "C" jlong _Atomic_add_long(jlong add_value, volatile jlong* dest); 119 extern "C" jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest); 120 121 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { 122 return (intptr_t)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest); 123 } 124 125 inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { 126 return (void*)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest); 127 } 128 129 inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { 130 return (intptr_t)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest); 131 } 132 133 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { 134 return (void*)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest); 135 } 136 137 inline jlong Atomic::load(const volatile jlong* src) { return *src; } 138 139 #endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP