diff --git a/rocclr/runtime/platform/commandqueue.cpp b/rocclr/runtime/platform/commandqueue.cpp index 705f381267..3d6148f6fc 100644 --- a/rocclr/runtime/platform/commandqueue.cpp +++ b/rocclr/runtime/platform/commandqueue.cpp @@ -163,6 +163,12 @@ void HostQueue::append(Command& command) { queue_.enqueue(&command); } + +bool HostQueue::isEmpty() { + // Get a snapshot of queue size + return queue_.empty(); +} + DeviceQueue::~DeviceQueue() { delete virtualDevice_; ScopedLock lock(context().lock()); diff --git a/rocclr/runtime/platform/commandqueue.hpp b/rocclr/runtime/platform/commandqueue.hpp index 218e36913b..85563746bf 100644 --- a/rocclr/runtime/platform/commandqueue.hpp +++ b/rocclr/runtime/platform/commandqueue.hpp @@ -196,6 +196,9 @@ class HostQueue : public CommandQueue { //! Finish all queued commands void finish(); + //! Check if hostQueue empty snapshot + bool isEmpty(); + //! Get virtual device for the current command queue device::VirtualDevice* vdev() const { return thread_.vdev(); } diff --git a/rocclr/runtime/utils/concurrent.hpp b/rocclr/runtime/utils/concurrent.hpp index 5a64c01d97..e1338f203f 100644 --- a/rocclr/runtime/utils/concurrent.hpp +++ b/rocclr/runtime/utils/concurrent.hpp @@ -90,6 +90,9 @@ template class ConcurrentLinkedQueue : public HeapObject //! \brief Dequeue an element from this queue. inline T dequeue(); + + //! \brief Check if queue is empty + inline bool empty(); }; /*@}*/ @@ -169,6 +172,22 @@ template inline T ConcurrentLinkedQueue::dequeue() { } } +template inline bool ConcurrentLinkedQueue::empty() { + for (;;) { + typename Node::Ptr head = head_.load(std::memory_order_acquire); + typename Node::Ptr tail = tail_.load(std::memory_order_acquire); + typename Node::Ptr next = head->ptr()->next_.load(std::memory_order_acquire); + if (likely(head == head_.load(std::memory_order_acquire))) { + if (head->ptr() == tail->ptr()) { + if (next->ptr() == NULL) { + return true; + } + } + return false; + } + } +} + } // namespace amd #endif /*CONCURRENT_HPP_*/