From 53e469915bc6552c0d79cb6461512c7c1168ee2d Mon Sep 17 00:00:00 2001 From: Jim Flynn Date: Mon, 14 Oct 2019 12:31:10 +0100 Subject: IVGCVSW-3972 Implement the Disconnect functionality * Added Disconnect method to the ProfilingService class * Added unit test Signed-off-by: Matteo Martincigh Signed-off-by: Jim Flynn Change-Id: I5cc57abd3e1239cdf8afe21ee4883c1f73cd0e80 --- src/profiling/ProfilingService.cpp | 43 ++++++++++++++++++---- src/profiling/ProfilingService.hpp | 4 +++ src/profiling/ProfilingStateMachine.cpp | 2 +- src/profiling/test/ProfilingTests.cpp | 64 +++++++++++++++++++++++++++++++-- 4 files changed, 103 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp index 79184416cd..b481695d49 100644 --- a/src/profiling/ProfilingService.cpp +++ b/src/profiling/ProfilingService.cpp @@ -103,6 +103,26 @@ void ProfilingService::Update() } } +void ProfilingService::Disconnect() +{ + ProfilingState currentState = m_StateMachine.GetCurrentState(); + switch (currentState) + { + case ProfilingState::Uninitialised: + case ProfilingState::NotConnected: + case ProfilingState::WaitingForAck: + return; // NOP + case ProfilingState::Active: + // Stop the command thread (if running) + Stop(); + + break; + default: + throw RuntimeException(boost::str(boost::format("Unknown profiling service state: %1") + % static_cast(currentState))); + } +} + const ICounterDirectory& ProfilingService::GetCounterDirectory() const { return m_CounterDirectory; @@ -244,7 +264,18 @@ void ProfilingService::InitializeCounterValue(uint16_t counterUid) void ProfilingService::Reset() { // Reset the profiling service + Stop(); + // ...then delete all the counter data and configuration... + m_CounterIndex.clear(); + m_CounterValues.clear(); + m_CounterDirectory.Clear(); + // ...finally reset the profiling state machine + m_StateMachine.Reset(); +} + +void ProfilingService::Stop() +{ // The order in which we reset/stop the components is not trivial! // First stop the threads (Command Handler first)... @@ -253,15 +284,13 @@ void ProfilingService::Reset() m_PeriodicCounterCapture.Stop(); // ...then destroy the profiling connection... + if (m_ProfilingConnection != nullptr && m_ProfilingConnection->IsOpen()) + { + m_ProfilingConnection->Close(); + } m_ProfilingConnection.reset(); - // ...then delete all the counter data and configuration... - m_CounterIndex.clear(); - m_CounterValues.clear(); - m_CounterDirectory.Clear(); - - // ...finally reset the profiling state machine - m_StateMachine.Reset(); + m_StateMachine.TransitionToState(ProfilingState::NotConnected); } inline void ProfilingService::CheckCounterUid(uint16_t counterUid) const diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp index dd70af4b39..d4fa85604c 100644 --- a/src/profiling/ProfilingService.hpp +++ b/src/profiling/ProfilingService.hpp @@ -45,6 +45,9 @@ public: // Updates the profiling service, making it transition to a new state if necessary void Update(); + // Disconnects the profiling service from the external server + void Disconnect(); + // Getters for the profiling service state const ICounterDirectory& GetCounterDirectory() const; ProfilingState GetCurrentState() const; @@ -70,6 +73,7 @@ private: void Initialize(); void InitializeCounterValue(uint16_t counterUid); void Reset(); + void Stop(); // Helper function void CheckCounterUid(uint16_t counterUid) const; diff --git a/src/profiling/ProfilingStateMachine.cpp b/src/profiling/ProfilingStateMachine.cpp index 9d3a81f64a..58fac969ab 100644 --- a/src/profiling/ProfilingStateMachine.cpp +++ b/src/profiling/ProfilingStateMachine.cpp @@ -53,7 +53,7 @@ void ProfilingStateMachine::TransitionToState(ProfilingState newState) do { if (!IsOneOfStates(currentState, ProfilingState::Uninitialised, ProfilingState::NotConnected, - ProfilingState::Active)) + ProfilingState::Active, ProfilingState::WaitingForAck)) { ThrowStateTransitionException(currentState, newState); } diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp index 554b7e1936..446c6096ed 100644 --- a/src/profiling/test/ProfilingTests.cpp +++ b/src/profiling/test/ProfilingTests.cpp @@ -424,8 +424,8 @@ BOOST_AUTO_TEST_CASE(CheckProfilingStateMachine) armnn::Exception); ProfilingStateMachine profilingState14(ProfilingState::WaitingForAck); - BOOST_CHECK_THROW(profilingState14.TransitionToState(ProfilingState::NotConnected), - armnn::Exception); + profilingState14.TransitionToState(ProfilingState::NotConnected); + BOOST_CHECK(profilingState14.GetCurrentState() == ProfilingState::NotConnected); ProfilingStateMachine profilingState15(ProfilingState::Active); BOOST_CHECK_THROW(profilingState15.TransitionToState(ProfilingState::Uninitialised), @@ -2281,6 +2281,7 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadConnectionAcknowledgedPacket) unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast(processName.size()) + 1; unsigned int streamMetadataPacketsize = 118 + processNameSize; + // Reset the profiling service to the uninitialized state armnn::Runtime::CreationOptions::ExternalProfilingOptions options; options.m_EnableProfiling = true; ProfilingService& profilingService = ProfilingService::Instance(); @@ -2354,6 +2355,7 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodConnectionAcknowledgedPacket) unsigned int processNameSize = processName.empty() ? 0 : boost::numeric_cast(processName.size()) + 1; unsigned int streamMetadataPacketsize = 118 + processNameSize; + // Reset the profiling service to the uninitialized state armnn::Runtime::CreationOptions::ExternalProfilingOptions options; options.m_EnableProfiling = true; ProfilingService& profilingService = ProfilingService::Instance(); @@ -3012,4 +3014,62 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceGoodPeriodicCounterSelectionPacketMult profilingService.ResetExternalProfilingOptions(options, true); } +BOOST_AUTO_TEST_CASE(CheckProfilingServiceDisconnect) +{ + // Swap the profiling connection factory in the profiling service instance with our mock one + SwapProfilingConnectionFactoryHelper helper; + + // Reset the profiling service to the uninitialized state + armnn::Runtime::CreationOptions::ExternalProfilingOptions options; + options.m_EnableProfiling = true; + ProfilingService& profilingService = ProfilingService::Instance(); + profilingService.ResetExternalProfilingOptions(options, true); + + // Try to disconnect the profiling service while in the "Uninitialised" state + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); + profilingService.Disconnect(); + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Uninitialised); // The state should not change + + // Try to disconnect the profiling service while in the "NotConnected" state + profilingService.Update(); // Initialize the counter directory + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); + profilingService.Disconnect(); + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should not change + + // Try to disconnect the profiling service while in the "WaitingForAck" state + profilingService.Update(); // Create the profiling connection + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); + profilingService.Disconnect(); + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::WaitingForAck); // The state should not change + + // Try to disconnect the profiling service while in the "Active" state + profilingService.Update(); // Start the command handler and the send thread + + // Wait for the Stream Metadata packet the be sent + // (we are not testing the connection acknowledgement here so it will be ignored by this test) + helper.WaitForProfilingPacketsSent(); + + // Force the profiling service to the "Active" state + helper.ForceTransitionToState(ProfilingState::Active); + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::Active); + + // Get the mock profiling connection + MockProfilingConnection* mockProfilingConnection = helper.GetMockProfilingConnection(); + BOOST_CHECK(mockProfilingConnection); + + // Check that the profiling connection is open + BOOST_CHECK(mockProfilingConnection->IsOpen()); + + profilingService.Disconnect(); + BOOST_CHECK(profilingService.GetCurrentState() == ProfilingState::NotConnected); // The state should have changed + + // Check that the profiling connection has been reset + mockProfilingConnection = helper.GetMockProfilingConnection(); + BOOST_CHECK(mockProfilingConnection == nullptr); + + // Reset the profiling service to stop any running thread + options.m_EnableProfiling = false; + profilingService.ResetExternalProfilingOptions(options, true); +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.1