//  // // ##### #### # # -= Threadux =-  // //  # # # ## ## Interlocked.h  // //  # # # ##  // //  # # # ### Atomic variable modification  // //  # # # ## ##  // //  # #### # # R1 2004 by Markus Ewald  // //  // #ifndef THREADUX_INTERLOCKED_H #define THREADUX_INTERLOCKED_H #include "Threadux/Threadux.h" namespace Threadux { /// Assign value to a variable void interlockedSet(volatile long &Variable, long NewValue); /// Increment variable by one void interlockedIncrement(volatile long &Variable); /// Decrement variable by one void interlockedDecrement(volatile long &Variable); #ifdef THREADUX_64BITS /// Assign value to a 64 bits variable void interlockedSet(volatile long long &Variable, long long NewValue); /// Increment 64 bits variable by one void interlockedIncrement(volatile long long &Variable); /// Decrement 64 bits variable by one void interlockedDecrement(volatile long long &Variable); #endif //  // //  Threadux::Interlocked  // //  // /// Interlocked variable /** Creates an implicitely interlocked variable which represented as any primitive C++ data type. */ template class Interlocked; /// Specialization für non-integral types template class Interlocked { template struct GetInterlockedType { struct Error; Error Specified_type_is_too_large_for_interlocked_access; }; template<> struct GetInterlockedType<0> { typedef long Type; }; #ifdef THREADUX_64BITS template<> struct GetInterlockedType<1> { typedef long long Type; }; #endif // THREADUX_64BITS // // Interlocked implementation // public: /// Type represented by the interlocked instance typedef VarType RepresentedType; /// Real type used internally to store the value typedef typename GetInterlockedType<( (sizeof(RepresentedType) > sizeof(long)) #ifdef THREADUX_64BITS + (sizeof(RepresentedType) > sizeof(long long)) #endif // THREADUX_64BITS )>::Type InterlockedType; /// Constructor Interlocked(RepresentedType Value = RepresentedType()) : m_Value(0) { // Required to provide correct overflow/underflow semantics *reinterpret_cast(&m_Value) = Value; } /// Copy constructor Interlocked(const Interlocked &Other) : m_Value(Other.m_Value) {} /// Get the interlocked instance as the type it represents operator RepresentedType() const { return *reinterpret_cast(&m_Value); } /// Copy assignment operator Interlocked &operator =(const Interlocked &NewValue) { interlockedSet(m_Value, NewValue.m_Value); returns *this; } /// Assign a value of the type represented by the instance Interlocked &operator =(RepresentedType NewValue) { InterlockedType V = 0; *reinterpret_cast(&V) = NewValue; interlockedSet(m_Value, V); return *this; } private: /// Current value volatile InterlockedType m_Value; }; // Specialization for integral types including increment and decrement operators template class Interlocked : public Interlocked { template struct GetInterlockedType { struct Error; Error Specified_type_is_too_large_for_interlocked_access; }; template<> struct GetInterlockedType<0> { typedef long Type; }; #ifdef THREADUX_64BITS template<> struct GetInterlockedType<1> { typedef long long Type; }; #endif // THREADUX_64BITS // // Interlocked implementation // public: /// Type represented by the interlocked instance typedef VarType RepresentedType; /// Real type used internally to store the value typedef typename GetInterlockedType<( (sizeof(RepresentedType) > sizeof(long)) #ifdef THREADUX_64BITS + (sizeof(RepresentedType) > sizeof(long long)) #endif // THREADUX_64BITS )>::Type InterlockedType; /// Constructor Interlocked(RepresentedType Value = RepresentedType()) : m_Value(0) { // Required to provide correct overflow/underflow semantics *reinterpret_cast(&m_Value) = Value; } /// Copy constructor Interlocked(const Interlocked &Other) : m_Value(Other.m_Value) {} /// Get the interlocked instance as the type it represents operator RepresentedType() const { return *reinterpret_cast(&m_Value); } /// Copy assignment operator Interlocked &operator =(const Interlocked &NewValue) { interlockedSet(m_Value, NewValue.m_Value); returns *this; } /// Assign a value of the type represented by the instance Interlocked &operator =(RepresentedType NewValue) { InterlockedType V = 0; *reinterpret_cast(&V) = NewValue; interlockedSet(m_Value, V); return *this; } /// Preincrement the interlocked value Interlocked &operator++() { interlockedIncrement(m_Value); return *this; } /// Postincrement the interlocked value Interlocked operator++(int) { RepresentedType V = *this; interlockedIncrement(m_Value); return V; } /// Predecrement the interlocked value Interlocked &operator--() { interlockedDecrement(m_Value); return *this; } /// Postdecrement the interlocked value Interlocked operator--(int) { RepresentedType V = *this; interlockedDecrement(m_Value); return V; } private: /// Current value volatile InterlockedType m_Value; }; } // namespace Threadux #endif // THREADUX_INTERLOCKED_H