1*66de1283SSergey Makeev // The MIT License (MIT) 2*66de1283SSergey Makeev // 3*66de1283SSergey Makeev // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4*66de1283SSergey Makeev // 5*66de1283SSergey Makeev // Permission is hereby granted, free of charge, to any person obtaining a copy 6*66de1283SSergey Makeev // of this software and associated documentation files (the "Software"), to deal 7*66de1283SSergey Makeev // in the Software without restriction, including without limitation the rights 8*66de1283SSergey Makeev // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9*66de1283SSergey Makeev // copies of the Software, and to permit persons to whom the Software is 10*66de1283SSergey Makeev // furnished to do so, subject to the following conditions: 11*66de1283SSergey Makeev // 12*66de1283SSergey Makeev // The above copyright notice and this permission notice shall be included in 13*66de1283SSergey Makeev // all copies or substantial portions of the Software. 14*66de1283SSergey Makeev // 15*66de1283SSergey Makeev // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*66de1283SSergey Makeev // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*66de1283SSergey Makeev // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18*66de1283SSergey Makeev // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*66de1283SSergey Makeev // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20*66de1283SSergey Makeev // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21*66de1283SSergey Makeev // THE SOFTWARE. 22*66de1283SSergey Makeev 23*66de1283SSergey Makeev #pragma once 24*66de1283SSergey Makeev 25*66de1283SSergey Makeev 26*66de1283SSergey Makeev #ifdef _WIN32 27*66de1283SSergey Makeev #include <Platform/Windows/MTAtomic.h> 28*66de1283SSergey Makeev #else 29*66de1283SSergey Makeev #include <Platform/Posix/MTAtomic.h> 30*66de1283SSergey Makeev #endif 31*66de1283SSergey Makeev 32*66de1283SSergey Makeev 33*66de1283SSergey Makeev 34*66de1283SSergey Makeev namespace MT 35*66de1283SSergey Makeev { 36*66de1283SSergey Makeev //compile time POD type check 37*66de1283SSergey Makeev //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 38*66de1283SSergey Makeev static_assert(std::is_pod<AtomicInt32Base>::value == true, "AtomicInt32Base must be a POD (plain old data type)"); 39*66de1283SSergey Makeev 40*66de1283SSergey Makeev 41*66de1283SSergey Makeev // 42*66de1283SSergey Makeev // Atomic int (type with constructor) 43*66de1283SSergey Makeev // 44*66de1283SSergey Makeev //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 45*66de1283SSergey Makeev class AtomicInt32 : public AtomicInt32Base 46*66de1283SSergey Makeev { 47*66de1283SSergey Makeev 48*66de1283SSergey Makeev public: 49*66de1283SSergey Makeev 50*66de1283SSergey Makeev AtomicInt32() 51*66de1283SSergey Makeev { 52*66de1283SSergey Makeev _value = 0; 53*66de1283SSergey Makeev static_assert(sizeof(AtomicInt32) == 4, "Invalid type size"); 54*66de1283SSergey Makeev MT_ASSERT(IsPointerAligned(&_value, 4), "Invalid atomic int alignment"); 55*66de1283SSergey Makeev } 56*66de1283SSergey Makeev 57*66de1283SSergey Makeev explicit AtomicInt32(int v) 58*66de1283SSergey Makeev { 59*66de1283SSergey Makeev _value = v; 60*66de1283SSergey Makeev static_assert(sizeof(AtomicInt32) == 4, "Invalid type size"); 61*66de1283SSergey Makeev MT_ASSERT(IsPointerAligned(&_value, 4), "Invalid atomic int alignment"); 62*66de1283SSergey Makeev } 63*66de1283SSergey Makeev }; 64*66de1283SSergey Makeev 65*66de1283SSergey Makeev 66*66de1283SSergey Makeev //compile time POD type check 67*66de1283SSergey Makeev //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 68*66de1283SSergey Makeev static_assert(std::is_pod<AtomicPtrBase>::value == true, "AtomicPtrBase must be a POD (plain old data type)"); 69*66de1283SSergey Makeev 70*66de1283SSergey Makeev 71*66de1283SSergey Makeev // 72*66de1283SSergey Makeev // Atomic pointer (type with constructor) 73*66de1283SSergey Makeev // 74*66de1283SSergey Makeev //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 75*66de1283SSergey Makeev template<typename T> 76*66de1283SSergey Makeev class AtomicPtr : protected AtomicPtrBase 77*66de1283SSergey Makeev { 78*66de1283SSergey Makeev public: 79*66de1283SSergey Makeev AtomicPtr() 80*66de1283SSergey Makeev { 81*66de1283SSergey Makeev _value = nullptr; 82*66de1283SSergey Makeev MT_ASSERT(IsPointerAligned(&_value, sizeof(void*)), "Invalid atomic ptr alignment"); 83*66de1283SSergey Makeev } 84*66de1283SSergey Makeev 85*66de1283SSergey Makeev explicit AtomicPtr(T* v) 86*66de1283SSergey Makeev { 87*66de1283SSergey Makeev _value = v; 88*66de1283SSergey Makeev MT_ASSERT(IsPointerAligned(&_value, sizeof(void*)), "Invalid atomic ptr alignment"); 89*66de1283SSergey Makeev } 90*66de1283SSergey Makeev 91*66de1283SSergey Makeev T* Load() const 92*66de1283SSergey Makeev { 93*66de1283SSergey Makeev return (T*)AtomicPtrBase::Load(); 94*66de1283SSergey Makeev } 95*66de1283SSergey Makeev 96*66de1283SSergey Makeev T* Store(T* val) 97*66de1283SSergey Makeev { 98*66de1283SSergey Makeev return (T*)AtomicPtrBase::Store(val); 99*66de1283SSergey Makeev } 100*66de1283SSergey Makeev 101*66de1283SSergey Makeev 102*66de1283SSergey Makeev T* CompareAndSwap(T* compareValue, T* newValue) 103*66de1283SSergey Makeev { 104*66de1283SSergey Makeev return (T*)AtomicPtrBase::CompareAndSwap(compareValue, newValue); 105*66de1283SSergey Makeev } 106*66de1283SSergey Makeev 107*66de1283SSergey Makeev T* LoadRelaxed() const 108*66de1283SSergey Makeev { 109*66de1283SSergey Makeev return (T*)AtomicPtrBase::LoadRelaxed(); 110*66de1283SSergey Makeev } 111*66de1283SSergey Makeev 112*66de1283SSergey Makeev void StoreRelaxed(T* val) 113*66de1283SSergey Makeev { 114*66de1283SSergey Makeev AtomicPtrBase::StoreRelaxed(val); 115*66de1283SSergey Makeev } 116*66de1283SSergey Makeev }; 117*66de1283SSergey Makeev }