2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
8 #include <CommandHandlerRegistry.hpp>
21 enum class TargetEndianness
27 enum class PacketDirection
34 /// A class that implements a Mock Gatord server. It will listen on a specified Unix domain socket (UDS)
35 /// namespace for client connections. It will then allow opertaions to manage coutners while receiving counter data.
36 class GatordMockService
39 /// @param registry reference to a command handler registry.
40 /// @param echoPackets if true the raw packets will be printed to stdout.
41 GatordMockService(armnn::profiling::CommandHandlerRegistry& registry, bool echoPackets)
42 : m_HandlerRegistry(registry)
43 , m_EchoPackets(echoPackets)
45 m_PacketsReceivedCount.store(0, std::memory_order_relaxed);
50 // We have set SOCK_CLOEXEC on these sockets but we'll close them to be good citizens.
51 close(m_ClientConnection);
52 close(m_ListeningSocket);
55 /// Establish the Unix domain socket and set it to listen for connections.
56 /// @param udsNamespace the namespace (socket address) associated with the listener.
57 /// @return true only if the socket has been correctly setup.
58 bool OpenListeningSocket(std::string udsNamespace);
60 /// Block waiting to accept one client to connect to the UDS.
61 /// @return the file descriptor of the client connection.
62 int BlockForOneClient();
64 /// Once the connection is open wait to receive the stream meta data packet from the client. Reading this
65 /// packet differs from others as we need to determine endianness.
66 /// @return true only if a valid stream met data packet has been received.
67 bool WaitForStreamMetaData();
69 /// Send a connection acknowledged packet back to the client.
70 void SendConnectionAck();
72 /// Send a request counter directory packet back to the client.
73 void SendRequestCounterDir();
75 /// Start the thread that will receive all packets and print them nicely to stdout.
76 bool LaunchReceivingThread();
78 /// Return the total number of periodic counter capture packets received since the receive thread started.
79 /// @return number of periodic counter capture packets received.
80 uint32_t GetPacketsReceivedCount()
82 return m_PacketsReceivedCount.load(std::memory_order_acquire);
85 /// This is a placeholder method to prevent main exiting. It can be removed once the
86 /// command handling code is added.
87 void WaitForReceivingThread();
89 /// Send the counter list to ArmNN.
90 void SendPeriodicCounterSelectionList(uint32_t period, std::vector<uint16_t> counters);
92 /// Execute the WAIT command from the comamnd file.
93 void WaitCommand(uint32_t timeout);
95 uint32_t GetStreamMetadataVersion()
97 return m_StreamMetaDataVersion;
100 uint32_t GetStreamMetadataMaxDataLen()
102 return m_StreamMetaDataMaxDataLen;
105 uint32_t GetStreamMetadataPid()
107 return m_StreamMetaDataPid;
111 void ReceiveLoop(GatordMockService& mockService);
113 /// Block on the client connection until a complete packet has been received. This is a placeholder function to
114 /// enable early testing of the tool.
115 /// @return true if a valid packet has been received.
116 armnn::profiling::Packet WaitForPacket(uint32_t timeoutMs);
118 armnn::profiling::Packet ReceivePacket();
120 bool SendPacket(uint32_t packetFamily, uint32_t packetId, const uint8_t* data, uint32_t dataLength);
122 void EchoPacket(PacketDirection direction, uint8_t* packet, size_t lengthInBytes);
124 bool ReadHeader(uint32_t headerAsWords[2]);
126 bool ReadFromSocket(uint8_t* packetData, uint32_t expectedLength);
128 uint32_t ToUint32(uint8_t* data, TargetEndianness endianness);
130 void InsertU32(uint32_t value, uint8_t* data, TargetEndianness endianness);
132 static const uint32_t PIPE_MAGIC = 0x45495434;
134 std::atomic<uint32_t> m_PacketsReceivedCount;
135 TargetEndianness m_Endianness;
136 uint32_t m_StreamMetaDataVersion;
137 uint32_t m_StreamMetaDataMaxDataLen;
138 uint32_t m_StreamMetaDataPid;
140 armnn::profiling::CommandHandlerRegistry& m_HandlerRegistry;
143 int m_ListeningSocket;
144 int m_ClientConnection;
145 std::thread m_ListeningThread;
146 std::atomic<bool> m_CloseReceivingThread;
148 } // namespace gatordmock