From 4993a94b5b76b299b316877b50840d774fa6daab Mon Sep 17 00:00:00 2001 From: Maciej Dziuban Date: Wed, 4 Jul 2018 10:41:58 +0200 Subject: [PATCH] Prepare for future changes - Implement changing MemObj's GraphicsAllocation - Create function for resolving change of SharedHandler's GraphicsAllocation Change-Id: Ibd975070ca11ba8591f5561d9f02bf5d9af1636b --- runtime/mem_obj/mem_obj.cpp | 10 ++ runtime/mem_obj/mem_obj.h | 3 +- runtime/sharings/sharing.cpp | 12 ++- runtime/sharings/sharing.h | 1 + unit_tests/mem_obj/mem_obj_tests.cpp | 129 +++++++++++++++++++++++--- unit_tests/sharings/sharing_tests.cpp | 11 +++ 6 files changed, 152 insertions(+), 14 deletions(-) diff --git a/runtime/mem_obj/mem_obj.cpp b/runtime/mem_obj/mem_obj.cpp index 4e00c9bde9..4fea37e22e 100644 --- a/runtime/mem_obj/mem_obj.cpp +++ b/runtime/mem_obj/mem_obj.cpp @@ -246,6 +246,16 @@ GraphicsAllocation *MemObj::getGraphicsAllocation() { return graphicsAllocation; } +void MemObj::resetGraphicsAllocation(GraphicsAllocation *newGraphicsAllocation) { + TakeOwnershipWrapper lock(*this); + + if (graphicsAllocation != nullptr && (peekSharingHandler() == nullptr || graphicsAllocation->peekReuseCount() == 0)) { + memoryManager->checkGpuUsageAndDestroyGraphicsAllocations(graphicsAllocation); + } + + graphicsAllocation = newGraphicsAllocation; +} + bool MemObj::readMemObjFlagsInvalid() { if (this->getFlags() & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) { return true; diff --git a/runtime/mem_obj/mem_obj.h b/runtime/mem_obj/mem_obj.h index a2a2e99900..abbc3c295b 100644 --- a/runtime/mem_obj/mem_obj.h +++ b/runtime/mem_obj/mem_obj.h @@ -94,6 +94,7 @@ class MemObj : public BaseObject<_cl_mem> { virtual void transferDataFromHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) { UNRECOVERABLE_IF(true); }; GraphicsAllocation *getGraphicsAllocation(); + void resetGraphicsAllocation(GraphicsAllocation *newGraphicsAllocation); GraphicsAllocation *getMcsAllocation() { return mcsAllocation; } void setMcsAllocation(GraphicsAllocation *alloc) { mcsAllocation = alloc; } @@ -115,7 +116,7 @@ class MemObj : public BaseObject<_cl_mem> { void setSharingHandler(SharingHandler *sharingHandler) { this->sharingHandler.reset(sharingHandler); } void setParentSharingHandler(std::shared_ptr &handler) { sharingHandler = handler; } unsigned int acquireCount = 0; - const Context *getContext() const { return context; } + Context *getContext() const { return context; } void waitForCsrCompletion(); void destroyGraphicsAllocation(GraphicsAllocation *allocation, bool asyncDestroy); diff --git a/runtime/sharings/sharing.cpp b/runtime/sharings/sharing.cpp index ad45477fb8..e9b7f6e2ab 100644 --- a/runtime/sharings/sharing.cpp +++ b/runtime/sharings/sharing.cpp @@ -26,6 +26,7 @@ #include namespace OCLRT { + int SharingHandler::acquire(MemObj *memObj) { if (acquireCount == 0) { UpdateData updateData; @@ -33,11 +34,15 @@ int SharingHandler::acquire(MemObj *memObj) { updateData.sharedHandle = currentSharedHandle; updateData.memObject = memObj; int result = synchronizeHandler(&updateData); + resolveGraphicsAllocationChange(currentSharedHandle, &updateData); if (result != CL_SUCCESS) { return result; } - DEBUG_BREAK_IF(updateData.synchronizationStatus != SynchronizeStatus::ACQUIRE_SUCCESFUL); - DEBUG_BREAK_IF(currentSharedHandle != updateData.sharedHandle); + if (updateData.synchronizationStatus != SynchronizeStatus::ACQUIRE_SUCCESFUL) { + return CL_OUT_OF_RESOURCES; + } + + DEBUG_BREAK_IF(memObj->getGraphicsAllocation()->peekSharedHandle() != updateData.sharedHandle); } acquireCount++; return CL_SUCCESS; @@ -56,6 +61,9 @@ int SharingHandler::validateUpdateData(UpdateData *updateData) { return CL_SUCCESS; } +void SharingHandler::resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData) { +} + void SharingHandler::release(MemObj *memObject) { DEBUG_BREAK_IF(acquireCount <= 0); acquireCount--; diff --git a/runtime/sharings/sharing.h b/runtime/sharings/sharing.h index 2ca93fa961..821ea66722 100644 --- a/runtime/sharings/sharing.h +++ b/runtime/sharings/sharing.h @@ -61,6 +61,7 @@ class SharingHandler { virtual int synchronizeHandler(UpdateData *updateData); virtual int validateUpdateData(UpdateData *updateData); virtual void synchronizeObject(UpdateData *updateData) { updateData->synchronizationStatus = SYNCHRONIZE_ERROR; } + virtual void resolveGraphicsAllocationChange(osHandle currentSharedHandle, UpdateData *updateData); virtual void releaseResource(MemObj *memObject){}; unsigned int acquireCount = 0u; }; diff --git a/unit_tests/mem_obj/mem_obj_tests.cpp b/unit_tests/mem_obj/mem_obj_tests.cpp index 5de2db1aee..8826084999 100644 --- a/unit_tests/mem_obj/mem_obj_tests.cpp +++ b/unit_tests/mem_obj/mem_obj_tests.cpp @@ -32,6 +32,38 @@ using namespace OCLRT; +struct MySharingHandler : public SharingHandler { + MySharingHandler(MemObj *memObj) : memObj(memObj) { + auto alloc = getAllocation(); + if (alloc) { + alloc->incReuseCount(); + } + } + MySharingHandler(GraphicsAllocation *allocation) : allocation(allocation) { + auto alloc = getAllocation(); + if (alloc) { + alloc->incReuseCount(); + } + } + + void releaseReusedGraphicsAllocation() override { + auto alloc = getAllocation(); + if (alloc) { + alloc->decReuseCount(); + } + } + + GraphicsAllocation *getAllocation() { + if (memObj) { + return memObj->getGraphicsAllocation(); + } + return allocation; + } + + MemObj *memObj = nullptr; + GraphicsAllocation *allocation = nullptr; +}; + TEST(MemObj, useCount) { char buffer[64]; MockContext context; @@ -333,17 +365,6 @@ TEST(MemObj, givenDefaultWhenAskedForCpuMappingThenReturnTrue) { } TEST(MemObj, givenMultipleMemObjectsWithReusedGraphicsAllocationWhenDestroyedThenFreeAllocationOnce) { - // Each SharingHandler should have own implementation of reuseCount management - struct MySharingHandler : public SharingHandler { - MySharingHandler(GraphicsAllocation *allocation) : allocation(allocation) { - allocation->incReuseCount(); - } - void releaseReusedGraphicsAllocation() override { - allocation->decReuseCount(); - } - - GraphicsAllocation *allocation = nullptr; - }; MockMemoryManager memoryManager; MockContext context; @@ -379,3 +400,89 @@ TEST(MemObj, givenMemObjectWhenContextIsNotNullThenContextOutlivesMemobjects) { } EXPECT_EQ(1, context.getRefInternalCount()); } + +TEST(MemObj, givenSharedMemObjectWithNullGfxAllocationWhenSettingGfxAllocationThenSucceed) { + MockMemoryManager memoryManager; + MockContext context; + context.setMemoryManager(&memoryManager); + MockGraphicsAllocation *gfxAllocation = new MockGraphicsAllocation(nullptr, 0); + + MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR, + 1, nullptr, nullptr, nullptr, true, false, false); + memObj.setSharingHandler(new MySharingHandler(&memObj)); + + memObj.resetGraphicsAllocation(gfxAllocation); + gfxAllocation->incReuseCount(); + + ASSERT_EQ(1u, gfxAllocation->peekReuseCount()); + EXPECT_EQ(gfxAllocation, memObj.getGraphicsAllocation()); +} + +TEST(MemObj, givenSharedMemObjectAndNullGfxAllocationProvidedWhenSettingGfxAllocationThenSucceed) { + MockMemoryManager memoryManager; + MockContext context; + context.setMemoryManager(&memoryManager); + MockGraphicsAllocation *graphicsAllocation = new MockGraphicsAllocation(nullptr, 0); + + MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR, + 1, nullptr, nullptr, graphicsAllocation, true, false, false); + memObj.setSharingHandler(new MySharingHandler(&memObj)); + + graphicsAllocation->decReuseCount(); + memObj.resetGraphicsAllocation(nullptr); + + EXPECT_EQ(nullptr, memObj.getGraphicsAllocation()); +} + +TEST(MemObj, givenSharedMemObjectAndZeroReuseCountWhenChangingGfxAllocationThenOldAllocationIsDestroyed) { + MockMemoryManager memoryManager; + MockContext context; + context.setMemoryManager(&memoryManager); + MockGraphicsAllocation *oldGfxAllocation = new MockGraphicsAllocation(nullptr, 0); + MockGraphicsAllocation *newGfxAllocation = new MockGraphicsAllocation(nullptr, 0); + + MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR, + 1, nullptr, nullptr, oldGfxAllocation, true, false, false); + memObj.setSharingHandler(new MySharingHandler(&memObj)); + + oldGfxAllocation->decReuseCount(); + memObj.resetGraphicsAllocation(newGfxAllocation); + newGfxAllocation->incReuseCount(); + + ASSERT_EQ(1u, newGfxAllocation->peekReuseCount()); + EXPECT_EQ(newGfxAllocation, memObj.getGraphicsAllocation()); +} + +TEST(MemObj, givenSharedMemObjectAndNonZeroReuseCountWhenChangingGfxAllocationThenOldAllocationIsNotDestroyed) { + MockMemoryManager memoryManager; + MockContext context; + context.setMemoryManager(&memoryManager); + MockGraphicsAllocation *oldGfxAllocation = new MockGraphicsAllocation(nullptr, 0); + MockGraphicsAllocation *newGfxAllocation = new MockGraphicsAllocation(nullptr, 0); + + MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR, + 1, nullptr, nullptr, oldGfxAllocation, true, false, false); + memObj.setSharingHandler(new MySharingHandler(&memObj)); + + memObj.resetGraphicsAllocation(newGfxAllocation); + newGfxAllocation->incReuseCount(); + + ASSERT_EQ(1u, newGfxAllocation->peekReuseCount()); + EXPECT_EQ(newGfxAllocation, memObj.getGraphicsAllocation()); + memoryManager.checkGpuUsageAndDestroyGraphicsAllocations(oldGfxAllocation); +} + +TEST(MemObj, givenNotSharedMemObjectWhenChangingGfxAllocationThenOldAllocationIsDestroyed) { + MockMemoryManager memoryManager; + MockContext context; + context.setMemoryManager(&memoryManager); + MockGraphicsAllocation *oldGfxAllocation = new MockGraphicsAllocation(nullptr, 0); + MockGraphicsAllocation *newGfxAllocation = new MockGraphicsAllocation(nullptr, 0); + + MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR, + 1, nullptr, nullptr, oldGfxAllocation, true, false, false); + + memObj.resetGraphicsAllocation(newGfxAllocation); + + EXPECT_EQ(newGfxAllocation, memObj.getGraphicsAllocation()); +} diff --git a/unit_tests/sharings/sharing_tests.cpp b/unit_tests/sharings/sharing_tests.cpp index f97d7d3c80..47ec20982c 100644 --- a/unit_tests/sharings/sharing_tests.cpp +++ b/unit_tests/sharings/sharing_tests.cpp @@ -115,3 +115,14 @@ TEST(sharingHandler, givenSharingHandlerWhenValidateUpdateDataIsCalledWithNonNul UpdateData updateData; sharingHandler.validateUpdateData(&updateData); } + +TEST(sharingHandler, givenSharingHandlerWhenAcquiringThenReturnErrorCode) { + SharingHandler sharingHandler; + MockContext context; + MockGraphicsAllocation *graphicsAllocation = new MockGraphicsAllocation(nullptr, 0); + MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR, + 1, nullptr, nullptr, graphicsAllocation, true, false, false); + + auto result = sharingHandler.acquire(&memObj); + EXPECT_NE(CL_SUCCESS, result); +}