166de1283SSergey Makeev // The MIT License (MIT) 266de1283SSergey Makeev // 366de1283SSergey Makeev // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 466de1283SSergey Makeev // 566de1283SSergey Makeev // Permission is hereby granted, free of charge, to any person obtaining a copy 666de1283SSergey Makeev // of this software and associated documentation files (the "Software"), to deal 766de1283SSergey Makeev // in the Software without restriction, including without limitation the rights 866de1283SSergey Makeev // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 966de1283SSergey Makeev // copies of the Software, and to permit persons to whom the Software is 1066de1283SSergey Makeev // furnished to do so, subject to the following conditions: 1166de1283SSergey Makeev // 1266de1283SSergey Makeev // The above copyright notice and this permission notice shall be included in 1366de1283SSergey Makeev // all copies or substantial portions of the Software. 1466de1283SSergey Makeev // 1566de1283SSergey Makeev // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1666de1283SSergey Makeev // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1766de1283SSergey Makeev // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1866de1283SSergey Makeev // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1966de1283SSergey Makeev // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2066de1283SSergey Makeev // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2166de1283SSergey Makeev // THE SOFTWARE. 2266de1283SSergey Makeev 2366de1283SSergey Makeev #pragma once 2466de1283SSergey Makeev 2502d170cfSs.makeev_local #include <MTConfig.h> 2666de1283SSergey Makeev 2702d170cfSs.makeev_local #if MT_MSVC_COMPILER_FAMILY 2866de1283SSergey Makeev #include <Platform/Windows/MTAtomic.h> 2902d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 3066de1283SSergey Makeev #include <Platform/Posix/MTAtomic.h> 3102d170cfSs.makeev_local #else 3266de1283SSergey Makeev #endif 3366de1283SSergey Makeev 3466de1283SSergey Makeev 3566de1283SSergey Makeev 3666de1283SSergey Makeev namespace MT 3766de1283SSergey Makeev { IsPointerAligned(const volatile void * p,const uint32 align)3827dbb6f7Ss.makeev inline bool IsPointerAligned( const volatile void* p, const uint32 align ) 3927dbb6f7Ss.makeev { 4027dbb6f7Ss.makeev return !((uintptr_t)p & (align - 1)); 4127dbb6f7Ss.makeev } 4227dbb6f7Ss.makeev 4327dbb6f7Ss.makeev 4466de1283SSergey Makeev // 4566de1283SSergey Makeev // Atomic int (type with constructor) 4666de1283SSergey Makeev // 4766de1283SSergey Makeev //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 48*721f8c0bSs.makeev_local template<typename T> 49*721f8c0bSs.makeev_local class Atomic32 : public Atomic32Base<T> 5066de1283SSergey Makeev { 5166de1283SSergey Makeev 5266de1283SSergey Makeev public: 5366de1283SSergey Makeev Atomic32()54*721f8c0bSs.makeev_local Atomic32() 5566de1283SSergey Makeev { 56*721f8c0bSs.makeev_local static_assert(sizeof(Atomic32<T>) == sizeof(T), "Invalid atomic type size"); 57*721f8c0bSs.makeev_local MT_ASSERT(IsPointerAligned(this, __alignof(T)), "Invalid atomic alignment"); 58*721f8c0bSs.makeev_local 59*721f8c0bSs.makeev_local Atomic32Base<T>::Store(0); 6066de1283SSergey Makeev } 6166de1283SSergey Makeev Atomic32(T v)62*721f8c0bSs.makeev_local explicit Atomic32(T v) 6366de1283SSergey Makeev { 64*721f8c0bSs.makeev_local static_assert(sizeof(Atomic32<T>) == sizeof(T), "Invalid atomic type size"); 65*721f8c0bSs.makeev_local MT_ASSERT(IsPointerAligned(this, __alignof(T)), "Invalid atomic alignment"); 66*721f8c0bSs.makeev_local 67*721f8c0bSs.makeev_local Atomic32Base<T>::Store(v); 6866de1283SSergey Makeev } 6966de1283SSergey Makeev }; 7066de1283SSergey Makeev 7166de1283SSergey Makeev 7266de1283SSergey Makeev // 7366de1283SSergey Makeev // Atomic pointer (type with constructor) 7466de1283SSergey Makeev // 7566de1283SSergey Makeev //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 7666de1283SSergey Makeev template<typename T> 77*721f8c0bSs.makeev_local class AtomicPtr : public AtomicPtrBase<T> 7866de1283SSergey Makeev { 7966de1283SSergey Makeev public: AtomicPtr()8066de1283SSergey Makeev AtomicPtr() 8166de1283SSergey Makeev { 82*721f8c0bSs.makeev_local static_assert(sizeof(AtomicPtr<T>) == sizeof(T*), "Invalid atomic type size"); 83*721f8c0bSs.makeev_local MT_ASSERT(IsPointerAligned(this, sizeof(T*)), "Invalid atomic ptr alignment"); 84*721f8c0bSs.makeev_local 85*721f8c0bSs.makeev_local AtomicPtrBase<T>::Store(nullptr); 8666de1283SSergey Makeev } 8766de1283SSergey Makeev AtomicPtr(T * v)8866de1283SSergey Makeev explicit AtomicPtr(T* v) 8966de1283SSergey Makeev { 90*721f8c0bSs.makeev_local static_assert(sizeof(AtomicPtr<T>) == sizeof(T*), "Invalid atomic type size"); 91*721f8c0bSs.makeev_local MT_ASSERT(IsPointerAligned(this, sizeof(T*)), "Invalid atomic ptr alignment"); 92*721f8c0bSs.makeev_local 93*721f8c0bSs.makeev_local AtomicPtrBase<T>::Store(v); 9466de1283SSergey Makeev } 9566de1283SSergey Makeev 9666de1283SSergey Makeev }; 9766de1283SSergey Makeev }