Mesa (master): clover: Fix a bug with multi-threaded events v2

Tom Stellard tstellar at kemper.freedesktop.org
Mon May 11 18:59:28 UTC 2015


Module: Mesa
Branch: master
Commit: 9c4dc98b298c74015f2a7c21571bccf0a5b6cc98
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9c4dc98b298c74015f2a7c21571bccf0a5b6cc98

Author: Tom Stellard <thomas.stellard at amd.com>
Date:   Thu Mar 26 19:33:24 2015 +0000

clover: Fix a bug with multi-threaded events v2

It was possible for some events never to get triggered if one thread
was creating events and another threads was waiting for them.

This patch consolidates soft_event::wait() and hard_event::wait()
into event::wait() so that hard_event objects will now wait for
all their dependencies to be submitted before flushing the command
queue.

v2:
  - Rename variables
  - Use mutable varibales so we can keep event::wait() const
  - Open code signalled() call so mutex can be atted to signalled
    without deadlocking.

CC: 10.5 <mesa-stable at lists.freedesktop.org>

Reviewed-by: Francisco Jerez <currojerez at riseup.net>

---

 src/gallium/state_trackers/clover/core/event.cpp |   15 +++++++++++++--
 src/gallium/state_trackers/clover/core/event.hpp |    5 ++++-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp
index 58de888..5579303 100644
--- a/src/gallium/state_trackers/clover/core/event.cpp
+++ b/src/gallium/state_trackers/clover/core/event.cpp
@@ -39,6 +39,7 @@ event::~event() {
 void
 event::trigger() {
    if (!--wait_count) {
+      cv.notify_all();
       action_ok(*this);
 
       while (!_chain.empty()) {
@@ -73,6 +74,15 @@ event::chain(event &ev) {
    ev.deps.push_back(*this);
 }
 
+void
+event::wait() const {
+   for (event &ev : deps)
+      ev.wait();
+
+   std::unique_lock<std::mutex> lock(mutex);
+   cv.wait(lock, [=]{ return !wait_count; });
+}
+
 hard_event::hard_event(command_queue &q, cl_command_type command,
                        const ref_vector<event> &deps, action action) :
    event(q.context(), deps, profile(q, action), [](event &ev){}),
@@ -120,6 +130,8 @@ void
 hard_event::wait() const {
    pipe_screen *screen = queue()->device().pipe;
 
+   event::wait();
+
    if (status() == CL_QUEUED)
       queue()->flush();
 
@@ -207,8 +219,7 @@ soft_event::command() const {
 
 void
 soft_event::wait() const {
-   for (event &ev : deps)
-      ev.wait();
+   event::wait();
 
    if (status() != CL_COMPLETE)
       throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
diff --git a/src/gallium/state_trackers/clover/core/event.hpp b/src/gallium/state_trackers/clover/core/event.hpp
index d407c80..0914842 100644
--- a/src/gallium/state_trackers/clover/core/event.hpp
+++ b/src/gallium/state_trackers/clover/core/event.hpp
@@ -23,6 +23,7 @@
 #ifndef CLOVER_CORE_EVENT_HPP
 #define CLOVER_CORE_EVENT_HPP
 
+#include <condition_variable>
 #include <functional>
 
 #include "core/object.hpp"
@@ -68,7 +69,7 @@ namespace clover {
       virtual cl_int status() const = 0;
       virtual command_queue *queue() const = 0;
       virtual cl_command_type command() const = 0;
-      virtual void wait() const = 0;
+      virtual void wait() const;
 
       virtual struct pipe_fence_handle *fence() const {
          return NULL;
@@ -87,6 +88,8 @@ namespace clover {
       action action_ok;
       action action_fail;
       std::vector<intrusive_ref<event>> _chain;
+      mutable std::condition_variable cv;
+      mutable std::mutex mutex;
    };
 
    ///




More information about the mesa-commit mailing list