summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2015-03-26 19:33:24 +0000
committerEmil Velikov <[email protected]>2015-05-20 22:05:52 +0100
commit097e70202b6ae5b07303274c1d5087f94bd3cf06 (patch)
treeaa74accbbade1fcd1ce63609c5a6cd8097572958 /src
parent5bb7ee4fd605da1d9ca3b4aa2b6a7a28e214e0f6 (diff)
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 <[email protected]> Reviewed-by: Francisco Jerez <[email protected]> (cherry picked from commit 9c4dc98b298c74015f2a7c21571bccf0a5b6cc98)
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/clover/core/event.cpp15
-rw-r--r--src/gallium/state_trackers/clover/core/event.hpp5
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 58de8884457..55793031ad1 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 0e1359a3d20..e1727b8add5 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;
const intrusive_ref<clover::context> context;
@@ -83,6 +84,8 @@ namespace clover {
action action_ok;
action action_fail;
std::vector<intrusive_ref<event>> _chain;
+ mutable std::condition_variable cv;
+ mutable std::mutex mutex;
};
///