blob: 6ba49c227da82cea83575ab8abfdc0a20451f986 [file] [log] [blame]
FinnWilliamsArm4833cea2019-09-17 16:53:53 +01001//
Jim Flynnbbfe6032020-07-20 16:57:44 +01002// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
FinnWilliamsArm4833cea2019-09-17 16:53:53 +01003// SPDX-License-Identifier: MIT
4//
5
Matteo Martincigh8a837172019-10-04 17:01:07 +01006#include "CommandHandler.hpp"
Colm Donelan9ea77002019-10-17 14:02:44 +01007#include "ProfilingService.hpp"
FinnWilliamsArm4833cea2019-09-17 16:53:53 +01008
Jim Flynn6c9f17d2022-03-10 23:13:01 +00009#include <common/include/Logging.hpp>
Matteo Martincighd0613b52019-10-09 16:47:04 +010010
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000011namespace arm
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010012{
13
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000014namespace pipe
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010015{
16
Matteo Martincigh8a837172019-10-04 17:01:07 +010017void CommandHandler::Start(IProfilingConnection& profilingConnection)
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010018{
Matteo Martincigh88813932019-10-04 14:40:04 +010019 if (IsRunning())
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010020 {
Matteo Martincigh88813932019-10-04 14:40:04 +010021 return;
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010022 }
Matteo Martincigh88813932019-10-04 14:40:04 +010023
Colm Donelan9ea77002019-10-17 14:02:44 +010024 if (m_CommandThread.joinable())
25 {
26 m_CommandThread.join();
27 }
28
Matteo Martincighc2728f92019-10-07 12:35:21 +010029 m_IsRunning.store(true);
30 m_KeepRunning.store(true);
Matteo Martincigh8a837172019-10-04 17:01:07 +010031 m_CommandThread = std::thread(&CommandHandler::HandleCommands, this, std::ref(profilingConnection));
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010032}
33
Matteo Martincigh8a837172019-10-04 17:01:07 +010034void CommandHandler::Stop()
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010035{
Matteo Martincighc2728f92019-10-07 12:35:21 +010036 m_KeepRunning.store(false);
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010037
Matteo Martincigh88813932019-10-04 14:40:04 +010038 if (m_CommandThread.joinable())
39 {
40 m_CommandThread.join();
41 }
FinnWilliamsArm4833cea2019-09-17 16:53:53 +010042}
43
Matteo Martincigh8a837172019-10-04 17:01:07 +010044void CommandHandler::HandleCommands(IProfilingConnection& profilingConnection)
Matteo Martincigh88813932019-10-04 14:40:04 +010045{
46 do
47 {
48 try
49 {
Jim Flynnbbfe6032020-07-20 16:57:44 +010050 arm::pipe::Packet packet = profilingConnection.ReadPacket(m_Timeout.load());
Matteo Martincighd0613b52019-10-09 16:47:04 +010051
52 if (packet.IsEmpty())
53 {
54 // Nothing to do, continue
55 continue;
56 }
57
Jim Flynnbbfe6032020-07-20 16:57:44 +010058 arm::pipe::Version version = m_PacketVersionResolver.ResolvePacketVersion(packet.GetPacketFamily(),
59 packet.GetPacketId());
Matteo Martincigh88813932019-10-04 14:40:04 +010060
Jim Flynnbbfe6032020-07-20 16:57:44 +010061 arm::pipe::CommandHandlerFunctor* commandHandlerFunctor =
62 m_CommandHandlerRegistry.GetFunctor(packet.GetPacketFamily(),
63 packet.GetPacketId(),
Jim Flynn397043f2019-10-17 17:37:10 +010064 version.GetEncodedValue());
Jim Flynn6730fe92022-03-10 22:57:47 +000065 ARM_PIPE_ASSERT(commandHandlerFunctor);
Matteo Martincigh88813932019-10-04 14:40:04 +010066 commandHandlerFunctor->operator()(packet);
67 }
Jim Flynnf9db3ef2022-03-08 21:23:44 +000068 catch (const arm::pipe::TimeoutException&)
Matteo Martincigh88813932019-10-04 14:40:04 +010069 {
Matteo Martincighd0613b52019-10-09 16:47:04 +010070 if (m_StopAfterTimeout.load())
Matteo Martincigh88813932019-10-04 14:40:04 +010071 {
Matteo Martincighd0613b52019-10-09 16:47:04 +010072 m_KeepRunning.store(false);
Matteo Martincigh88813932019-10-04 14:40:04 +010073 }
74 }
Jim Flynnbbfe6032020-07-20 16:57:44 +010075 catch (const arm::pipe::ProfilingException& e)
76 {
77 // Log the error and continue
Jim Flynn6c9f17d2022-03-10 23:13:01 +000078 ARM_PIPE_LOG(warning) << "An error has occurred when handling a command: " << e.what();
Jim Flynnbbfe6032020-07-20 16:57:44 +010079 // Did we get here because the socket failed?
80 if ( !profilingConnection.IsOpen() )
81 {
82 // We're going to stop processing commands.
83 // This will leave the thread idle. There is no mechanism to restart the profiling service when the
84 // connection is lost.
85 m_KeepRunning.store(false);
86 }
87 }
Jim Flynnf9db3ef2022-03-08 21:23:44 +000088 catch (...)
Matteo Martincigh88813932019-10-04 14:40:04 +010089 {
Matteo Martincighd0613b52019-10-09 16:47:04 +010090 // Log the error and continue
Jim Flynn6c9f17d2022-03-10 23:13:01 +000091 ARM_PIPE_LOG(warning) << "An unknown error has occurred when handling a command";
Colm Donelan9ea77002019-10-17 14:02:44 +010092 // Did we get here because the socket failed?
93 if ( !profilingConnection.IsOpen() )
94 {
95 // We're going to stop processing commands.
96 // This will leave the thread idle. There is no mechanism to restart the profiling service when the
97 // connection is lost.
98 m_KeepRunning.store(false);
99 }
Matteo Martincigh88813932019-10-04 14:40:04 +0100100 }
Matteo Martincigh88813932019-10-04 14:40:04 +0100101 }
Matteo Martincighc2728f92019-10-07 12:35:21 +0100102 while (m_KeepRunning.load());
Matteo Martincigh88813932019-10-04 14:40:04 +0100103
Matteo Martincighc2728f92019-10-07 12:35:21 +0100104 m_IsRunning.store(false);
Matteo Martincigh88813932019-10-04 14:40:04 +0100105}
106
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000107} // namespace pipe
Matteo Martincigh88813932019-10-04 14:40:04 +0100108
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000109} // namespace arm