Browse Source

clover: Refactor event::trigger and ::abort to prevent deadlock and reentrancy issues.

Refactor ::trigger and ::abort to split out the operations that access
concurrently modified data members and require locking from the
recursive and possibly re-entrant part of these methods.  This will
avoid some deadlock situations when locking is implemented.

Tested-by: Tom Stellard <thomas.stellard@amd.com>
CC: 10.5 <mesa-stable@lists.freedesktop.org>
tags/10.6-branchpoint
Francisco Jerez 10 years ago
parent
commit
2232b929fd

+ 31
- 12
src/gallium/state_trackers/clover/core/event.cpp View File

@@ -36,28 +36,47 @@ event::event(clover::context &ctx, const ref_vector<event> &deps,
event::~event() {
}

std::vector<intrusive_ref<event>>
event::trigger_self() {
std::vector<intrusive_ref<event>> evs;

if (!--wait_count)
std::swap(_chain, evs);

return evs;
}

void
event::trigger() {
if (!--wait_count) {
cv.notify_all();
action_ok(*this);
auto evs = trigger_self();

while (!_chain.empty()) {
_chain.back()().trigger();
_chain.pop_back();
}
if (signalled()) {
action_ok(*this);
cv.notify_all();
}

for (event &ev : evs)
ev.trigger();
}

std::vector<intrusive_ref<event>>
event::abort_self(cl_int status) {
std::vector<intrusive_ref<event>> evs;

_status = status;
std::swap(_chain, evs);

return evs;
}

void
event::abort(cl_int status) {
_status = status;
auto evs = abort_self(status);

action_fail(*this);

while (!_chain.empty()) {
_chain.back()().abort(status);
_chain.pop_back();
}
for (event &ev : evs)
ev.abort(status);
}

bool

+ 3
- 0
src/gallium/state_trackers/clover/core/event.hpp View File

@@ -84,6 +84,9 @@ namespace clover {
std::vector<intrusive_ref<event>> deps;

private:
std::vector<intrusive_ref<event>> trigger_self();
std::vector<intrusive_ref<event>> abort_self(cl_int status);

unsigned wait_count;
action action_ok;
action action_fail;

Loading…
Cancel
Save