< prev index next >
src/share/vm/runtime/atomic.hpp
Print this page
rev 13452 : imported patch Atomic_cmpxchg
rev 13453 : imported patch Atomic_add
rev 13454 : [mq]: Atomic_add_v2
*** 217,226 ****
--- 217,227 ----
// scaling of the addend, as that has already been done by the
// caller.
public: // Temporary, can't be private: C++03 11.4/2. Fixed by C++11.
template<typename Derived> struct FetchAndAdd;
template<typename Derived> struct AddAndFetch;
+ struct AddShortUsingInt;
private:
// Support for platforms that implement some variants of add using a
// (typically out of line) non-template helper function. The
// generic arguments passed to PlatformAdd need to be translated to
*** 310,319 ****
--- 311,334 ----
struct Atomic::AddAndFetch VALUE_OBJ_CLASS_SPEC {
template<typename I, typename D>
D operator()(I add_value, D volatile* dest) const;
};
+ // Most platforms do not support atomic add on a 2-byte value. However,
+ // if the value occupies the most significant 16 bits of an aligned 32-bit
+ // word, then we can do this with an atomic add of (add_value << 16)
+ // to the 32-bit word.
+ //
+ // The least significant parts of this 32-bit word will never be affected, even
+ // in case of overflow/underflow.
+ //
+ // Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
+ struct Atomic::AddShortUsingInt VALUE_OBJ_CLASS_SPEC {
+ template<typename T>
+ T operator()(T add_value, T volatile* dest) const;
+ };
+
// Define the class before including platform file, which may specialize
// the operator definition. No generic definition of specializations
// of the operator template are provided, nor are there any generic
// specializations of the class. The platform file is responsible for
// providing those.
*** 383,413 ****
CI addend = add_value;
return PlatformAdd<sizeof(P*)>()(addend, dest);
}
};
! // Most platforms do not support atomic add on a 2-byte value. However,
! // if the value occupies the most significant 16 bits of an aligned 32-bit
! // word, then we can do this with an atomic add of (add_value << 16)
! // to the 32-bit word.
! //
! // The least significant parts of this 32-bit word will never be affected, even
! // in case of overflow/underflow.
! //
! // Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
! template<>
! struct Atomic::AddImpl<jshort, jshort> VALUE_OBJ_CLASS_SPEC {
! jshort operator()(jshort add_value, jshort volatile* dest) const {
#ifdef VM_LITTLE_ENDIAN
assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
! jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
#else
assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
! jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
#endif
! return (jshort)(new_value >> 16); // preserves sign
! }
};
template<typename Derived>
template<typename I, typename D>
inline D Atomic::FetchAndAdd<Derived>::operator()(I add_value, D volatile* dest) const {
--- 398,417 ----
CI addend = add_value;
return PlatformAdd<sizeof(P*)>()(addend, dest);
}
};
! template<typename T>
! T Atomic::AddShortUsingInt::operator()(T add_value, T volatile* dest) const {
#ifdef VM_LITTLE_ENDIAN
assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
! uint32_t new_value = Atomic::add(uint32_t(add_value) << 16, (volatile uint32_t*)(dest-1));
#else
assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
! uint32_t new_value = Atomic::add(uint32_t(add_value) << 16, (volatile uint32_t*)(dest));
#endif
! return T(new_value >> 16); // preserves sign
};
template<typename Derived>
template<typename I, typename D>
inline D Atomic::FetchAndAdd<Derived>::operator()(I add_value, D volatile* dest) const {
< prev index next >