Skip to content

Commit e1eab52

Browse files
use release for cl-objects instead of delete
- fix for data race in events - modification of the addition child event Change-Id: I6ea3a413f13f13a91d37d20d8b9fad37d0ffafb9
1 parent 3820a5e commit e1eab52

29 files changed

+329
-189
lines changed

runtime/command_queue/command_queue.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ CommandQueue::CommandQueue(Context *context, Device *deviceId, const cl_queue_pr
7676
CommandQueue::~CommandQueue() {
7777
if (virtualEvent) {
7878
UNRECOVERABLE_IF(this->virtualEvent->getCommandQueue() != this && this->virtualEvent->getCommandQueue() != nullptr);
79-
virtualEvent->setCurrentCmdQVirtualEvent(false);
8079
virtualEvent->decRefInternal();
8180
}
8281

@@ -519,7 +518,6 @@ void CommandQueue::enqueueBlockedMapUnmapOperation(const cl_event *eventWaitList
519518
eventBuilder->finalize();
520519

521520
if (this->virtualEvent) {
522-
this->virtualEvent->setCurrentCmdQVirtualEvent(false);
523521
this->virtualEvent->decRefInternal();
524522
}
525523
this->virtualEvent = eventBuilder->getEvent();

runtime/command_queue/command_queue.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Intel Corporation
2+
* Copyright (C) 2017-2019 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -10,6 +10,7 @@
1010
#include "runtime/helpers/engine_control.h"
1111
#include "runtime/helpers/task_information.h"
1212
#include "runtime/helpers/dispatch_info.h"
13+
#include "runtime/event/user_event.h"
1314
#include "instrumentation.h"
1415
#include <atomic>
1516
#include <cstdint>
@@ -341,6 +342,13 @@ class CommandQueue : public BaseObject<_cl_command_queue> {
341342

342343
MOCKABLE_VIRTUAL void releaseIndirectHeap(IndirectHeap::Type heapType);
343344

345+
void releaseVirtualEvent() {
346+
if (this->virtualEvent != nullptr) {
347+
this->virtualEvent->decRefInternal();
348+
this->virtualEvent = nullptr;
349+
}
350+
}
351+
344352
cl_command_queue_properties getCommandQueueProperties() const {
345353
return commandQueueProperties;
346354
}

runtime/command_queue/enqueue_common.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,6 @@ void CommandQueueHw<GfxFamily>::enqueueBlocked(
659659
eventBuilder = &internalEventBuilder;
660660
DBG_LOG(EventsDebugEnable, "enqueueBlocked", "new virtualEvent", eventBuilder->getEvent());
661661
}
662-
eventBuilder->getEvent()->setCurrentCmdQVirtualEvent(true);
663662

664663
//update queue taskCount
665664
taskCount = eventBuilder->getEvent()->getCompletionStamp();
@@ -720,7 +719,6 @@ void CommandQueueHw<GfxFamily>::enqueueBlocked(
720719
eventBuilder->finalize();
721720

722721
if (this->virtualEvent) {
723-
this->virtualEvent->setCurrentCmdQVirtualEvent(false);
724722
this->virtualEvent->decRefInternal();
725723
}
726724

runtime/event/event.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -416,11 +416,6 @@ void Event::unblockEventsBlockedByThis(int32_t transitionStatus) {
416416

417417
childEvent->unblockEventBy(*this, taskLevelToPropagate, transitionStatus);
418418

419-
if (childEvent->getCommandQueue() && childEvent->isCurrentCmdQVirtualEvent()) {
420-
// Check virtual event state and delete it if possible.
421-
childEvent->getCommandQueue()->isQueueBlocked();
422-
}
423-
424419
childEvent->decRefInternal();
425420
auto next = childEventRef->next;
426421
delete childEventRef;

runtime/event/event.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ class Event : public BaseObject<_cl_event>, public IDNode<Event> {
203203
}
204204
}
205205

206+
bool peekIsCmdSubmitted() {
207+
return submittedCmd != nullptr;
208+
}
209+
206210
//commands blocked by user event depencies
207211
bool isReadyForSubmission();
208212

@@ -217,6 +221,10 @@ class Event : public BaseObject<_cl_event>, public IDNode<Event> {
217221
return (CL_COMMAND_USER == cmdType);
218222
}
219223

224+
bool isEventWithoutCommand() {
225+
return eventWithoutCommand;
226+
}
227+
220228
Context *getContext() {
221229
return ctx;
222230
}

runtime/event/event_builder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Intel Corporation
2+
* Copyright (C) 2017-2019 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -53,7 +53,8 @@ void EventBuilder::finalize() {
5353

5454
//do not add as child if:
5555
//parent has no parents and is not blocked
56-
if (!(parent->peekIsBlocked() == false && parent->taskLevel != Event::eventNotReady)) {
56+
if (!(parent->peekIsBlocked() == false && parent->taskLevel != Event::eventNotReady) ||
57+
(!parent->isEventWithoutCommand() && !parent->peekIsCmdSubmitted())) {
5758
parent->addChild(*this->event);
5859
}
5960
}

runtime/helpers/queue_helpers.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111
#include "runtime/helpers/get_info.h"
1212

1313
namespace OCLRT {
14+
15+
inline void releaseVirtualEvent(CommandQueue &commandQueue) {
16+
if (commandQueue.getRefApiCount() == 1) {
17+
commandQueue.releaseVirtualEvent();
18+
}
19+
}
20+
21+
inline void releaseVirtualEvent(DeviceQueue &commandQueue) {
22+
}
23+
1424
template <typename QueueType>
1525
void retainQueue(cl_command_queue commandQueue, cl_int &retVal) {
1626
using BaseType = typename QueueType::BaseType;
@@ -26,6 +36,7 @@ void releaseQueue(cl_command_queue commandQueue, cl_int &retVal) {
2636
using BaseType = typename QueueType::BaseType;
2737
auto queue = castToObject<QueueType>(static_cast<BaseType *>(commandQueue));
2838
if (queue) {
39+
releaseVirtualEvent(*queue);
2940
queue->release();
3041
retVal = CL_SUCCESS;
3142
}

unit_tests/command_queue/command_queue_hw_tests.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "unit_tests/fixtures/buffer_fixture.h"
1212
#include "unit_tests/fixtures/context_fixture.h"
1313
#include "unit_tests/fixtures/device_fixture.h"
14+
#include "unit_tests/utilities/base_object_utils.h"
1415
#include "unit_tests/helpers/debug_manager_state_restore.h"
1516
#include "unit_tests/helpers/unit_test_helper.h"
1617
#include "unit_tests/mocks/mock_buffer.h"
@@ -361,6 +362,7 @@ HWTEST_F(CommandQueueHwTest, GivenNotCompleteUserEventPassedToEnqueueWhenEventIs
361362
mockCSR->getMemoryManager()->freeGraphicsMemory(privateSurface);
362363
mockCSR->getMemoryManager()->freeGraphicsMemory(printfSurface);
363364
mockCSR->getMemoryManager()->freeGraphicsMemory(constantSurface);
365+
pCmdQ->isQueueBlocked();
364366
}
365367

366368
typedef CommandQueueHwTest BlockedCommandQueueTest;
@@ -387,6 +389,8 @@ HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWhenBlockedCommandIsBeingSubm
387389
EXPECT_EQ(0u, ioh.getUsed());
388390
EXPECT_EQ(0u, dsh.getUsed());
389391
EXPECT_EQ(defaultSshUse, ssh.getUsed());
392+
393+
pCmdQ->isQueueBlocked();
390394
}
391395

392396
HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWithUsedHeapsWhenBlockedCommandIsBeingSubmittedThenQueueHeapsAreNotUsed) {
@@ -417,6 +421,8 @@ HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWithUsedHeapsWhenBlockedComma
417421
EXPECT_EQ(spaceToUse, ioh.getUsed());
418422
EXPECT_EQ(spaceToUse, dsh.getUsed());
419423
EXPECT_EQ(sshSpaceUse, ssh.getUsed());
424+
425+
pCmdQ->isQueueBlocked();
420426
}
421427

422428
HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWhichHasSomeUnusedHeapsWhenBlockedCommandIsBeingSubmittedThenThoseHeapsAreBeingUsed) {
@@ -443,6 +449,8 @@ HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWhichHasSomeUnusedHeapsWhenBl
443449
EXPECT_EQ(iohBase, ioh.getCpuBase());
444450
EXPECT_EQ(dshBase, dsh.getCpuBase());
445451
EXPECT_EQ(sshBase, ssh.getCpuBase());
452+
453+
pCmdQ->isQueueBlocked();
446454
}
447455

448456
HWTEST_F(BlockedCommandQueueTest, givenEnqueueBlockedByUserEventWhenItIsEnqueuedThenKernelReferenceCountIsIncreased) {
@@ -459,6 +467,7 @@ HWTEST_F(BlockedCommandQueueTest, givenEnqueueBlockedByUserEventWhenItIsEnqueued
459467
pCmdQ->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr);
460468
EXPECT_EQ(currentRefCount + 1, mockKernel->getRefInternalCount());
461469
userEvent.setStatus(CL_COMPLETE);
470+
pCmdQ->isQueueBlocked();
462471
EXPECT_EQ(currentRefCount, mockKernel->getRefInternalCount());
463472
}
464473

@@ -490,7 +499,7 @@ HWTEST_F(CommandQueueHwRefCountTest, givenBlockedCmdQWhenNewBlockedEnqueueReplac
490499

491500
userEvent.setStatus(CL_COMPLETE);
492501
// UserEvent is set to complete and event tree is unblocked, queue has only 1 refference to itself after this operation
493-
EXPECT_EQ(1, mockCmdQ->getRefInternalCount());
502+
EXPECT_EQ(2, mockCmdQ->getRefInternalCount());
494503

495504
//this call will release the queue
496505
releaseQueue<CommandQueue>(mockCmdQ, retVal);
@@ -530,12 +539,13 @@ HWTEST_F(CommandQueueHwRefCountTest, givenBlockedCmdQWithOutputEventAsVirtualEve
530539
// unblocking deletes 2 virtualEvents
531540
userEvent.setStatus(CL_COMPLETE);
532541

533-
EXPECT_EQ(2, mockCmdQ->getRefInternalCount());
542+
EXPECT_EQ(3, mockCmdQ->getRefInternalCount());
534543

535544
auto pEventOut = castToObject<Event>(eventOut);
536545
pEventOut->release();
537546
// releasing output event decrements refCount
538-
EXPECT_EQ(1, mockCmdQ->getRefInternalCount());
547+
EXPECT_EQ(2, mockCmdQ->getRefInternalCount());
548+
mockCmdQ->isQueueBlocked();
539549

540550
releaseQueue<CommandQueue>(mockCmdQ, retVal);
541551
}
@@ -575,13 +585,16 @@ HWTEST_F(CommandQueueHwRefCountTest, givenSeriesOfBlockedEnqueuesWhenEveryEventI
575585
userEvent->setStatus(CL_COMPLETE);
576586

577587
userEvent->release();
578-
// releasing UserEvent doesn't change the refCount
579-
EXPECT_EQ(2, mockCmdQ->getRefInternalCount());
588+
EXPECT_EQ(3, mockCmdQ->getRefInternalCount());
580589

581590
auto pEventOut = castToObject<Event>(eventOut);
582591
pEventOut->release();
583592

584593
// releasing output event decrements refCount
594+
EXPECT_EQ(2, mockCmdQ->getRefInternalCount());
595+
596+
mockCmdQ->isQueueBlocked();
597+
585598
EXPECT_EQ(1, mockCmdQ->getRefInternalCount());
586599

587600
releaseQueue<CommandQueue>(mockCmdQ, retVal);
@@ -622,7 +635,7 @@ HWTEST_F(CommandQueueHwRefCountTest, givenSeriesOfBlockedEnqueuesWhenCmdQIsRelea
622635

623636
userEvent->release();
624637
// releasing UserEvent doesn't change the queue refCount
625-
EXPECT_EQ(2, mockCmdQ->getRefInternalCount());
638+
EXPECT_EQ(3, mockCmdQ->getRefInternalCount());
626639

627640
releaseQueue<CommandQueue>(mockCmdQ, retVal);
628641

@@ -963,6 +976,7 @@ HWTEST_F(CommandQueueHwTest, givenWalkerSplitEnqueueNDRangeWhenBlockedThenKernel
963976
EXPECT_EQ(1u, mockKernel->getResidencyCalls);
964977

965978
userEvent.setStatus(CL_COMPLETE);
979+
pCmdQ->isQueueBlocked();
966980
}
967981

968982
HWTEST_F(CommandQueueHwTest, givenKernelSplitEnqueueReadBufferWhenBlockedThenEnqueueSurfacesMakeResidentIsCalledOnce) {
@@ -972,7 +986,7 @@ HWTEST_F(CommandQueueHwTest, givenKernelSplitEnqueueReadBufferWhenBlockedThenEnq
972986
csr.timestampPacketWriteEnabled = false;
973987

974988
BufferDefaults::context = context;
975-
std::unique_ptr<Buffer> buffer(BufferHelper<>::create());
989+
auto buffer = clUniquePtr(BufferHelper<>::create());
976990
GraphicsAllocation *bufferAllocation = buffer->getGraphicsAllocation();
977991
char array[3 * MemoryConstants::cacheLineSize];
978992
char *ptr = &array[MemoryConstants::cacheLineSize];
@@ -995,4 +1009,6 @@ HWTEST_F(CommandQueueHwTest, givenKernelSplitEnqueueReadBufferWhenBlockedThenEnq
9951009
}
9961010
EXPECT_EQ(expected, it->second);
9971011
}
1012+
1013+
pCmdQ->isQueueBlocked();
9981014
}

unit_tests/command_queue/enqueue_handler_tests.cpp

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -200,54 +200,11 @@ HWTEST_F(EnqueueHandlerTest, enqueueBlockedSetsVirtualEventAsCurrentCmdQVirtualE
200200

201201
ASSERT_NE(nullptr, mockCmdQ->virtualEvent);
202202

203-
EXPECT_TRUE(mockCmdQ->virtualEvent->isCurrentCmdQVirtualEvent());
204-
205203
mockCmdQ->virtualEvent->setStatus(CL_COMPLETE);
206204
mockCmdQ->isQueueBlocked();
207205
mockCmdQ->release();
208206
}
209207

210-
HWTEST_F(EnqueueHandlerTest, enqueueBlockedUnsetsCurrentCmdQVirtualEventForPreviousVirtualEvent) {
211-
212-
UserEvent userEvent;
213-
cl_event clUserEvent = &userEvent;
214-
215-
MockKernelWithInternals kernelInternals(*pDevice, context);
216-
217-
Kernel *kernel = kernelInternals.mockKernel;
218-
219-
MockMultiDispatchInfo multiDispatchInfo(kernel);
220-
221-
auto mockCmdQ = new MockCommandQueueHw<FamilyType>(context, pDevice, 0);
222-
223-
// put queue into initial blocked state with userEvent
224-
225-
bool blocking = false;
226-
mockCmdQ->template enqueueHandler<CL_COMMAND_NDRANGE_KERNEL>(nullptr,
227-
0,
228-
blocking,
229-
multiDispatchInfo,
230-
1,
231-
&clUserEvent,
232-
nullptr);
233-
234-
ASSERT_NE(nullptr, mockCmdQ->virtualEvent);
235-
Event *previousVirtualEvent = mockCmdQ->virtualEvent;
236-
237-
mockCmdQ->template enqueueHandler<CL_COMMAND_NDRANGE_KERNEL>(nullptr,
238-
0,
239-
blocking,
240-
multiDispatchInfo,
241-
0,
242-
nullptr,
243-
nullptr);
244-
245-
EXPECT_FALSE(previousVirtualEvent->isCurrentCmdQVirtualEvent());
246-
EXPECT_TRUE(mockCmdQ->virtualEvent->isCurrentCmdQVirtualEvent());
247-
248-
mockCmdQ->release();
249-
}
250-
251208
HWTEST_F(EnqueueHandlerTest, enqueueWithOutputEventRegistersEvent) {
252209
MockKernelWithInternals kernelInternals(*pDevice, context);
253210
Kernel *kernel = kernelInternals.mockKernel;

unit_tests/command_queue/enqueue_kernel_2_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ HWTEST_P(EnqueueKernelPrintfTest, GivenKernelWithPrintfBlockedByEventWhenEventUn
643643

644644
std::string output = testing::internal::GetCapturedStdout();
645645
EXPECT_STREQ("test", output.c_str());
646+
pCmdQ->releaseVirtualEvent();
646647
}
647648
}
648649

0 commit comments

Comments
 (0)