blob: db09856dae2e2a715f070639dec1ab2de9cbd963 [file] [log] [blame]
Ferran Balaguer1b941722019-08-28 16:57:18 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "PeriodicCounterSelectionCommandHandler.hpp"
7#include "ProfilingUtils.hpp"
8
9#include <boost/numeric/conversion/cast.hpp>
Matteo Martincighe8485382019-10-10 14:08:21 +010010#include <boost/format.hpp>
11
12#include <vector>
Ferran Balaguer1b941722019-08-28 16:57:18 +010013
14namespace armnn
15{
16
17namespace profiling
18{
19
Ferran Balaguer1b941722019-08-28 16:57:18 +010020void PeriodicCounterSelectionCommandHandler::ParseData(const Packet& packet, CaptureData& captureData)
21{
22 std::vector<uint16_t> counterIds;
Matteo Martincighe8485382019-10-10 14:08:21 +010023 uint32_t sizeOfUint32 = boost::numeric_cast<uint32_t>(sizeof(uint32_t));
24 uint32_t sizeOfUint16 = boost::numeric_cast<uint32_t>(sizeof(uint16_t));
Ferran Balaguer1b941722019-08-28 16:57:18 +010025 uint32_t offset = 0;
26
Matteo Martincighe8485382019-10-10 14:08:21 +010027 if (packet.GetLength() < 4)
Ferran Balaguer1b941722019-08-28 16:57:18 +010028 {
Matteo Martincighe8485382019-10-10 14:08:21 +010029 // Insufficient packet size
30 return;
31 }
32
33 // Parse the capture period
34 uint32_t capturePeriod = ReadUint32(packet.GetData(), offset);
35
36 // Set the capture period
37 captureData.SetCapturePeriod(capturePeriod);
38
39 // Parse the counter ids
40 unsigned int counters = (packet.GetLength() - 4) / 2;
41 if (counters > 0)
42 {
43 counterIds.reserve(counters);
44 offset += sizeOfUint32;
45 for (unsigned int i = 0; i < counters; ++i)
Ferran Balaguer1b941722019-08-28 16:57:18 +010046 {
Matteo Martincighe8485382019-10-10 14:08:21 +010047 // Parse the counter id
48 uint16_t counterId = ReadUint16(packet.GetData(), offset);
49 counterIds.emplace_back(counterId);
50 offset += sizeOfUint16;
Ferran Balaguer1b941722019-08-28 16:57:18 +010051 }
52 }
Matteo Martincighe8485382019-10-10 14:08:21 +010053
54 // Set the counter ids
55 captureData.SetCounterIds(counterIds);
Ferran Balaguer1b941722019-08-28 16:57:18 +010056}
57
58void PeriodicCounterSelectionCommandHandler::operator()(const Packet& packet)
59{
Matteo Martincighe8485382019-10-10 14:08:21 +010060 ProfilingState currentState = m_StateMachine.GetCurrentState();
61 switch (currentState)
62 {
63 case ProfilingState::Uninitialised:
64 case ProfilingState::NotConnected:
65 case ProfilingState::WaitingForAck:
66 throw RuntimeException(boost::str(boost::format("Periodic Counter Selection Command Handler invoked while in "
67 "an wrong state: %1%")
68 % GetProfilingStateName(currentState)));
69 case ProfilingState::Active:
70 {
71 // Process the packet
72 if (!(packet.GetPacketFamily() == 0u && packet.GetPacketId() == 4u))
73 {
74 throw armnn::InvalidArgumentException(boost::str(boost::format("Expected Packet family = 0, id = 4 but "
75 "received family = %1%, id = %2%")
76 % packet.GetPacketFamily()
77 % packet.GetPacketId()));
78 }
Ferran Balaguer1b941722019-08-28 16:57:18 +010079
Matteo Martincighe8485382019-10-10 14:08:21 +010080 // Parse the packet to get the capture period and counter UIDs
81 CaptureData captureData;
82 ParseData(packet, captureData);
Ferran Balaguer1b941722019-08-28 16:57:18 +010083
Matteo Martincighe8485382019-10-10 14:08:21 +010084 // Get the capture data
85 const uint32_t capturePeriod = captureData.GetCapturePeriod();
86 const std::vector<uint16_t>& counterIds = captureData.GetCounterIds();
Ferran Balaguer1b941722019-08-28 16:57:18 +010087
Matteo Martincighe8485382019-10-10 14:08:21 +010088 // Check whether the selected counter UIDs are valid
89 std::vector<uint16_t> validCounterIds;
90 for (uint16_t counterId : counterIds)
91 {
92 // Check whether the counter is registered
93 if (!m_ReadCounterValues.IsCounterRegistered(counterId))
94 {
95 // Invalid counter UID, ignore it and continue
96 continue;
97 }
Ferran Balaguer1b941722019-08-28 16:57:18 +010098
Matteo Martincighe8485382019-10-10 14:08:21 +010099 // The counter is valid
100 validCounterIds.push_back(counterId);
101 }
Ferran Balaguer1b941722019-08-28 16:57:18 +0100102
Matteo Martincighe8485382019-10-10 14:08:21 +0100103 // Set the capture data with only the valid counter UIDs
104 m_CaptureDataHolder.SetCaptureData(capturePeriod, validCounterIds);
105
106 // Echo back the Periodic Counter Selection packet to the Counter Stream Buffer
107 m_SendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, validCounterIds);
108
109 // Notify the Send Thread that new data is available in the Counter Stream Buffer
110 m_SendCounterPacket.SetReadyToRead();
111
112 // Start the Period Counter Capture thread (if not running already)
113 m_PeriodicCounterCapture.Start();
114
115 break;
116 }
117 default:
118 throw RuntimeException(boost::str(boost::format("Unknown profiling service state: %1%")
119 % static_cast<int>(currentState)));
120 }
Ferran Balaguer1b941722019-08-28 16:57:18 +0100121}
122
123} // namespace profiling
124
Matteo Martincighe8485382019-10-10 14:08:21 +0100125} // namespace armnn