< 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 >