00001 /* 00002 * Volatile.hpp 00003 * 00004 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Oracle is a registered trademarks of Oracle Corporation and/or its 00007 * affiliates. 00008 * 00009 * This software is the confidential and proprietary information of Oracle 00010 * Corporation. You shall not disclose such confidential and proprietary 00011 * information and shall use it only in accordance with the terms of the 00012 * license agreement you entered into with Oracle. 00013 * 00014 * This notice may not be removed or altered. 00015 */ 00016 #ifndef COH_VOLATILE_HPP 00017 #define COH_VOLATILE_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/Object.hpp" 00022 #include "coherence/native/NativeAtomic32.hpp" 00023 #include "coherence/native/NativeAtomic64.hpp" 00024 00025 00026 COH_OPEN_NAMESPACE2(coherence,lang) 00027 00028 using coherence::native::NativeAtomic32; 00029 using coherence::native::NativeAtomic64; 00030 00031 template<class T> 00032 class VolatileStorage 00033 { 00034 public: 00035 typedef int64_t cast_type; 00036 typedef NativeAtomic64 storage; 00037 }; 00038 00039 #define COH_DEFINE_VOLATILE_STORAGE(TYPE, WIDTH) \ 00040 template<> \ 00041 class VolatileStorage<TYPE> \ 00042 { \ 00043 public: \ 00044 typedef int##WIDTH##_t cast_type; \ 00045 typedef NativeAtomic##WIDTH storage; \ 00046 } 00047 00048 COH_DEFINE_VOLATILE_STORAGE(bool, 32); 00049 COH_DEFINE_VOLATILE_STORAGE(char, 32); 00050 //COH_DEFINE_VOLATILE_STORAGE(octet_t, 32); // avoid duplicate instantiation 00051 //COH_DEFINE_VOLATILE_STORAGE(wchar16_t, 32); // avoid duplicate instantiation 00052 //COH_DEFINE_VOLATILE_STORAGE(int8_t, 32); // avoid duplicate instantiation 00053 //COH_DEFINE_VOLATILE_STORAGE(uint8_t, 32); // avoid duplicate instantiation 00054 COH_DEFINE_VOLATILE_STORAGE(int16_t, 32); 00055 COH_DEFINE_VOLATILE_STORAGE(uint16_t, 32); 00056 COH_DEFINE_VOLATILE_STORAGE(int32_t, 32); 00057 COH_DEFINE_VOLATILE_STORAGE(uint32_t, 32); 00058 COH_DEFINE_VOLATILE_STORAGE(int64_t, 64); 00059 COH_DEFINE_VOLATILE_STORAGE(uint64_t, 64); 00060 COH_DEFINE_VOLATILE_STORAGE(float32_t, 64); 00061 COH_DEFINE_VOLATILE_STORAGE(float64_t , 64); 00062 //COH_DEFINE_VOLATILE_STORAGE(size32_t, 32); // avoid duplicate instantiation 00063 //COH_DEFINE_VOLATILE_STORAGE(size64_t, 64); // avoid duplicate instantiation 00064 00065 /** 00066 * Template class wraps primitive data types with memory barriers, providing 00067 * JSR-133 style volatiles. Note that Weak|MemberHandle/View/Holder are naturally 00068 * volatile and thus don't need to be supported by this class. 00069 * 00070 * Note: In the rare case that a Volatile is declared via the mutable 00071 * keyword, the Volatile must be informed of this fact by setting 00072 * fMutable to true during construction. 00073 * 00074 * @author mf 2008.02.07 00075 */ 00076 template<class T> 00077 class COH_EXPORT Volatile 00078 { 00079 // ----- typedefs ------------------------------------------------------- 00080 00081 public: 00082 /** 00083 * A primitive data type that is wrapped by this Volatile<T> 00084 */ 00085 typedef T Type; 00086 00087 00088 // ----- constructors --------------------------------------------------- 00089 00090 public: 00091 /** 00092 * Construct a new Volatile<T> with the default wrapped T value. 00093 * 00094 * @param oGuardian the object which this data member is part of 00095 */ 00096 Volatile(Object& oGuardian); 00097 00098 /** 00099 * Copy-construct a Volatile<T>. 00100 * 00101 * @param oGuardian the object which this data member is part of 00102 */ 00103 Volatile(Object& oGuardian, const Volatile& o); 00104 00105 /** 00106 * Copy-construct a Volatile<T>. 00107 * 00108 * @param oGuardian the object which this data member is part of 00109 * @param fMutable true if the member is declared as mutable, false 00110 * if declared as const 00111 */ 00112 Volatile(Object& oGuardian, const Volatile& o, bool fMutable); 00113 00114 /** 00115 * Construct a new Volatile<T> with the specified wrapped T value. 00116 * 00117 * @param oGuardian the object which this data member is part of 00118 */ 00119 Volatile(Object& oGuardian, const T& value); 00120 00121 /** 00122 * Construct a new Volatile<T> with the specified wrapped T value. 00123 * 00124 * @param oGuardian the object which this data member is part of 00125 * @param fMutable true if the member is declared as mutable, false 00126 * if declared as const 00127 */ 00128 Volatile(Object& oGuardian, const T& value, bool fMutable); 00129 00130 /** 00131 * Destruct this Volatile<T> object. 00132 */ 00133 ~Volatile(); 00134 00135 00136 // ----- operators ------------------------------------------------------ 00137 00138 public: 00139 /** 00140 * Assign this Volatile the value from another Volatile 00141 */ 00142 Volatile& operator=(const Volatile& value); 00143 00144 /** 00145 * Assign this Volatile a new value. 00146 */ 00147 Volatile& operator=(const T& value); 00148 00149 00150 // ----- Volatile interface -------------------------------------------- 00151 00152 public: 00153 /** 00154 * Return the Volatile value 00155 * 00156 * @return The Volatile value 00157 */ 00158 operator const T() const; 00159 00160 00161 // ----- data members --------------------------------------------------- 00162 00163 private: 00164 /** 00165 * The object which this data member is part of. 00166 */ 00167 const Object& m_oGuardian; 00168 00169 /** 00170 * The volatile value wrapped in a union of NativeAtomic64. 00171 */ 00172 typename VolatileStorage<T>::storage m_atomic; 00173 }; 00174 00175 // ----- global operators and functions ------------------------------------- 00176 00177 /** 00178 * Output a human-readable description of the given Volatile<T> to the 00179 * specified stream. 00180 * 00181 * @param out the stream used to output the description 00182 * @param o the Volatile<T> value to describe 00183 * 00184 * @return the supplied stream 00185 */ 00186 template <typename Char, typename Traits, class T> 00187 COH_INLINE std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, 00188 const coherence::lang::Volatile<T>& o) 00189 { 00190 out << (T) o; 00191 return out; 00192 } 00193 00194 COH_CLOSE_NAMESPACE2 00195 00196 #endif // COH_Volatile_HPP