Fix race in isQueueBlocked.

- Sequence is as follows :
Enqueue returning event , blocked on user event.
clFinish.

There are 2 additional threads:
- one is calling updateExecutionStatus in a loop on returned
event
- one is calling setUserEventStatus on parent user event

In such case virtual event may be submitted but task count will
not be assigned.

Change-Id: Ia097bd59b276cc9213945c476cf289398b8f5934
Signed-off-by: Mrozek, Michal <michal.mrozek@intel.com>
This commit is contained in:
Mrozek, Michal
2019-07-09 10:20:59 +02:00
parent 5735e2e715
commit b349c4bb13
3 changed files with 44 additions and 1 deletions

View File

@@ -107,3 +107,41 @@ TEST_F(EventTests, givenUserEventBlockingEnqueueWithBlockingFlagWhenUserEventIsC
EXPECT_EQ(CL_SUCCESS, retVal);
t.join();
}
TEST_F(EventTests, givenoneThreadUpdatingUserEventAnotherWaitingOnFinishWhenFinishIsCalledThenItWaitsForCorrectTaskCount) {
std::unique_ptr<Buffer> srcBuffer(BufferHelper<>::create());
std::unique_ptr<char[]> dst(new char[srcBuffer->getSize()]);
for (uint32_t i = 0; i < 100; i++) {
UserEvent uEvent;
cl_event eventWaitList[] = {&uEvent};
int sizeOfWaitList = sizeof(eventWaitList) / sizeof(cl_event);
cl_event returnedEvent = nullptr;
std::atomic_bool go{false};
std::thread t([&]() {
while (!go)
;
uEvent.setStatus(CL_COMPLETE);
});
auto retVal = pCmdQ->enqueueReadBuffer(srcBuffer.get(), CL_FALSE, 0, srcBuffer->getSize(), dst.get(), nullptr, sizeOfWaitList, eventWaitList, &returnedEvent);
EXPECT_EQ(CL_SUCCESS, retVal);
std::thread t2([&]() {
castToObject<Event>(returnedEvent)->updateExecutionStatus();
});
go = true;
clFinish(pCmdQ);
EXPECT_EQ(pCmdQ->latestTaskCountWaited, i + 1);
t.join();
t2.join();
clReleaseEvent(returnedEvent);
}
}