Deferred deletion of allocations in main thread

Add a clearQueueTillFirstFailure interface to DeferredDeleter, which
iterates the queue from the front and delete the allocations in the
queue till a failure. It is called by defer deletion of allocations
occupied by mutliple contexts to unlock the execution in main thread

Related-To: NEO-7532

Signed-off-by: HeFan2017 <fan.f.he@intel.com>
This commit is contained in:
HeFan2017
2022-12-12 10:57:02 +00:00
committed by Compute-Runtime-Automation
parent 1ad4b81b28
commit 2ea734491a
21 changed files with 245 additions and 51 deletions

View File

@@ -2200,41 +2200,6 @@ HWTEST_F(GraphicsAllocationTests, givenAllocationUsedOnlyByNonDefaultDeviceWhenC
// no need to call freeGraphicsAllocation
}
HWTEST_F(GraphicsAllocationTests, givenAllocationUsedByManyOsContextsWhenCheckingUsageBeforeDestroyThenMultiContextDestructorIsUsedForWaitingForAllOsContexts) {
ExecutionEnvironment *executionEnvironment = platform()->peekExecutionEnvironment();
auto memoryManager = new MockMemoryManager(false, false, *executionEnvironment);
executionEnvironment->memoryManager.reset(memoryManager);
auto multiContextDestructor = new MockDeferredDeleter();
multiContextDestructor->expectDrainBlockingValue(false);
memoryManager->multiContextResourceDestructor.reset(multiContextDestructor);
auto device = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(executionEnvironment, 0u));
auto &lowPriorityEngine = device->getEngine(device->getHardwareInfo().capabilityTable.defaultEngineType, EngineUsage::LowPriority);
auto nonDefaultOsContext = lowPriorityEngine.osContext;
auto nonDefaultCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(lowPriorityEngine.commandStreamReceiver);
auto defaultCsr = static_cast<UltCommandStreamReceiver<FamilyType> *>(device->getDefaultEngine().commandStreamReceiver);
auto defaultOsContext = device->getDefaultEngine().osContext;
EXPECT_FALSE(defaultOsContext->isLowPriority());
EXPECT_TRUE(nonDefaultOsContext->isLowPriority());
auto graphicsAllocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{device->getRootDeviceIndex(), MemoryConstants::pageSize});
nonDefaultCsr->taskCount = *nonDefaultCsr->getTagAddress();
nonDefaultCsr->latestFlushedTaskCount = *nonDefaultCsr->getTagAddress();
graphicsAllocation->updateTaskCount(*nonDefaultCsr->getTagAddress(), nonDefaultOsContext->getContextId());
graphicsAllocation->updateTaskCount(0, defaultOsContext->getContextId()); // used and ready
EXPECT_TRUE(graphicsAllocation->isUsedByManyOsContexts());
memoryManager->checkGpuUsageAndDestroyGraphicsAllocations(graphicsAllocation);
EXPECT_EQ(1, multiContextDestructor->deferDeletionCalled);
EXPECT_TRUE(nonDefaultCsr->getInternalAllocationStorage()->getTemporaryAllocations().peekIsEmpty());
EXPECT_TRUE(defaultCsr->getInternalAllocationStorage()->getTemporaryAllocations().peekIsEmpty());
}
TEST(GraphicsAllocation, givenSharedHandleBasedConstructorWhenGraphicsAllocationIsCreatedThenGpuAddressHasCorrectValue) {
uintptr_t address = 0xf0000000;
void *addressWithTrailingBitSet = reinterpret_cast<void *>(address);

View File

@@ -30,7 +30,7 @@ struct ClearQueueTest : public ::testing::Test,
static void threadMethod(MockDeferredDeleter *deleter) {
while (!startClear)
;
deleter->clearQueue();
deleter->clearQueue(false);
threadStopped++;
}
MockDeferrableDeletion *createDeletion() {

View File

@@ -223,3 +223,20 @@ TEST_F(DeferredDeleterTest, givenDeferredDeleterWhenNonBlockingDrainIsCalledThen
EXPECT_EQ(0, deleter->areElementsReleasedCalled);
EXPECT_EQ(1, deleter->drainCalled);
}
TEST_F(DeferredDeleterTest, GivenAsyncThreadStartedThenCallClearQueueTillFirstFailure) {
deleter->DeferredDeleter::addClient();
waitForAsyncThread();
auto deletion = createDeletion();
deleter->DeferredDeleter::deferDeletion(deletion);
deleter->clearQueueTillFirstFailure();
EXPECT_TRUE(deleter->isThreadRunning());
EXPECT_TRUE(deleter->isWorking());
EXPECT_EQ(0, deleter->clearCalledWithBreakTillFailure);
deleter->allowEarlyStopThread();
deleter->DeferredDeleter::removeClient();
EXPECT_TRUE(deleter->isQueueEmpty());
}