diff --git a/core/helpers/non_copyable_or_moveable.h b/core/helpers/non_copyable_or_moveable.h index 9e1dcbc97d..c3a789bba1 100644 --- a/core/helpers/non_copyable_or_moveable.h +++ b/core/helpers/non_copyable_or_moveable.h @@ -16,4 +16,14 @@ class NonCopyableOrMovableClass { NonCopyableOrMovableClass(NonCopyableOrMovableClass &&) = delete; NonCopyableOrMovableClass &operator=(NonCopyableOrMovableClass &&) = delete; }; + +class NonCopyableClass { + public: + NonCopyableClass() = default; + NonCopyableClass(const NonCopyableClass &) = delete; + NonCopyableClass &operator=(const NonCopyableClass &) = delete; + + NonCopyableClass(NonCopyableClass &&) = default; + NonCopyableClass &operator=(NonCopyableClass &&) = default; +}; } // namespace NEO diff --git a/core/utilities/idlist.h b/core/utilities/idlist.h index 569e95357b..ed6129dbb1 100644 --- a/core/utilities/idlist.h +++ b/core/utilities/idlist.h @@ -23,6 +23,8 @@ struct IDNode { next(nullptr) { } + MOCKABLE_VIRTUAL ~IDNode() = default; + void insertOneNext(NodeObjectType &nd) { nd.next = next; if (next != nullptr) { diff --git a/runtime/command_queue/command_queue_hw.h b/runtime/command_queue/command_queue_hw.h index 2e8e282e4d..7f146f0840 100644 --- a/runtime/command_queue/command_queue_hw.h +++ b/runtime/command_queue/command_queue_hw.h @@ -344,7 +344,7 @@ class CommandQueueHw : public CommandQueue { Surface **surfacesForResidency, size_t surfacesCount, const MultiDispatchInfo &multiDispatchInfo, - TimestampPacketContainer *previousTimestampPacketNodes, + TimestampPacketContainer &previousTimestampPacketNodes, TimestampPacketContainer &barrierTimestampPacketNode, std::unique_ptr &blockedCommandsData, const EnqueueProperties &enqueueProperties, diff --git a/runtime/command_queue/enqueue_common.h b/runtime/command_queue/enqueue_common.h index b3d5cf8284..9e092c5d8c 100644 --- a/runtime/command_queue/enqueue_common.h +++ b/runtime/command_queue/enqueue_common.h @@ -345,7 +345,7 @@ void CommandQueueHw::enqueueHandler(Surface **surfacesForResidency, surfacesForResidency, numSurfaceForResidency, multiDispatchInfo, - &previousTimestampPacketNodes, + previousTimestampPacketNodes, barrierTimestampPacketNode, blockedCommandsData, enqueueProperties, @@ -740,7 +740,7 @@ void CommandQueueHw::enqueueBlocked( Surface **surfaces, size_t surfaceCount, const MultiDispatchInfo &multiDispatchInfo, - TimestampPacketContainer *previousTimestampPacketNodes, + TimestampPacketContainer &previousTimestampPacketNodes, TimestampPacketContainer &barrierTimestampPacketNode, std::unique_ptr &blockedCommandsData, const EnqueueProperties &enqueueProperties, @@ -820,7 +820,8 @@ void CommandQueueHw::enqueueBlocked( auto event = castToObjectOrAbort(eventsRequest.eventWaitList[i]); event->incRefInternal(); } - command->setTimestampPacketNode(*timestampPacketContainer, *previousTimestampPacketNodes, barrierTimestampPacketNode); + command->setTimestampPacketNode(*timestampPacketContainer, std::move(previousTimestampPacketNodes), + std::move(barrierTimestampPacketNode)); command->setEventsRequest(eventsRequest); } outEvent->setCommand(std::move(command)); diff --git a/runtime/helpers/task_information.cpp b/runtime/helpers/task_information.cpp index 3eb70f9a6f..c8e285c463 100644 --- a/runtime/helpers/task_information.cpp +++ b/runtime/helpers/task_information.cpp @@ -341,15 +341,15 @@ void Command::setEventsRequest(EventsRequest &eventsRequest) { } } -void Command::setTimestampPacketNode(TimestampPacketContainer ¤t, TimestampPacketContainer &previous, TimestampPacketContainer &barrier) { +void Command::setTimestampPacketNode(TimestampPacketContainer ¤t, TimestampPacketContainer &&previous, TimestampPacketContainer &&barrier) { currentTimestampPacketNodes = std::make_unique(); currentTimestampPacketNodes->assignAndIncrementNodesRefCounts(current); previousTimestampPacketNodes = std::make_unique(); - previousTimestampPacketNodes->assignAndIncrementNodesRefCounts(previous); + *previousTimestampPacketNodes = std::move(previous); barrierTimestampPacketNodes = std::make_unique(); - barrierTimestampPacketNodes->assignAndIncrementNodesRefCounts(barrier); + *barrierTimestampPacketNodes = std::move(barrier); } Command::~Command() { diff --git a/runtime/helpers/task_information.h b/runtime/helpers/task_information.h index da260d5b0a..aa4ccf8436 100644 --- a/runtime/helpers/task_information.h +++ b/runtime/helpers/task_information.h @@ -94,7 +94,7 @@ class Command : public IFNode { virtual LinearStream *getCommandStream() { return nullptr; } - void setTimestampPacketNode(TimestampPacketContainer ¤t, TimestampPacketContainer &previous, TimestampPacketContainer &barrier); + void setTimestampPacketNode(TimestampPacketContainer ¤t, TimestampPacketContainer &&previous, TimestampPacketContainer &&barrier); void setEventsRequest(EventsRequest &eventsRequest); void makeTimestampPacketsResident(CommandStreamReceiver &commandStreamReceiver); diff --git a/runtime/helpers/timestamp_packet.h b/runtime/helpers/timestamp_packet.h index 3140897f2e..8c72e31e2d 100644 --- a/runtime/helpers/timestamp_packet.h +++ b/runtime/helpers/timestamp_packet.h @@ -71,10 +71,12 @@ struct TimestampPacketStorage { static_assert(((4 * TimestampPacketSizeControl::preferredPacketCount + 1) * sizeof(uint32_t)) == sizeof(TimestampPacketStorage), "This structure is consumed by GPU and has to follow specific restrictions for padding and size"); -class TimestampPacketContainer : public NonCopyableOrMovableClass { +class TimestampPacketContainer : public NonCopyableClass { public: using Node = TagNode; TimestampPacketContainer() = default; + TimestampPacketContainer(TimestampPacketContainer &&) = default; + TimestampPacketContainer &operator=(TimestampPacketContainer &&) = default; MOCKABLE_VIRTUAL ~TimestampPacketContainer(); const std::vector &peekNodes() const { return timestampPacketNodes; } diff --git a/runtime/utilities/tag_allocator.h b/runtime/utilities/tag_allocator.h index 52e7f1315e..566e384d26 100644 --- a/runtime/utilities/tag_allocator.h +++ b/runtime/utilities/tag_allocator.h @@ -32,7 +32,7 @@ struct TagNode : public IDNode> { void incRefCount() { refCount++; } - void returnTag() { + MOCKABLE_VIRTUAL void returnTag() { allocator->returnTag(this); } diff --git a/unit_tests/command_queue/enqueue_command_without_kernel_tests.cpp b/unit_tests/command_queue/enqueue_command_without_kernel_tests.cpp index 53c9d3bf5f..d1b559fd21 100644 --- a/unit_tests/command_queue/enqueue_command_without_kernel_tests.cpp +++ b/unit_tests/command_queue/enqueue_command_without_kernel_tests.cpp @@ -72,7 +72,7 @@ HWTEST_F(EnqueueHandlerTest, givenNonBlitPropertyWhenEnqueueIsBlockedThenDontReg auto blockedCommandsData = std::unique_ptr(blockedCommandsDataForDependencyFlush); Surface *surfaces[] = {nullptr}; - mockCmdQ->enqueueBlocked(CL_COMMAND_MARKER, surfaces, size_t(0), multiDispatchInfo, &previousTimestampPacketNodes, + mockCmdQ->enqueueBlocked(CL_COMMAND_MARKER, surfaces, size_t(0), multiDispatchInfo, previousTimestampPacketNodes, barrierTimestampPacketNodes, blockedCommandsData, enqueuePropertiesForDependencyFlush, eventsRequest, eventBuilder, std::unique_ptr(nullptr)); EXPECT_FALSE(blockedCommandsDataForDependencyFlush->blitEnqueue); @@ -102,7 +102,7 @@ HWTEST_F(EnqueueHandlerTest, givenBlitPropertyWhenEnqueueIsBlockedThenRegisterBl auto blockedCommandsData = std::unique_ptr(blockedCommandsDataForBlitEnqueue); Surface *surfaces[] = {nullptr}; - mockCmdQ->enqueueBlocked(CL_COMMAND_READ_BUFFER, surfaces, size_t(0), multiDispatchInfo, &previousTimestampPacketNodes, + mockCmdQ->enqueueBlocked(CL_COMMAND_READ_BUFFER, surfaces, size_t(0), multiDispatchInfo, previousTimestampPacketNodes, barrierTimestampPacketNodes, blockedCommandsData, enqueuePropertiesForBlitEnqueue, eventsRequest, eventBuilder, std::unique_ptr(nullptr)); EXPECT_TRUE(blockedCommandsDataForBlitEnqueue->blitEnqueue); diff --git a/unit_tests/helpers/timestamp_packet_tests.cpp b/unit_tests/helpers/timestamp_packet_tests.cpp index 42616853fb..196e578038 100644 --- a/unit_tests/helpers/timestamp_packet_tests.cpp +++ b/unit_tests/helpers/timestamp_packet_tests.cpp @@ -142,6 +142,42 @@ TEST_F(TimestampPacketSimpleTests, whenEndTagIsNotOneThenCanBeReleased) { EXPECT_TRUE(timestampPacketStorage.canBeReleased()); } +TEST_F(TimestampPacketSimpleTests, givenTimestampPacketContainerWhenMovedTheMoveAllNodes) { + EXPECT_TRUE(std::is_move_constructible::value); + EXPECT_TRUE(std::is_move_assignable::value); + EXPECT_FALSE(std::is_copy_assignable::value); + EXPECT_FALSE(std::is_copy_constructible::value); + + struct MockTagNode : public TagNode { + void returnTag() override { + returnCalls++; + } + using TagNode::refCount; + uint32_t returnCalls = 0; + }; + + MockTagNode node0; + MockTagNode node1; + + { + TimestampPacketContainer timestampPacketContainer0; + TimestampPacketContainer timestampPacketContainer1; + + timestampPacketContainer0.add(&node0); + timestampPacketContainer0.add(&node1); + + timestampPacketContainer1 = std::move(timestampPacketContainer0); + EXPECT_EQ(0u, node0.returnCalls); + EXPECT_EQ(0u, node1.returnCalls); + EXPECT_EQ(0u, timestampPacketContainer0.peekNodes().size()); + EXPECT_EQ(2u, timestampPacketContainer1.peekNodes().size()); + EXPECT_EQ(&node0, timestampPacketContainer1.peekNodes()[0]); + EXPECT_EQ(&node1, timestampPacketContainer1.peekNodes()[1]); + } + EXPECT_EQ(1u, node0.returnCalls); + EXPECT_EQ(1u, node1.returnCalls); +} + TEST_F(TimestampPacketSimpleTests, whenIsCompletedIsCalledThenItReturnsProperTimestampPacketStatus) { TimestampPacketStorage timestampPacketStorage; auto &packet = timestampPacketStorage.packets[0];