< prev index next >
src/share/vm/runtime/atomic.hpp
Print this page
rev 13452 : [mq]: coleen_review1
rev 13454 : [mq]: roman_review1
rev 13455 : [mq]: replace_if_null
rev 13458 : imported patch cmpxchg_using_helper
*** 121,139 ****
inline static D cmpxchg(T exchange_value,
D volatile* dest,
U compare_value,
cmpxchg_memory_order order = memory_order_conservative);
template<typename T, typename D>
! inline static bool conditional_store_ptr(T* value, D* volatile* dest,
cmpxchg_memory_order order = memory_order_conservative);
! inline static intptr_t cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order = memory_order_conservative) {
return cmpxchg(exchange_value, dest, compare_value, order);
}
! inline static void* cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order = memory_order_conservative) {
return cmpxchg(exchange_value,
reinterpret_cast<void* volatile*>(dest),
compare_value,
order);
}
--- 121,150 ----
inline static D cmpxchg(T exchange_value,
D volatile* dest,
U compare_value,
cmpxchg_memory_order order = memory_order_conservative);
+ // Performs atomic compare of *dest and NULL, and replaces *dest
+ // with exchange_value if the comparison succeeded. Returns true if
+ // the comparison succeeded and the exchange occurred. This is
+ // often used as part of lazy initialization, as a lock-free
+ // alternative to the Double-Checked Locking Pattern.
template<typename T, typename D>
! inline static bool replace_if_null(T* value, D* volatile* dest,
cmpxchg_memory_order order = memory_order_conservative);
! inline static intptr_t cmpxchg_ptr(intptr_t exchange_value,
! volatile intptr_t* dest,
! intptr_t compare_value,
! cmpxchg_memory_order order = memory_order_conservative) {
return cmpxchg(exchange_value, dest, compare_value, order);
}
! inline static void* cmpxchg_ptr(void* exchange_value,
! volatile void* dest,
! void* compare_value,
! cmpxchg_memory_order order = memory_order_conservative) {
return cmpxchg(exchange_value,
reinterpret_cast<void* volatile*>(dest),
compare_value,
order);
}
*** 154,171 ****
// Platform-specific implementation of cmpxchg. Support for sizes
// of 1, 4, and 8 are required. The class is a function object that
// must be default constructable, with these requirements:
//
! // - dest is of type D*.
! // - exchange_value and compare_value are of type D.
// - order is of type cmpxchg_memory_order.
! // - platform_cmpxchg is an object of type PlatformCmpxchg<sizeof(D)>.
//
// Then
! // platform_cmpxchg()(exchange_value, dest, compare_value, order)
! // must be a valid expression, returning a result convertible to D.
//
// A default definition is provided, which declares a function template
// T operator()(T, T volatile*, T, cmpxchg_memory_order) const
//
// For each required size, a platform must either provide an
--- 165,182 ----
// Platform-specific implementation of cmpxchg. Support for sizes
// of 1, 4, and 8 are required. The class is a function object that
// must be default constructable, with these requirements:
//
! // - dest is of type T*.
! // - exchange_value and compare_value are of type T.
// - order is of type cmpxchg_memory_order.
! // - platform_cmpxchg is an object of type PlatformCmpxchg<sizeof(T)>.
//
// Then
! // platform_cmpxchg(exchange_value, dest, compare_value, order)
! // must be a valid expression, returning a result convertible to T.
//
// A default definition is provided, which declares a function template
// T operator()(T, T volatile*, T, cmpxchg_memory_order) const
//
// For each required size, a platform must either provide an
*** 176,230 ****
// Support for platforms that implement some variants of cmpxchg
// using a (typically out of line) non-template helper function.
// The generic arguments passed to PlatformCmpxchg need to be
// translated to the appropriate type for the helper function, the
// helper invoked on the translated arguments, and the result
! // translated back.
! template<typename StubType, typename StubFn, typename T>
! static T cmpxchg_using_stub(StubFn stub_fn,
T exchange_value,
T volatile* dest,
T compare_value);
! // Support platforms that do not provide RMW byte-level atomic access
! // To use, derive PlatformCmpxchg<1> from this class.
! // Can't be private: C++03 11.4/2; fixed in C++11.
! public:
struct CmpxchgByteUsingInt;
private:
};
template<typename From, typename To>
struct Atomic::IsPointerConvertible<From*, To*> : AllStatic {
! // Use the "sizeof trick" to test for convertibility.
typedef char yes;
typedef char (&no)[2];
static yes test(To*);
static no test(...);
static From* test_value;
static const bool value = (sizeof(yes) == sizeof(test(test_value)));
};
! // Define 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. That all needs to be provided by the
! // platform file.
template<size_t byte_size>
struct Atomic::PlatformCmpxchg VALUE_OBJ_CLASS_SPEC {
template<typename T>
T operator()(T exchange_value,
T volatile* dest,
T compare_value,
cmpxchg_memory_order order) const;
};
! // Define class before including platform file, which may use this as
! // a base class, requiring it be complete. The operator template
! // definition is defined later.
struct Atomic::CmpxchgByteUsingInt VALUE_OBJ_CLASS_SPEC {
template<typename T>
T operator()(T exchange_value,
T volatile* dest,
T compare_value,
--- 187,243 ----
// Support for platforms that implement some variants of cmpxchg
// using a (typically out of line) non-template helper function.
// The generic arguments passed to PlatformCmpxchg need to be
// translated to the appropriate type for the helper function, the
// helper invoked on the translated arguments, and the result
! // translated back. Type is the parameter / return type of the
! // helper function.
! template<typename Type, typename Fn, typename T>
! static T cmpxchg_using_helper(Fn fn,
T exchange_value,
T volatile* dest,
T compare_value);
! // Support platforms that do not provide Read-Modify-Write
! // byte-level atomic access. To use, derive PlatformCmpxchg<1> from
! // this class.
! public: // Temporary, can't be private: C++03 11.4/2. Fixed by C++11.
struct CmpxchgByteUsingInt;
private:
};
template<typename From, typename To>
struct Atomic::IsPointerConvertible<From*, To*> : AllStatic {
! // Determine whether From* is implicitly convertible to To*, using
! // the "sizeof trick".
typedef char yes;
typedef char (&no)[2];
static yes test(To*);
static no test(...);
static From* test_value;
static const bool value = (sizeof(yes) == sizeof(test(test_value)));
};
! // 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.
template<size_t byte_size>
struct Atomic::PlatformCmpxchg VALUE_OBJ_CLASS_SPEC {
template<typename T>
T operator()(T exchange_value,
T volatile* dest,
T compare_value,
cmpxchg_memory_order order) const;
};
! // Define the class before including platform file, which may use this
! // as a base class, requiring it be complete. The definition is later
! // in this file, near the other definitions related to cmpxchg.
struct Atomic::CmpxchgByteUsingInt VALUE_OBJ_CLASS_SPEC {
template<typename T>
T operator()(T exchange_value,
T volatile* dest,
T compare_value,
*** 261,272 ****
cmpxchg_memory_order order) {
return CmpxchgImpl<T, D, U>()(exchange_value, dest, compare_value, order);
}
template<typename T, typename D>
! inline bool Atomic::conditional_store_ptr(T* value, D* volatile* dest,
cmpxchg_memory_order order) {
D* expected_null = NULL;
return expected_null == cmpxchg(value, dest, expected_null, order);
}
// Handle cmpxchg for integral and enum types.
--- 274,288 ----
cmpxchg_memory_order order) {
return CmpxchgImpl<T, D, U>()(exchange_value, dest, compare_value, order);
}
template<typename T, typename D>
! inline bool Atomic::replace_if_null(T* value, D* volatile* dest,
cmpxchg_memory_order order) {
+ // Presently using a trivial implementation in terms of cmpxchg.
+ // Consider adding platform support, to permit the use of compiler
+ // intrinsics like gcc's __sync_bool_compare_and_swap.
D* expected_null = NULL;
return expected_null == cmpxchg(value, dest, expected_null, order);
}
// Handle cmpxchg for integral and enum types.
*** 308,320 ****
D* operator()(T* exchange_value, D* volatile* dest, U* compare_value,
cmpxchg_memory_order order) const {
// Allow derived to base conversion, and adding cv-qualifiers.
D* new_value = exchange_value;
// Don't care what the CV qualifiers for compare_value are,
! // but we need to match D when calling platform support.
! typedef typename RemoveCV<U>::type U_nocv;
! D* old_value = const_cast<U_nocv *>(compare_value);
return PlatformCmpxchg<sizeof(D*)>()(new_value, dest, old_value, order);
}
};
// Handle cmpxchg for types that have a translator.
--- 324,335 ----
D* operator()(T* exchange_value, D* volatile* dest, U* compare_value,
cmpxchg_memory_order order) const {
// Allow derived to base conversion, and adding cv-qualifiers.
D* new_value = exchange_value;
// Don't care what the CV qualifiers for compare_value are,
! // but we need to match D* when calling platform support.
! D* old_value = const_cast<D*>(compare_value);
return PlatformCmpxchg<sizeof(D*)>()(new_value, dest, old_value, order);
}
};
// Handle cmpxchg for types that have a translator.
*** 341,360 ****
Translator::decay(compare_value),
order));
}
};
! template<typename StubType, typename StubFn, typename T>
! inline T Atomic::cmpxchg_using_stub(StubFn stub_fn,
T exchange_value,
T volatile* dest,
T compare_value) {
! STATIC_ASSERT(sizeof(StubType) == sizeof(T));
return IntegerTypes::cast<T>(
! stub_fn(IntegerTypes::cast<StubType>(exchange_value),
! reinterpret_cast<StubType volatile*>(dest),
! IntegerTypes::cast<StubType>(compare_value)));
}
template<typename T>
inline T Atomic::CmpxchgByteUsingInt::operator()(T exchange_value,
T volatile* dest,
--- 356,375 ----
Translator::decay(compare_value),
order));
}
};
! template<typename Type, typename Fn, typename T>
! inline T Atomic::cmpxchg_using_helper(Fn fn,
T exchange_value,
T volatile* dest,
T compare_value) {
! STATIC_ASSERT(sizeof(Type) == sizeof(T));
return IntegerTypes::cast<T>(
! fn(IntegerTypes::cast<Type>(exchange_value),
! reinterpret_cast<Type volatile*>(dest),
! IntegerTypes::cast<Type>(compare_value)));
}
template<typename T>
inline T Atomic::CmpxchgByteUsingInt::operator()(T exchange_value,
T volatile* dest,
< prev index next >