diff --git a/rocclr/device/device.cpp b/rocclr/device/device.cpp index f175fa801e..1aa326df9d 100755 --- a/rocclr/device/device.cpp +++ b/rocclr/device/device.cpp @@ -19,7 +19,6 @@ THE SOFTWARE. */ #include "device/device.hpp" -#include "thread/atomic.hpp" #include "thread/monitor.hpp" #include "utils/options.hpp" #include "comgrctx.hpp" diff --git a/rocclr/device/devprogram.cpp b/rocclr/device/devprogram.cpp index abbcd8f75c..e18a9fbbce 100755 --- a/rocclr/device/devprogram.cpp +++ b/rocclr/device/devprogram.cpp @@ -30,6 +30,7 @@ #include "comgrctx.hpp" #include +#include #include #include #include @@ -1345,7 +1346,7 @@ bool Program::initBuild(amd::option::Options* options) { programOptions_ = options; if (options->oVariables->DumpFlags > 0) { - static amd::Atomic build_num = 0; + static std::atomic build_num{0}; options->setBuildNo(build_num++); } buildLog_.clear(); diff --git a/rocclr/device/gpu/gpudevice.hpp b/rocclr/device/gpu/gpudevice.hpp index 6c33e5a920..5b2b11373a 100644 --- a/rocclr/device/gpu/gpudevice.hpp +++ b/rocclr/device/gpu/gpudevice.hpp @@ -37,6 +37,7 @@ #include "device/gpu/gpusettings.hpp" #include "device/gpu/gpuappprofile.hpp" +#include #include "acl.h" #include "vaminterface.h" @@ -316,7 +317,7 @@ class Device : public NullDevice, public CALGSLDevice { Resource::MemoryType type_; //!< The buffer's type size_t bufSize_; //!< Staged buffer size std::list freeBuffers_; //!< The list of free buffers - amd::Atomic acquiredCnt_; //!< The total number of acquired buffers + std::atomic acquiredCnt_; //!< The total number of acquired buffers amd::Monitor lock_; //!< Staged buffer acquire/release lock const Device& gpuDevice_; //!< GPU device object }; diff --git a/rocclr/device/gpu/gpumemory.hpp b/rocclr/device/gpu/gpumemory.hpp index 234ef22ebe..9354900d98 100644 --- a/rocclr/device/gpu/gpumemory.hpp +++ b/rocclr/device/gpu/gpumemory.hpp @@ -22,7 +22,6 @@ #define GPUMEMORY_HPP_ #include "top.hpp" -#include "thread/atomic.hpp" #include "device/gpu/gpuresource.hpp" #include diff --git a/rocclr/device/gpu/gpuresource.cpp b/rocclr/device/gpu/gpuresource.cpp index ea4b048cd0..bbf93d0c26 100644 --- a/rocclr/device/gpu/gpuresource.cpp +++ b/rocclr/device/gpu/gpuresource.cpp @@ -34,7 +34,6 @@ #include "device/gpu/gpudevice.hpp" #include "device/gpu/gpublit.hpp" #include "device/gpu/gputimestamp.hpp" -#include "thread/atomic.hpp" #include "hsa_ext_image.h" #include diff --git a/rocclr/device/gpu/gpuresource.hpp b/rocclr/device/gpu/gpuresource.hpp index 82327f3240..6f81357b2e 100644 --- a/rocclr/device/gpu/gpuresource.hpp +++ b/rocclr/device/gpu/gpuresource.hpp @@ -25,6 +25,8 @@ #include "platform/program.hpp" #include "device/gpu/gpudefs.hpp" +#include + //! \namespace gpu GPU Resource Implementation namespace gpu { @@ -412,7 +414,7 @@ class Resource : public amd::HeapObject { const Device& gpuDevice_; //!< GPU device CalResourceDesc cal_; //!< CAL descriptor for this resource - amd::Atomic mapCount_; //!< Total number of maps + std::atomic mapCount_; //!< Total number of maps void* address_; //!< Physical address of this resource size_t offset_; //!< Resource offset size_t curRename_; //!< Current active rename in the list diff --git a/rocclr/device/pal/paldevice.hpp b/rocclr/device/pal/paldevice.hpp index fa39b250a5..27fdef8bc9 100755 --- a/rocclr/device/pal/paldevice.hpp +++ b/rocclr/device/pal/paldevice.hpp @@ -39,6 +39,7 @@ #include "acl.h" #include "memory" +#include #include /*! \addtogroup PAL @@ -258,7 +259,7 @@ class Device : public NullDevice { Resource::MemoryType type_; //!< The buffer's type size_t bufSize_; //!< Staged buffer size std::list freeBuffers_; //!< The list of free buffers - amd::Atomic acquiredCnt_; //!< The total number of acquired buffers + std:atomic acquiredCnt_; //!< The total number of acquired buffers amd::Monitor lock_; //!< Stgaed buffer acquire/release lock const Device& gpuDevice_; //!< GPU device object }; diff --git a/rocclr/device/pal/palmemory.hpp b/rocclr/device/pal/palmemory.hpp index f0bb640c6d..53f169c7c5 100644 --- a/rocclr/device/pal/palmemory.hpp +++ b/rocclr/device/pal/palmemory.hpp @@ -21,7 +21,6 @@ #pragma once #include "top.hpp" -#include "thread/atomic.hpp" #include "device/pal/palresource.hpp" #include diff --git a/rocclr/device/pal/palresource.cpp b/rocclr/device/pal/palresource.cpp index 101d09b100..763136585e 100644 --- a/rocclr/device/pal/palresource.cpp +++ b/rocclr/device/pal/palresource.cpp @@ -28,7 +28,6 @@ #include "device/pal/paldevice.hpp" #include "device/pal/palblit.hpp" #include "device/pal/paltimestamp.hpp" -#include "thread/atomic.hpp" #include "hsa_ext_image.h" #ifdef _WIN32 #include diff --git a/rocclr/device/pal/palresource.hpp b/rocclr/device/pal/palresource.hpp index 4bb25a8787..eeee07a785 100644 --- a/rocclr/device/pal/palresource.hpp +++ b/rocclr/device/pal/palresource.hpp @@ -25,6 +25,7 @@ #include "device/pal/paldefs.hpp" #include "util/palBuddyAllocatorImpl.h" +#include #include //! \namespace pal PAL Resource Implementation @@ -479,7 +480,7 @@ class Resource : public amd::HeapObject { const Device& gpuDevice_; //!< GPU device Descriptor desc_; //!< Descriptor for this resource - amd::Atomic mapCount_; //!< Total number of maps + std::atomic mapCount_; //!< Total number of maps void* address_; //!< Physical address of this resource size_t offset_; //!< Resource offset GpuMemoryReference* memRef_; //!< PAL resource reference diff --git a/rocclr/device/rocm/rocdevice.hpp b/rocclr/device/rocm/rocdevice.hpp index a4cde6cbce..817e66cd0a 100755 --- a/rocclr/device/rocm/rocdevice.hpp +++ b/rocclr/device/rocm/rocdevice.hpp @@ -45,6 +45,7 @@ #include "hsa_ext_amd.h" #include "hsa_ven_amd_loader.h" +#include #include #include #include @@ -281,7 +282,7 @@ class Device : public NullDevice { size_t bufSize_; //!< Staged buffer size std::list freeBuffers_; //!< The list of free buffers - amd::Atomic acquiredCnt_; //!< The total number of acquired buffers + std::atomic_uint acquiredCnt_; //!< The total number of acquired buffers amd::Monitor lock_; //!< Stgaed buffer acquire/release lock const Device& gpuDevice_; //!< GPU device object }; @@ -535,7 +536,7 @@ class Device : public NullDevice { std::vector* link_attr); public: - amd::Atomic numOfVgpus_; //!< Virtual gpu unique index + std::atomic numOfVgpus_; //!< Virtual gpu unique index //! enum for keeping the total and available queue priorities enum QueuePriority : uint { Low = 0, Normal = 1, High = 2, Total = 3}; diff --git a/rocclr/include/top.hpp b/rocclr/include/top.hpp index 44e2076760..531f92664e 100644 --- a/rocclr/include/top.hpp +++ b/rocclr/include/top.hpp @@ -45,6 +45,7 @@ #include #endif /*!ATI_ARCH_ARM*/ +#include #include #include #include @@ -169,7 +170,7 @@ class HeapObject { /*! \brief For all reference counted objects. */ class ReferenceCountedObject { - volatile uint referenceCount_; + std::atomic referenceCount_; protected: virtual ~ReferenceCountedObject() {} @@ -185,7 +186,7 @@ class ReferenceCountedObject { }; void operator delete(void* obj, size_t extSize) { ReferenceCountedObject::operator delete(obj); } - uint referenceCount() const { return referenceCount_; } + uint referenceCount() const { return referenceCount_.load(std::memory_order_relaxed); } uint retain(); uint release(); diff --git a/rocclr/os/os_win32.cpp b/rocclr/os/os_win32.cpp index 8045f53b45..c8df137626 100644 --- a/rocclr/os/os_win32.cpp +++ b/rocclr/os/os_win32.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/rocclr/platform/activity.hpp b/rocclr/platform/activity.hpp index f2474b4b6b..65575cb403 100644 --- a/rocclr/platform/activity.hpp +++ b/rocclr/platform/activity.hpp @@ -20,12 +20,12 @@ #pragma once +#include "thread/monitor.hpp" + #include #include #include -#include "thread/monitor.hpp" - #define USE_PROF_API 1 #if USE_PROF_API diff --git a/rocclr/platform/command.cpp b/rocclr/platform/command.cpp index a16e52d12b..e36afd6ee4 100644 --- a/rocclr/platform/command.cpp +++ b/rocclr/platform/command.cpp @@ -36,6 +36,7 @@ #include "platform/agent.hpp" #include "os/alloc.hpp" +#include #include #include @@ -91,7 +92,7 @@ uint64_t epoch = 0; bool Event::setStatus(int32_t status, uint64_t timeStamp) { assert(status <= CL_QUEUED && "invalid status"); - int32_t currentStatus = status_; + int32_t currentStatus = this->status(); if (currentStatus <= CL_COMPLETE || currentStatus <= status) { // We can only move forward in the execution status. return false; @@ -104,7 +105,7 @@ bool Event::setStatus(int32_t status, uint64_t timeStamp) { } } - if (!make_atomic(status_).compareAndSet(currentStatus, status)) { + if (!status_.compare_exchange_strong(currentStatus, status, std::memory_order_relaxed)) { // Somebody else beat us to it, let them deal with the release/signal. return false; } @@ -154,7 +155,7 @@ bool Event::setCallback(int32_t status, Event::CallBackFunction callback, void* ; // Someone else is also updating the head of the linked list! reload. // Check if the event has already reached 'status' - if (status_ <= status && entry->callback_ != CallBackFunction(0)) { + if (this->status() <= status && entry->callback_ != CallBackFunction(0)) { if (entry->callback_.exchange(NULL) != NULL) { callback(as_cl(this), status, entry->data_); } @@ -183,30 +184,30 @@ void Event::processCallbacks(int32_t status) const { } bool Event::awaitCompletion() { - if (status_ > CL_COMPLETE) { + if (status() > CL_COMPLETE) { // Notifies current command queue about waiting if (!notifyCmdQueue()) { return false; } - ClPrint(LOG_DEBUG, LOG_WAIT, "waiting for event %p to complete, current status %d", this, status_); + ClPrint(LOG_DEBUG, LOG_WAIT, "waiting for event %p to complete, current status %d", this, status()); auto* queue = command().queue(); if ((queue != nullptr) && queue->vdev()->ActiveWait()) { - while (status_ > CL_COMPLETE) { + while (status() > CL_COMPLETE) { amd::Os::yield(); } } else { ScopedLock lock(lock_); // Wait until the status becomes CL_COMPLETE or negative. - while (status_ > CL_COMPLETE) { + while (status() > CL_COMPLETE) { lock_.wait(); } } ClPrint(LOG_DEBUG, LOG_WAIT, "event %p wait completed", this); } - return status_ == CL_COMPLETE; + return status() == CL_COMPLETE; } bool Event::notifyCmdQueue() { diff --git a/rocclr/platform/command.hpp b/rocclr/platform/command.hpp index 2e242ce125..aa692eceef 100644 --- a/rocclr/platform/command.hpp +++ b/rocclr/platform/command.hpp @@ -90,7 +90,7 @@ class Event : public RuntimeObject { Monitor lock_; std::atomic callbacks_; //!< linked list of callback entries. - volatile int32_t status_; //!< current execution status. + std::atomic status_; //!< current execution status. std::atomic_flag notified_; //!< Command queue was notified protected: @@ -163,7 +163,7 @@ class Event : public RuntimeObject { const ProfilingInfo& profilingInfo() const { return profilingInfo_; } //! Return this command's execution status. - int32_t status() const { return status_; } + int32_t status() const { return status_.load(std::memory_order_relaxed); } //! Insert the given \a callback into the callback stack. bool setCallback(int32_t status, CallBackFunction callback, void* data); diff --git a/rocclr/platform/memory.cpp b/rocclr/platform/memory.cpp index 66c0a3bf36..857af62400 100644 --- a/rocclr/platform/memory.cpp +++ b/rocclr/platform/memory.cpp @@ -26,6 +26,8 @@ #include "platform/memory.hpp" #include "device/device.hpp" +#include + namespace amd { bool BufferRect::create(const size_t* bufferOrigin, const size_t* region, size_t bufferRowPitch, @@ -277,7 +279,7 @@ bool Memory::create(void* initFrom, bool sysMemAlloc, bool skipAlloc, bool force // Create memory on all available devices for (size_t i = 0; i < devices.size(); i++) { - deviceAlloced_[devices[i]] = AllocInit; + deviceAlloced_[devices[i]].store(AllocInit, std::memory_order_relaxed); deviceMemories_[i].ref_ = devices[i]; deviceMemories_[i].value_ = NULL; @@ -301,11 +303,11 @@ bool Memory::addDeviceMemory(const Device* dev) { AllocState create = AllocCreate; AllocState init = AllocInit; - if (make_atomic(deviceAlloced_[dev]).compareAndSet(init, create)) { + if (deviceAlloced_[dev].compare_exchange_strong(init, create, std::memory_order_acq_rel)) { // Check if runtime already allocated all available slots for device memory if (numDevices() == NumDevicesWithP2P()) { // Mark the allocation as an empty - deviceAlloced_[dev] = AllocInit; + deviceAlloced_[dev].store(AllocInit, std::memory_order_release); return false; } device::Memory* dm = dev->createMemory(*this); @@ -325,17 +327,17 @@ bool Memory::addDeviceMemory(const Device* dev) { } else { LogError("Video memory allocation failed!"); // Mark the allocation as an empty - deviceAlloced_[dev] = AllocInit; + deviceAlloced_[dev].store(AllocInit, std::memory_order_release); } } // Make sure runtime finished memory allocation. // Loop if in the create state - while (deviceAlloced_[dev] == AllocCreate) { + while (deviceAlloced_[dev].load(std::memory_order_acquire) == AllocCreate) { Os::yield(); } - if (deviceAlloced_[dev] == AllocComplete) { + if (deviceAlloced_[dev].load(std::memory_order_acquire) == AllocComplete) { result = true; } @@ -357,7 +359,7 @@ void Memory::replaceDeviceMemory(const Device* dev, device::Memory* dm) { } deviceMemories_[i].value_ = dm; - deviceAlloced_[dev] = AllocRealloced; + deviceAlloced_[dev].store(AllocRealloced, std::memory_order_release); } device::Memory* Memory::getDeviceMemory(const Device& dev, bool alloc) { diff --git a/rocclr/platform/memory.hpp b/rocclr/platform/memory.hpp index 37a45bb97d..39d4569379 100755 --- a/rocclr/platform/memory.hpp +++ b/rocclr/platform/memory.hpp @@ -146,7 +146,7 @@ class Memory : public amd::RuntimeObject { DeviceMemory* deviceMemories_; //! The device alloced state - std::unordered_map deviceAlloced_; + std::unordered_map> deviceAlloced_; //! Linked list of destructor callbacks. std::atomic destructorCallbacks_; diff --git a/rocclr/platform/runtime.cpp b/rocclr/platform/runtime.cpp index 893dd56643..713948e632 100644 --- a/rocclr/platform/runtime.cpp +++ b/rocclr/platform/runtime.cpp @@ -102,10 +102,12 @@ public: ~RuntimeTearDown() { /*Runtime::tearDown();*/ } } runtime_tear_down; -uint ReferenceCountedObject::retain() { return ++make_atomic(referenceCount_); } +uint ReferenceCountedObject::retain() { + return referenceCount_.fetch_add(1, std::memory_order_relaxed) + 1; +} uint ReferenceCountedObject::release() { - uint newCount = --make_atomic(referenceCount_); + uint newCount = referenceCount_.fetch_sub(1, std::memory_order_relaxed) - 1; if (newCount == 0) { if (terminate()) { delete this; diff --git a/rocclr/thread/atomic.hpp b/rocclr/thread/atomic.hpp deleted file mode 100644 index 15eaf9960c..0000000000 --- a/rocclr/thread/atomic.hpp +++ /dev/null @@ -1,457 +0,0 @@ -/* Copyright (c) 2009-present Advanced Micro Devices, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. */ - -/*! \file atomic.hpp - * \brief Declarations for Memory order access and Atomic operations. - * - * \author Laurent Morichetti - * \date October 2008 - */ - -#ifndef ATOMIC_HPP_ -#define ATOMIC_HPP_ - -#include "top.hpp" - -#include - -#ifdef _WIN32 -#include -#elif defined(ATI_ARCH_X86) -#include -#include -#endif // !_WIN32 - -#include -#include - -namespace amd { - -/*! \addtogroup Threads - * @{ - * - * \addtogroup Atomic Atomic Operations - * @{ - */ - -/*! \brief Static functions for atomic operations. - */ -class AtomicOperation : AllStatic { - private: - //! Template to specialize atomic intrinsics on register size. - template struct Intrinsics { - /*! \brief %Atomic add. - * - * Atomically add \a inc to \a *dest and return the prior value. - */ - template static inline T add(T increment, volatile T* dest); - - /*! \brief %Atomic exchange. - * - * Atomically exchange value with *dest and return the prior value. - */ - template static inline T swap(T value, volatile T* dest); - - /*! \brief %Atomic compare and exchange. - * - * Atomically compare and xchge value with *dest if *dest == compare. - * Return the prior value. - */ - template static inline T compareAndSwap(T compare, volatile T* dest, T value); - - /*! \brief %Atomic increment. - * - * Atomically increment *dest and return the prior value. - */ - template static inline T increment(volatile T* dest); - - /*! \brief %Atomic exchange. - * - * Atomically decrement *dest and return the prior value. - */ - template static inline T decrement(volatile T* dest); - - /*! \brief %Atomic or. - * - * Atomically or \a mask to \a *dest and return the prior value. - */ - template static inline T _or(T mask, volatile T* dest); - - /*! \brief %Atomic and. - * - * Atomically and \a mask to \a *dest and return the prior value. - */ - template static inline T _and(T mask, volatile T* dest); - }; - - public: - /*! \brief %Atomic add. - * - * Atomically add \a inc to \a *dest and return the prior value. - */ - template static T add(T inc, volatile T* dest) { - return Intrinsics::add((T)inc, dest); - } - - /*! \brief %Atomic exchange. - * - * Atomically exchange value with *dest and return the prior value. - */ - template static T swap(T value, volatile T* dest) { - return Intrinsics::swap(value, dest); - } - - /*! \brief %Atomic compare and exchange. - * - * Atomically compare and exchange value with *dest if *dest == compare. - * Return the prior value. - */ - template static T compareAndSwap(T compare, volatile T* dest, T value) { - return Intrinsics::compareAndSwap(compare, dest, value); - } - - /*! \brief %Atomic increment. - * - * Atomically increment *dest and return the prior value. - */ - template static T increment(volatile T* dest) { - return Intrinsics::increment(dest); - } - - /*! \brief %Atomic decrement. - * - * Atomically decrement *dest and return the prior value. - */ - template static T decrement(volatile T* dest) { - return Intrinsics::decrement(dest); - } - - /*! \brief %Atomic or. - * - * Atomically or \a mask to \a *dest and return the prior value. - */ - template static T _or(T mask, volatile T* dest) { - return Intrinsics::_or((T)mask, dest); - } - - /*! \brief %Atomic and. - * - * Atomically or \a mask to \a *dest and return the prior value. - */ - template static T _and(T mask, volatile T* dest) { - return Intrinsics::_and((T)mask, dest); - } -}; - -/*@}*/ - -#if defined(_MSC_VER) - -template <> -template -inline T AtomicOperation::Intrinsics<4>::add(T increment, volatile T* dest) { - return (T)_InterlockedExchangeAdd((volatile long*)dest, (long)increment); -} - -template <> -template -inline T AtomicOperation::Intrinsics<4>::swap(T value, volatile T* dest) { - return (T)_InterlockedExchange((volatile long*)dest, (long)value); -} - -template <> -template -inline T AtomicOperation::Intrinsics<4>::compareAndSwap(T compare, volatile T* dest, T value) { - return (T)_InterlockedCompareExchange((volatile long*)dest, (long)value, (long)compare); -} - -template <> -template -inline T AtomicOperation::Intrinsics<4>::increment(volatile T* dest) { - return (T)(_InterlockedIncrement((volatile long*)dest) - 1L); -} - -template <> -template -inline T AtomicOperation::Intrinsics<4>::decrement(volatile T* dest) { - return (T)(_InterlockedDecrement((volatile long*)dest) + 1L); -} - -template <> -template -inline T AtomicOperation::Intrinsics<4>::_or(T mask, volatile T* dest) { - return (T)_InterlockedOr((volatile long*)dest, (long)mask); -} - -template <> -template -inline T AtomicOperation::Intrinsics<4>::_and(T mask, volatile T* dest) { - return (T)_InterlockedAnd((volatile long*)dest, (long)mask); -} - -#ifdef _WIN64 - -template <> -template -inline T AtomicOperation::Intrinsics<8>::add(T increment, volatile T* dest) { - return (T)_InterlockedExchangeAdd64((volatile __int64*)dest, (__int64)increment); -} - -template <> -template -inline T AtomicOperation::Intrinsics<8>::swap(T value, volatile T* dest) { - return (T)_InterlockedExchange64((volatile __int64*)dest, (__int64)value); -} - -template <> -template -inline T AtomicOperation::Intrinsics<8>::compareAndSwap(T compare, volatile T* dest, T value) { - return (T)_InterlockedCompareExchange64((volatile __int64*)dest, (__int64)value, - (__int64)compare); -} - -template <> -template -inline T AtomicOperation::Intrinsics<8>::increment(volatile T* dest) { - return (T)(_InterlockedIncrement64((volatile __int64*)dest) - 1LL); -} - -template <> -template -inline T AtomicOperation::Intrinsics<8>::decrement(volatile T* dest) { - return (T)(_InterlockedDecrement64((volatile __int64*)dest) + 1LL); -} - -template <> -template -inline T AtomicOperation::Intrinsics<8>::_or(T mask, volatile T* dest) { - return (T)_InterlockedOr64((volatile long*)dest, (long)mask); -} - -template <> -template -inline T AtomicOperation::Intrinsics<8>::_and(T mask, volatile T* dest) { - return (T)_InterlockedAnd64((volatile long*)dest, (long)mask); -} - -#endif // _LP64 - -#elif defined(__GNUC__) - -template -template -inline T AtomicOperation::Intrinsics::add(T inc, volatile T* dest) { - return __sync_fetch_and_add(dest, inc); -} - -template -template -inline T AtomicOperation::Intrinsics::swap(T value, volatile T* dest) { - return __sync_lock_test_and_set(dest, value); -} - -template -template -inline T AtomicOperation::Intrinsics::compareAndSwap(T compare, volatile T* dest, T value) { - return __sync_val_compare_and_swap(dest, compare, value); -} - -template -template -inline T AtomicOperation::Intrinsics::increment(volatile T* dest) { - return add(T(1), dest); -} - -template -template -inline T AtomicOperation::Intrinsics::decrement(volatile T* dest) { - return add(T(-1), dest); -} - -template -template -inline T AtomicOperation::Intrinsics::_or(T mask, volatile T* dest) { - return __sync_fetch_and_or(dest, mask); -} - -template -template -inline T AtomicOperation::Intrinsics::_and(T mask, volatile T* dest) { - return __sync_fetch_and_and(dest, mask); -} - -#else -#error Unimplemented -#endif - -/*! \addtogroup Atomic Atomic Operations - * @{ - */ - -/*! \brief A variable of type T with atomic properties. - */ -template class Atomic { - private: - typedef typename std::remove_volatile< - typename std::remove_pointer::type>::type>::type value_type; - typename std::add_volatile::type value_; //!< \brief The variable. - - public: - //! Construct a new %Atomic variable of type T. - Atomic() : value_(T(0)) {} - //! Construct a new %Atomic variable of type T from \a value. - Atomic(T value) : value_(value) {} - //! Construct a new %Atomic variable of type T from another %Atomic. - Atomic(const Atomic& atomic) : value_(atomic.value_) {} - //! Copy value into this %Atomic variable. - Atomic& operator=(T value) { - value_ = value; - return *this; - } - - //! Return the %Atomic variable value. - operator T() const { return T(value_); } - //! Return the %Atomic variable value. - T operator->() const { return T(value_); } - //! Return the %Atomic variable's address. - typename std::add_pointer::type>::type operator&() { - return &value_; - } - - //! Atomically add \a inc to this variable. - Atomic& operator+=(value_type inc) { - if (std::is_pointer::value) { - inc *= sizeof(typename std::remove_pointer::type); - } - AtomicOperation::add(inc, &value_); - return *this; - } - - //! Atomically subtract \a inc to this variable. - Atomic& operator-=(value_type inc) { - value_type modifier = 0; - if (std::is_pointer::value) { - inc *= sizeof(typename std::remove_pointer::type); - } - AtomicOperation::add(modifier - inc, &value_); - return *this; - } - - //! Atomically OR \a value to this variable. - Atomic& operator|=(value_type mask) { - AtomicOperation::_or(mask, &value_); - return *this; - } - - //! Atomically AND \a value to this variable. - Atomic& operator&=(value_type mask) { - AtomicOperation::_and(mask, &value_); - return *this; - } - - //! Atomically increment this variable and return its new value. - typename std::remove_reference::type operator++() { - if (std::is_pointer::value) { - value_type inc = static_cast(sizeof(typename std::remove_pointer::type)); - return AtomicOperation::add(inc, &value_) + 1; - } else { - return AtomicOperation::increment(&value_) + 1; - } - } - - //! Atomically decrement this variable and return its new value. - typename std::remove_reference::type operator--() { - if (std::is_pointer::value) { - value_type inc = - static_cast(-static_cast::type>( - sizeof(typename std::remove_pointer::type))); - return AtomicOperation::add(inc, &value_) - 1; - } else { - return AtomicOperation::decrement(&value_) - 1; - } - } - - //! Atomically increment this variable and return its previous value. - typename std::remove_reference::type operator++(int) { - if (std::is_pointer::value) { - value_type inc = static_cast(sizeof(typename std::remove_pointer::type)); - return AtomicOperation::add(inc, &value_); - } else { - return AtomicOperation::increment(&value_); - } - } - - //! Atomically decrement this variable and return its previous value. - T operator--(int) { - if (std::is_pointer::value) { - value_type inc = - static_cast(-static_cast::type>( - sizeof(typename std::remove_pointer::type))); - return AtomicOperation::add(inc, &value_); - } else { - return AtomicOperation::decrement(&value_); - } - } - - /*! \brief Atomically compare this variable with \a compare and set - * to value if equals - */ - bool compareAndSet(T compare, T value) { - return compare == AtomicOperation::compareAndSwap(compare, &value_, value); - } - - //! Atomically set this variable to \a value and return its previous value. - T swap(T value) { return AtomicOperation::swap(value, &value_); } - - /*! \brief Execute a stores fence followed by a store to this variable. - * - * This storeRelease operation ensures that all store to memory operations - * preceding this function will be globally visible before the update to - * this variable's value. - */ - void storeRelease(T value) { - std::atomic_thread_fence(std::memory_order_release); - value_ = value; - } - - /*! \brief Execute a load from this variable followed by a loads fence. - * - * This loadAcquire operation ensures that all load from memory operations - * following this function will be globally visible after the read from - * this variable's value. - */ - T loadAcquire() const { - T value = value_; - std::atomic_thread_fence(std::memory_order_acquire); - return value; - } -}; - -//! Helper function to tie an Atomic to a variable of type T. -template inline Atomic make_atomic(T& t) { return Atomic(t); } - - -/*! @} - * @} - */ - -} // namespace amd - -#endif /*ATOMIC_HPP_*/ diff --git a/rocclr/thread/monitor.cpp b/rocclr/thread/monitor.cpp index 6c1e496682..b6ce28f76f 100644 --- a/rocclr/thread/monitor.cpp +++ b/rocclr/thread/monitor.cpp @@ -19,11 +19,11 @@ THE SOFTWARE. */ #include "thread/monitor.hpp" -#include "thread/atomic.hpp" #include "thread/semaphore.hpp" #include "thread/thread.hpp" #include "utils/util.hpp" +#include #include #include #include diff --git a/rocclr/thread/monitor.hpp b/rocclr/thread/monitor.hpp index c89ec287aa..717d1ffc3f 100644 --- a/rocclr/thread/monitor.hpp +++ b/rocclr/thread/monitor.hpp @@ -22,7 +22,6 @@ #define MONITOR_HPP_ #include "top.hpp" -#include "thread/atomic.hpp" #include "thread/semaphore.hpp" #include "thread/thread.hpp"