blob: 2ff93c9de6df16c5ab135f33735ad8418fde6667 [file] [log] [blame]
Colm Donelana21620d2019-10-11 13:09:49 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Matteo Martincigh65984272019-10-17 13:26:21 +01008#include <CommandHandlerRegistry.hpp>
9#include <Packet.hpp>
Rob Hughes25b74362020-01-13 11:14:59 +000010#include <NetworkSockets.hpp>
Matteo Martincigh65984272019-10-17 13:26:21 +010011
Colm Donelanb682d842019-10-16 12:24:20 +010012#include <atomic>
Colm Donelana21620d2019-10-11 13:09:49 +010013#include <string>
14#include <thread>
Colm Donelana21620d2019-10-11 13:09:49 +010015
Keith Davis33ed2212020-03-30 10:43:41 +010016#include <TimelineDecoder.hpp>
17#include <DirectoryCaptureCommandHandler.hpp>
18#include <TimelineCaptureCommandHandler.hpp>
19#include <TimelineDirectoryCaptureCommandHandler.hpp>
20#include "PeriodicCounterCaptureCommandHandler.hpp"
21#include "StreamMetadataCommandHandler.hpp"
22
23#include "PacketVersionResolver.hpp"
24
Colm Donelana21620d2019-10-11 13:09:49 +010025namespace armnn
26{
27
28namespace gatordmock
29{
30
31enum class TargetEndianness
32{
Colm Donelanb682d842019-10-16 12:24:20 +010033 BeWire,
34 LeWire
Colm Donelana21620d2019-10-11 13:09:49 +010035};
36
37enum class PacketDirection
38{
Colm Donelanb682d842019-10-16 12:24:20 +010039 Sending,
40 ReceivedHeader,
41 ReceivedData
Colm Donelana21620d2019-10-11 13:09:49 +010042};
43
44/// A class that implements a Mock Gatord server. It will listen on a specified Unix domain socket (UDS)
45/// namespace for client connections. It will then allow opertaions to manage coutners while receiving counter data.
46class GatordMockService
47{
48public:
Colm Donelana21620d2019-10-11 13:09:49 +010049 /// @param registry reference to a command handler registry.
50 /// @param echoPackets if true the raw packets will be printed to stdout.
Keith Davis33ed2212020-03-30 10:43:41 +010051 GatordMockService(armnnUtils::Sockets::Socket clientConnection, bool echoPackets)
Finn Williamse6a2ccd2020-02-27 16:21:41 +000052 : m_ClientConnection(clientConnection)
Keith Davis33ed2212020-03-30 10:43:41 +010053 , m_PacketsReceivedCount(0)
Finn Williamse6a2ccd2020-02-27 16:21:41 +000054 , m_EchoPackets(echoPackets)
55 , m_CloseReceivingThread(false)
Keith Davis33ed2212020-03-30 10:43:41 +010056 , m_PacketVersionResolver()
57 , m_HandlerRegistry()
58 , m_TimelineDecoder()
59 , m_StreamMetadataCommandHandler(
60 0, 0, m_PacketVersionResolver.ResolvePacketVersion(0, 0).GetEncodedValue(), true)
61 , m_CounterCaptureCommandHandler(
62 0, 4, m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(), true)
63 , m_DirectoryCaptureCommandHandler(
64 0, 2, m_PacketVersionResolver.ResolvePacketVersion(0, 2).GetEncodedValue(), true)
65 , m_TimelineCaptureCommandHandler(
66 1, 1, m_PacketVersionResolver.ResolvePacketVersion(1, 1).GetEncodedValue(), m_TimelineDecoder)
67 , m_TimelineDirectoryCaptureCommandHandler(
68 1, 0, m_PacketVersionResolver.ResolvePacketVersion(1, 0).GetEncodedValue(),
69 m_TimelineCaptureCommandHandler, true)
Colm Donelana21620d2019-10-11 13:09:49 +010070 {
Keith Davis33ed2212020-03-30 10:43:41 +010071 m_TimelineDecoder.SetDefaultCallbacks();
72
73 m_HandlerRegistry.RegisterFunctor(&m_StreamMetadataCommandHandler);
74 m_HandlerRegistry.RegisterFunctor(&m_CounterCaptureCommandHandler);
75 m_HandlerRegistry.RegisterFunctor(&m_DirectoryCaptureCommandHandler);
76 m_HandlerRegistry.RegisterFunctor(&m_TimelineDirectoryCaptureCommandHandler);
77 m_HandlerRegistry.RegisterFunctor(&m_TimelineCaptureCommandHandler);
Colm Donelana21620d2019-10-11 13:09:49 +010078 }
79
80 ~GatordMockService()
81 {
82 // We have set SOCK_CLOEXEC on these sockets but we'll close them to be good citizens.
Rob Hughes25b74362020-01-13 11:14:59 +000083 armnnUtils::Sockets::Close(m_ClientConnection);
Colm Donelana21620d2019-10-11 13:09:49 +010084 }
85
86 /// Establish the Unix domain socket and set it to listen for connections.
87 /// @param udsNamespace the namespace (socket address) associated with the listener.
88 /// @return true only if the socket has been correctly setup.
Finn Williamse6a2ccd2020-02-27 16:21:41 +000089 static bool OpenListeningSocket(armnnUtils::Sockets::Socket listeningSocket,
90 const std::string udsNamespace,
91 const int numOfConnections = 1);
Colm Donelana21620d2019-10-11 13:09:49 +010092
93 /// Once the connection is open wait to receive the stream meta data packet from the client. Reading this
94 /// packet differs from others as we need to determine endianness.
95 /// @return true only if a valid stream met data packet has been received.
96 bool WaitForStreamMetaData();
97
98 /// Send a connection acknowledged packet back to the client.
99 void SendConnectionAck();
100
Finn Williams15db7452019-10-15 14:22:13 +0100101 /// Send a request counter directory packet back to the client.
102 void SendRequestCounterDir();
103
Keith Davis33ed2212020-03-30 10:43:41 +0100104 /// Send a activate timeline packet back to the client.
105 void SendActivateTimelinePacket();
106
107 /// Send a deactivate timeline packet back to the client.
108 void SendDeactivateTimelinePacket();
109
Colm Donelana21620d2019-10-11 13:09:49 +0100110 /// Start the thread that will receive all packets and print them nicely to stdout.
111 bool LaunchReceivingThread();
112
113 /// Return the total number of periodic counter capture packets received since the receive thread started.
114 /// @return number of periodic counter capture packets received.
115 uint32_t GetPacketsReceivedCount()
116 {
117 return m_PacketsReceivedCount.load(std::memory_order_acquire);
118 }
119
120 /// This is a placeholder method to prevent main exiting. It can be removed once the
121 /// command handling code is added.
122 void WaitForReceivingThread();
123
Colm Donelan02705242019-11-14 14:19:07 +0000124 // @return true only if the receive thread is closed or closing.
125 bool ReceiveThreadRunning()
126 {
127 return !m_CloseReceivingThread.load();
128 }
129
Colm Donelana21620d2019-10-11 13:09:49 +0100130 /// Send the counter list to ArmNN.
Colm Donelanb682d842019-10-16 12:24:20 +0100131 void SendPeriodicCounterSelectionList(uint32_t period, std::vector<uint16_t> counters);
Colm Donelana21620d2019-10-11 13:09:49 +0100132
133 /// Execute the WAIT command from the comamnd file.
Rob Hughes270233f2019-11-13 11:53:48 +0000134 void WaitCommand(uint32_t timeout);
Colm Donelana21620d2019-10-11 13:09:49 +0100135
136 uint32_t GetStreamMetadataVersion()
137 {
138 return m_StreamMetaDataVersion;
139 }
140
141 uint32_t GetStreamMetadataMaxDataLen()
142 {
143 return m_StreamMetaDataMaxDataLen;
144 }
145
146 uint32_t GetStreamMetadataPid()
147 {
148 return m_StreamMetaDataPid;
149 }
150
Keith Davis33ed2212020-03-30 10:43:41 +0100151 profiling::DirectoryCaptureCommandHandler& GetDirectoryCaptureCommandHandler()
152 {
153 return m_DirectoryCaptureCommandHandler;
154 }
155
156 timelinedecoder::TimelineDecoder& GetTimelineDecoder()
157 {
158 return m_TimelineDecoder;
159 }
160
161 timelinedecoder::TimelineDirectoryCaptureCommandHandler& GetTimelineDirectoryCaptureCommandHandler()
162 {
163 return m_TimelineDirectoryCaptureCommandHandler;
164 }
165
166
Colm Donelana21620d2019-10-11 13:09:49 +0100167private:
Colm Donelana21620d2019-10-11 13:09:49 +0100168 void ReceiveLoop(GatordMockService& mockService);
169
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000170 int MainLoop(armnn::profiling::CommandHandlerRegistry& registry, armnnUtils::Sockets::Socket m_ClientConnection);
171
Colm Donelana21620d2019-10-11 13:09:49 +0100172 /// Block on the client connection until a complete packet has been received. This is a placeholder function to
173 /// enable early testing of the tool.
174 /// @return true if a valid packet has been received.
175 armnn::profiling::Packet WaitForPacket(uint32_t timeoutMs);
176
177 armnn::profiling::Packet ReceivePacket();
178
Rob Hughes270233f2019-11-13 11:53:48 +0000179 bool SendPacket(uint32_t packetFamily, uint32_t packetId, const uint8_t* data, uint32_t dataLength);
Colm Donelana21620d2019-10-11 13:09:49 +0100180
Rob Hughes270233f2019-11-13 11:53:48 +0000181 void EchoPacket(PacketDirection direction, uint8_t* packet, size_t lengthInBytes);
Colm Donelana21620d2019-10-11 13:09:49 +0100182
183 bool ReadHeader(uint32_t headerAsWords[2]);
184
Rob Hughes270233f2019-11-13 11:53:48 +0000185 bool ReadFromSocket(uint8_t* packetData, uint32_t expectedLength);
Colm Donelana21620d2019-10-11 13:09:49 +0100186
Rob Hughes270233f2019-11-13 11:53:48 +0000187 uint32_t ToUint32(uint8_t* data, TargetEndianness endianness);
Colm Donelana21620d2019-10-11 13:09:49 +0100188
Rob Hughes270233f2019-11-13 11:53:48 +0000189 void InsertU32(uint32_t value, uint8_t* data, TargetEndianness endianness);
Colm Donelana21620d2019-10-11 13:09:49 +0100190
191 static const uint32_t PIPE_MAGIC = 0x45495434;
192
Colm Donelanb682d842019-10-16 12:24:20 +0100193 TargetEndianness m_Endianness;
194 uint32_t m_StreamMetaDataVersion;
195 uint32_t m_StreamMetaDataMaxDataLen;
196 uint32_t m_StreamMetaDataPid;
Colm Donelana21620d2019-10-11 13:09:49 +0100197
Finn Williamse6a2ccd2020-02-27 16:21:41 +0000198 armnnUtils::Sockets::Socket m_ClientConnection;
Keith Davis33ed2212020-03-30 10:43:41 +0100199 std::atomic<uint32_t> m_PacketsReceivedCount;
Colm Donelana21620d2019-10-11 13:09:49 +0100200
201 bool m_EchoPackets;
Colm Donelana21620d2019-10-11 13:09:49 +0100202 std::thread m_ListeningThread;
203 std::atomic<bool> m_CloseReceivingThread;
Keith Davis33ed2212020-03-30 10:43:41 +0100204
205 profiling::PacketVersionResolver m_PacketVersionResolver;
206 profiling::CommandHandlerRegistry m_HandlerRegistry;
207
208 timelinedecoder::TimelineDecoder m_TimelineDecoder;
209
210 gatordmock::StreamMetadataCommandHandler m_StreamMetadataCommandHandler;
211 gatordmock::PeriodicCounterCaptureCommandHandler m_CounterCaptureCommandHandler;
212
213 profiling::DirectoryCaptureCommandHandler m_DirectoryCaptureCommandHandler;
214
215 timelinedecoder::TimelineCaptureCommandHandler m_TimelineCaptureCommandHandler;
216 timelinedecoder::TimelineDirectoryCaptureCommandHandler m_TimelineDirectoryCaptureCommandHandler;
Colm Donelana21620d2019-10-11 13:09:49 +0100217};
Colm Donelanb682d842019-10-16 12:24:20 +0100218} // namespace gatordmock
Colm Donelana21620d2019-10-11 13:09:49 +0100219
Colm Donelanb682d842019-10-16 12:24:20 +0100220} // namespace armnn