From 90c15d9f06431316c5f6d46bb474f6b35b9dd8d1 Mon Sep 17 00:00:00 2001
From: foreman
Date: Mon, 29 Sep 2014 17:38:55 -0400
Subject: [PATCH] P4 to Git Change 1082378 by lmoriche@lmoriche_opencl_dev on
2014/09/29 17:08:11
ECR #304775 - Replace amd::Atomic with std::atomic
Pre-checkin: http://ocltc.amd.com:8111/viewModification.html?modId=40639&personal=true&buildTypeId=&tab=vcsModificationBuilds&show_all_builds=true
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/os/os_posix.cpp#38 edit
... //depot/stg/opencl/drivers/opencl/runtime/os/os_win32.cpp#40 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/command.cpp#64 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/command.hpp#73 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.cpp#108 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.hpp#86 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/runtime.cpp#33 edit
... //depot/stg/opencl/drivers/opencl/runtime/thread/monitor.hpp#6 edit
... //depot/stg/opencl/drivers/opencl/runtime/thread/semaphore.cpp#6 edit
... //depot/stg/opencl/drivers/opencl/runtime/thread/semaphore.hpp#6 edit
... //depot/stg/opencl/drivers/opencl/runtime/utils/util.hpp#10 edit
---
rocclr/runtime/os/os_posix.cpp | 3 +-
rocclr/runtime/os/os_win32.cpp | 2 +-
rocclr/runtime/platform/command.cpp | 24 ++++----
rocclr/runtime/platform/command.hpp | 10 ++--
rocclr/runtime/platform/memory.cpp | 7 ++-
rocclr/runtime/platform/memory.hpp | 6 +-
rocclr/runtime/platform/runtime.cpp | 34 ++---------
rocclr/runtime/thread/monitor.hpp | 39 ++++++++++++-
rocclr/runtime/thread/semaphore.cpp | 10 ++--
rocclr/runtime/thread/semaphore.hpp | 10 ++--
rocclr/runtime/utils/util.hpp | 91 +----------------------------
11 files changed, 78 insertions(+), 158 deletions(-)
diff --git a/rocclr/runtime/os/os_posix.cpp b/rocclr/runtime/os/os_posix.cpp
index dfe2dd4394..0c2bd457bb 100644
--- a/rocclr/runtime/os/os_posix.cpp
+++ b/rocclr/runtime/os/os_posix.cpp
@@ -32,6 +32,7 @@
# define DT_GNU_HASH 0x6ffffef5
#endif // DT_GNU_HASH
+#include
#include
#include
#include
@@ -753,7 +754,7 @@ Os::getTempPath()
std::string
Os::getTempFileName()
{
- static amd::Atomic counter = 0;
+ static std::atomic_size_t counter(0);
std::string tempPath = getTempPath();
std::stringstream tempFileName;
diff --git a/rocclr/runtime/os/os_win32.cpp b/rocclr/runtime/os/os_win32.cpp
index ceb148e73c..afde674399 100644
--- a/rocclr/runtime/os/os_win32.cpp
+++ b/rocclr/runtime/os/os_win32.cpp
@@ -731,7 +731,7 @@ Os::getTempPath()
std::string
Os::getTempFileName()
{
- static amd::Atomic counter = 0;
+ static std::atomic_size_t counter(0);
std::string tempPath = getTempPath();
std::stringstream tempFileName;
diff --git a/rocclr/runtime/platform/command.cpp b/rocclr/runtime/platform/command.cpp
index 145280f14e..97ac07c7a0 100644
--- a/rocclr/runtime/platform/command.cpp
+++ b/rocclr/runtime/platform/command.cpp
@@ -29,18 +29,16 @@ Event::Event(HostQueue& queue)
: context_(queue.context())
, callbacks_(NULL)
, status_(CL_INT_MAX)
- , notified_(0)
, profilingInfo_(
queue.properties().test(CL_QUEUE_PROFILING_ENABLE)
|| Agent::shouldPostEventEvents())
-{ }
+{ notified_.clear(); }
Event::Event(Context& context)
: context_(context)
, callbacks_(NULL)
, status_(CL_SUBMITTED)
- , notified_(0)
-{ }
+{ notified_.clear(); }
Event::~Event()
{
@@ -95,7 +93,7 @@ Event::setStatus(cl_int status, uint64_t timeStamp)
return false;
}
- if (callbacks_ != NULL) {
+ if (callbacks_ != (CallBackEntry*)0) {
processCallbacks(status);
}
@@ -131,14 +129,14 @@ Event::setCallback(cl_int status, Event::CallBackFunction callback, void* data)
}
entry->next_ = callbacks_;
- while (!callbacks_.compareAndSet(entry->next_, entry)) {
+ while (!callbacks_.compare_exchange_weak(entry->next_, entry)) {
// Someone else is also updating the head of the linked list! reload.
entry->next_ = callbacks_;
}
// Check if the event has already reached 'status'
- if (status_ <= status && entry->callback_ != NULL) {
- if (entry->callback_.swap(NULL) != NULL) {
+ if (status_ <= status && entry->callback_ != CallBackFunction(0)) {
+ if (entry->callback_.exchange(NULL) != NULL) {
callback(as_cl(this), status, entry->data_);
}
}
@@ -157,9 +155,9 @@ Event::processCallbacks(cl_int status) const
CallBackEntry* entry;
for (entry = callbacks_; entry != NULL; entry = entry->next_) {
// If the entry's status matches the mask,
- if (entry->status_ == mask && entry->callback_ != NULL) {
+ if (entry->status_ == mask && entry->callback_ != CallBackFunction(0)) {
// invoke the callback function.
- CallBackFunction callback = entry->callback_.swap(NULL);
+ CallBackFunction callback = entry->callback_.exchange(NULL);
if (callback != NULL) {
callback(event, status, entry->data_);
}
@@ -190,14 +188,12 @@ Event::awaitCompletion()
bool
Event::notifyCmdQueue()
{
- static uint Notifed = 1;
- static uint Empty = 0;
HostQueue* queue = command().queue();
- if ((NULL != queue) && notified_.compareAndSet(Empty, Notifed)) {
+ if ((NULL != queue) && !notified_.test_and_set()) {
// Make sure the queue is draining the enqueued commands.
amd::Command* command = new amd::Marker(*queue, false, nullWaitList, this);
if (command == NULL) {
- notified_.compareAndSet(Notifed, Empty);
+ notified_.clear();
return false;
}
command->enqueue();
diff --git a/rocclr/runtime/platform/command.hpp b/rocclr/runtime/platform/command.hpp
index 2aea1b8018..d630dcc08b 100644
--- a/rocclr/runtime/platform/command.hpp
+++ b/rocclr/runtime/platform/command.hpp
@@ -13,7 +13,6 @@
#define COMMAND_HPP_
#include "top.hpp"
-#include "thread/atomic.hpp"
#include "thread/monitor.hpp"
#include "thread/thread.hpp"
#include "platform/agent.hpp"
@@ -28,6 +27,7 @@
#include "CL/cl_ext.h"
#include
+#include
#include
#include
@@ -58,7 +58,7 @@ class Event : public RuntimeObject
{
struct CallBackEntry* next_; //!< the next entry in the callback list.
- Atomic callback_; //!< callback function pointer.
+ std::atomic callback_; //!< callback function pointer.
void* data_; //!< user data passed to the callback function.
cl_int status_; //!< execution status triggering the callback.
@@ -76,9 +76,9 @@ private:
Monitor lock_;
SharedReference context_; //!< context associated with this event.
- Atomic callbacks_; //!< linked list of callback entries.
- volatile cl_int status_; //!< current execution status.
- Atomic notified_; //!< Command queue was notified
+ std::atomic callbacks_; //!< linked list of callback entries.
+ volatile cl_int status_; //!< current execution status.
+ std::atomic_flag notified_; //!< Command queue was notified
protected:
diff --git a/rocclr/runtime/platform/memory.cpp b/rocclr/runtime/platform/memory.cpp
index f13eee6e04..18d742ae07 100644
--- a/rocclr/runtime/platform/memory.cpp
+++ b/rocclr/runtime/platform/memory.cpp
@@ -87,12 +87,12 @@ Memory::Memory(
, isParent_(false)
, vDev_(NULL)
, forceSysMemAlloc_(false)
- , mapCount_(0)
, svmHostAddress_(svmPtr)
, svmPtrCommited_(false)
, canBeCached_(true)
, lockMemoryOps_("Memory Ops Lock", true)
{
+ std::atomic_init(&mapCount_, 0u);
}
Memory::Memory(
@@ -117,7 +117,6 @@ Memory::Memory(
, isParent_(false)
, vDev_(NULL)
, forceSysMemAlloc_(false)
- , mapCount_(0)
, svmHostAddress_(parent.getSvmPtr())
, svmPtrCommited_(parent.isSvmPtrCommited())
, canBeCached_(true)
@@ -142,6 +141,8 @@ Memory::Memory(
(CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY |
CL_MEM_HOST_NO_ACCESS);
}
+
+ std::atomic_init(&mapCount_, 0u);
}
void
@@ -438,7 +439,7 @@ Memory::setDestructorCallback(DestructorCallBackFunction callback, void* data)
}
entry->next_ = destructorCallbacks_;
- while (!destructorCallbacks_.compareAndSet(entry->next_, entry)) {
+ while (!destructorCallbacks_.compare_exchange_weak(entry->next_, entry)) {
// Someone else is also updating the head of the linked list! reload.
entry->next_ = destructorCallbacks_;
}
diff --git a/rocclr/runtime/platform/memory.hpp b/rocclr/runtime/platform/memory.hpp
index fcf36769f2..b36a286f35 100644
--- a/rocclr/runtime/platform/memory.hpp
+++ b/rocclr/runtime/platform/memory.hpp
@@ -7,13 +7,13 @@
#include "top.hpp"
#include "utils/flags.hpp"
-#include "thread/atomic.hpp"
#include "thread/monitor.hpp"
#include "platform/context.hpp"
#include "platform/object.hpp"
#include "platform/interop.hpp"
#include "device/device.hpp"
+#include
#include
#include
#include
@@ -155,7 +155,7 @@ protected:
std::map deviceAlloced_;
//! Linked list of destructor callbacks.
- Atomic destructorCallbacks_;
+ std::atomic destructorCallbacks_;
SharedReference context_; //!< Owning context
Memory* parent_;
@@ -170,7 +170,7 @@ protected:
bool isParent_; //!< This object is a parent
device::VirtualDevice* vDev_; //!< Memory object belongs to a virtual device only
bool forceSysMemAlloc_; //!< Forces system memory allocation
- Atomic mapCount_; //!< Keep track of number of mappings for a memory object
+ std::atomic_uint mapCount_; //!< Keep track of number of mappings for a memory object
void * svmHostAddress_; //!< svm host address;
bool svmPtrCommited_; //!< svm host address committed flag;
bool canBeCached_; //!< flag to if the object can be cached;
diff --git a/rocclr/runtime/platform/runtime.cpp b/rocclr/runtime/platform/runtime.cpp
index 38f8ab7519..cdbfe127df 100644
--- a/rocclr/runtime/platform/runtime.cpp
+++ b/rocclr/runtime/platform/runtime.cpp
@@ -3,7 +3,6 @@
//
#include "platform/runtime.hpp"
-#include "thread/atomic.hpp"
#include "os/os.hpp"
#include "thread/thread.hpp"
#include "device/device.hpp"
@@ -24,14 +23,10 @@
#include
#endif
+#include
#include
#include
-#ifdef TIMEBOMB
-# include
-# include
-#endif // TIMEBOMB
-
namespace amd {
#ifdef __linux__
@@ -60,22 +55,19 @@ Runtime::init()
// from concurrently executing the init() routines. We can't use a
// Monitor since the system is not yet initialized.
- static Atomic lock = 0;
+ static std::atomic_flag lock = ATOMIC_FLAG_INIT;
struct CriticalRegion
{
- Atomic& lock_;
- CriticalRegion(Atomic& lock) : lock_(lock)
+ std::atomic_flag& lock_;
+ CriticalRegion(std::atomic_flag& lock) : lock_(lock)
{
- while (true) {
- if (lock == 0 && lock.swap(1) == 0) {
- break;
- }
+ while (lock.test_and_set(std::memory_order_acquire)) {
Os::yield();
}
}
~CriticalRegion()
{
- lock_.storeRelease(0);
+ lock_.clear(std::memory_order_release);
}
} region(lock);
@@ -83,20 +75,6 @@ Runtime::init()
return true;
}
-#ifdef TIMEBOMB
- time_t current = time(NULL);
- time_t expiration = TIMEBOMB;
-
- if (current > expiration) {
- fprintf(stderr, "Expired on %s", asctime(gmtime(&expiration)));
- return false;
- }
- else {
- fprintf(stderr, "For test only: Expires on %s",
- asctime(gmtime(&expiration)));
- }
-#endif // TIMEBOMB
-
if ( !Flag::init()
|| !option::init()
|| !Device::init()
diff --git a/rocclr/runtime/thread/monitor.hpp b/rocclr/runtime/thread/monitor.hpp
index 4a09332464..4729ea0876 100644
--- a/rocclr/runtime/thread/monitor.hpp
+++ b/rocclr/runtime/thread/monitor.hpp
@@ -6,10 +6,11 @@
#define MONITOR_HPP_
#include "top.hpp"
-#include "atomic.hpp"
+#include "thread/atomic.hpp"
#include "thread/semaphore.hpp"
#include "thread/thread.hpp"
+#include
#include
#include
@@ -22,9 +23,43 @@ namespace amd {
* @{
*/
+namespace details {
+
+template
+struct SimplyLinkedNode : public AllocClass
+{
+ typedef SimplyLinkedNode Node;
+
+protected:
+ std::atomic next_; /*!< \brief The next element. */
+ T volatile item_;
+
+public:
+ //! \brief Return the next element in the linked-list.
+ Node* next() const { return next_; }
+ //! \brief Return the item.
+ T item() const { return item_; }
+
+ //! \brief Set the next element pointer.
+ void setNext(Node* next) { next_ = next; }
+ //! \brief Set the item.
+ void setItem(T item) { item_ = item; }
+
+ //! \brief Swap the next element pointer.
+ Node* swapNext(Node* next) { return next_.swap(next); }
+
+ //! \brief Compare and set the next element pointer.
+ bool compareAndSetNext(Node* compare, Node* next)
+ {
+ return next_.compare_exchange_strong(compare, next);
+ }
+};
+
+} // namespace details
+
class Monitor : public HeapObject
{
- typedef SimplyLinkedNode LinkedNode;
+ typedef details::SimplyLinkedNode LinkedNode;
private:
static const bool kUnlocked = false;
diff --git a/rocclr/runtime/thread/semaphore.cpp b/rocclr/runtime/thread/semaphore.cpp
index f6d1a0955b..d1ff87d596 100644
--- a/rocclr/runtime/thread/semaphore.cpp
+++ b/rocclr/runtime/thread/semaphore.cpp
@@ -3,7 +3,6 @@
//
#include "thread/semaphore.hpp"
-#include "thread/atomic.hpp"
#include "thread/thread.hpp"
#if defined(_WIN32) || defined(__CYGWIN__)
@@ -16,8 +15,8 @@
namespace amd {
Semaphore::Semaphore()
- : state_(0)
{
+ std::atomic_init(&state_, 0);
#ifdef _WIN32
handle_ = static_cast(CreateSemaphore(NULL, 0, LONG_MAX, NULL));
assert(handle_ != NULL && "CreateSemaphore failed");
@@ -48,14 +47,13 @@ Semaphore::post()
while (true) {
state = state_;
if (state > 0) {
- // Do a load acquire.
- MemoryOrder::fence();
- if (state == state_) {
+ if (state == state_.load(std::memory_order_acquire)) {
return;
}
continue;
}
- if (state_.compareAndSet(state, state+1)) {
+ if (state_.compare_exchange_weak(state, state+1,
+ std::memory_order_acq_rel, std::memory_order_acquire)) {
break;
}
}
diff --git a/rocclr/runtime/thread/semaphore.hpp b/rocclr/runtime/thread/semaphore.hpp
index ede63ff2b5..93c8c0f209 100644
--- a/rocclr/runtime/thread/semaphore.hpp
+++ b/rocclr/runtime/thread/semaphore.hpp
@@ -6,9 +6,9 @@
#define SEMAPHORE_HPP_
#include "top.hpp"
-#include "thread/atomic.hpp"
#include "utils/util.hpp"
+#include
#if defined(__linux__)
# include
#endif /*linux*/
@@ -29,14 +29,14 @@ class Thread;
class Semaphore : public HeapObject
{
private:
- Atomic state_; //!< This semaphore's value.
+ std::atomic_int state_; //!< This semaphore's value.
#ifdef _WIN32
void* handle_; //!< The semaphore object's handle.
- char padding_[64-sizeof(void*)-sizeof(Atomic)];
+ char padding_[64-sizeof(void*)-sizeof(std::atomic_int)];
#else // !_WIN32
sem_t sem_; //!< The semaphore object's identifier.
- char padding_[64-sizeof(sem_t)-sizeof(Atomic)];
+ char padding_[64-sizeof(sem_t)-sizeof(std::atomic_int)];
#endif /*!_WIN32*/
public:
@@ -52,7 +52,7 @@ public:
//! \brief Reset this semaphore.
void reset()
{
- state_.swap(0);
+ state_.store(0, std::memory_order_release);
}
};
diff --git a/rocclr/runtime/utils/util.hpp b/rocclr/runtime/utils/util.hpp
index c5568ac0f6..efe0d41288 100644
--- a/rocclr/runtime/utils/util.hpp
+++ b/rocclr/runtime/utils/util.hpp
@@ -6,8 +6,8 @@
#define UTIL_HPP_
#include "top.hpp"
-#include "thread/atomic.hpp"
+#include
#include
namespace amd {
@@ -187,95 +187,6 @@ inline bool isMultipleOf(T* value, size_t alignment)
return isMultipleOf(ptr, alignment);
}
-template
-struct SimplyLinkedNode : public AllocClass
-{
- typedef SimplyLinkedNode Node;
-
-protected:
- Atomic next_; /*!< \brief The next element. */
- T volatile item_;
-
-public:
- //! \brief Return the next element in the linked-list.
- Node* next() const { return next_; }
- //! \brief Return the item.
- T item() const { return item_; }
-
- //! \brief Set the next element pointer.
- void setNext(Node* next) { next_ = next; }
- //! \brief Set the item.
- void setItem(T item) { item_ = item; }
-
- //! \brief Swap the next element pointer.
- Node* swapNext(Node* next) { return next_.swap(next); }
-
- //! \brief Compare and set the next element pointer.
- bool compareAndSetNext(Node* compare, Node* next)
- {
- return next_.compareAndSet(compare, next);
- }
-};
-
-/* For the implementation of a doubly-linked list, check:
- * Lock-Free and Practical
- * Deques and Doubly Linked
- * Lists using Single-Word
- * Compare-And-Swap
- *
- * Hakan Sundell, Philippas Tsigas
- * Department of Computing Science
- * Chalmers Univ. of Technol. and Goteborg Univ.
- */
-
-template
-struct DoublyLinkedNode
-{
- typedef SimplyLinkedNode Node;
-
-protected:
- Atomic prev_; //!< The previous element.
- Atomic next_; //!< The next element.
- T volatile item_;
-
-public:
- //! \brief Return the previous element in the linked-list.
- Node* prev() const { return prev_; }
- //! \brief Return the next element in the linked-list.
- Node* next() const { return next_; }
- //! \brief Return the item.
- T item() const { return item_; }
-
- //! \brief Set the previous element pointer.
- void setPrev(Node* prev) { prev_ = prev; }
- //! \brief Set the next element pointer.
- void setNext(Node* next) { next_ = next; }
- //! \brief Set the item.
- void setItem(T item) { item_ = item; }
-
- //! \brief Swap the previous element pointer.
- Node* swapPrev(Node* prev)
- {
- return prev_.swap(prev);
- }
- //! \brief Swap the next element pointer.
- Node* swapNext( Node* next)
- {
- return next_.swap(next);
- }
-
- //! \brief Compare and set the previous element pointer.
- bool compareAndSetPrev(Node* compare, Node* prev)
- {
- return prev_.compareAndSet(compare, prev, false, false);
- }
- //! \brief Compare and set the next element pointer.
- bool compareAndSetNext(Node* compare, Node* next)
- {
- return next_.compareAndSet(compare, next, false, false);
- }
-};
-
template
struct DeviceMap {
Reference ref_;