ArmNN
 20.05
GatordMockService.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "GatordMockService.hpp"
7 
10 #include <ProfilingUtils.hpp>
11 #include <NetworkSockets.hpp>
12 
13 #include <armnn/utility/Assert.hpp>
14 
15 #include <cerrno>
16 #include <iomanip>
17 #include <iostream>
18 #include <string>
19 
20 using namespace armnnUtils;
21 
22 namespace armnn
23 {
24 
25 namespace gatordmock
26 {
27 
29 {
30  if (m_EchoPackets)
31  {
32  std::cout << "Sending connection acknowledgement." << std::endl;
33  }
34  // The connection ack packet is an empty data packet with packetId == 1.
35  m_BasePipeServer.get()->SendPacket(0, 1, nullptr, 0);
36 }
37 
39 {
40  if (m_EchoPackets)
41  {
42  std::cout << "Sending connection acknowledgement." << std::endl;
43  }
44  // The request counter directory packet is an empty data packet with packetId == 3.
45  m_BasePipeServer.get()->SendPacket(0, 3, nullptr, 0);
46 }
47 
49 {
50  if (m_EchoPackets)
51  {
52  std::cout << "Sending activate timeline packet." << std::endl;
53  }
54  // The activate timeline packet is an empty data packet with packetId == 6.
55  m_BasePipeServer.get()->SendPacket(0, 6, nullptr, 0);
56 }
57 
59 {
60  if (m_EchoPackets)
61  {
62  std::cout << "Sending deactivate timeline packet." << std::endl;
63  }
64  // The deactivate timeline packet is an empty data packet with packetId == 7.
65  m_BasePipeServer.get()->SendPacket(0, 7, nullptr, 0);
66 }
67 
69 {
70  if (m_EchoPackets)
71  {
72  std::cout << "Launching receiving thread." << std::endl;
73  }
74  // At this point we want to make the socket non blocking.
75  if (!m_BasePipeServer.get()->SetNonBlocking())
76  {
77  m_BasePipeServer.get()->Close();
78  std::cerr << "Failed to set socket as non blocking: " << strerror(errno) << std::endl;
79  return false;
80  }
81  m_ListeningThread = std::thread(&GatordMockService::ReceiveLoop, this);
82  return true;
83 }
84 
86 {
87  // The receiving thread may already have died.
88  if (m_CloseReceivingThread != true)
89  {
90  m_CloseReceivingThread.store(true);
91  }
92  // Check that the receiving thread is running
93  if (m_ListeningThread.joinable())
94  {
95  // Wait for the receiving thread to complete operations
96  m_ListeningThread.join();
97  }
98 
99  if(m_EchoPackets)
100  {
101  m_TimelineDecoder.print();
102  }
103 }
104 
106 {
107  return m_BasePipeServer->WaitForStreamMetaData();
108 }
109 
110 void GatordMockService::SendPeriodicCounterSelectionList(uint32_t period, std::vector<uint16_t> counters)
111 {
112  // The packet body consists of a UINT32 representing the period following by zero or more
113  // UINT16's representing counter UID's. If the list is empty it implies all counters are to
114  // be disabled.
115 
116  if (m_EchoPackets)
117  {
118  std::cout << "SendPeriodicCounterSelectionList: Period=" << std::dec << period << "uSec" << std::endl;
119  std::cout << "List length=" << counters.size() << std::endl;
120  }
121  // Start by calculating the length of the packet body in bytes. This will be at least 4.
122  uint32_t dataLength = static_cast<uint32_t>(4 + (counters.size() * 2));
123 
124  std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength);
125  unsigned char* data = reinterpret_cast<unsigned char*>(uniqueData.get());
126 
127  uint32_t offset = 0;
128  profiling::WriteUint32(data, offset, period);
129  offset += 4;
130  for (std::vector<uint16_t>::iterator it = counters.begin(); it != counters.end(); ++it)
131  {
132  profiling::WriteUint16(data, offset, *it);
133  offset += 2;
134  }
135 
136  // Send the packet.
137  m_BasePipeServer.get()->SendPacket(0, 4, data, dataLength);
138  // There will be an echo response packet sitting in the receive thread. PeriodicCounterSelectionResponseHandler
139  // should deal with it.
140 }
141 
142 void GatordMockService::WaitCommand(uint32_t timeout)
143 {
144  // Wait for a maximum of timeout microseconds or if the receive thread has closed.
145  // There is a certain level of rounding involved in this timing.
146  uint32_t iterations = timeout / 1000;
147  std::cout << std::dec << "Wait command with timeout of " << timeout << " iterations = " << iterations << std::endl;
148  uint32_t count = 0;
149  while ((this->ReceiveThreadRunning() && (count < iterations)))
150  {
151  std::this_thread::sleep_for(std::chrono::microseconds(1000));
152  ++count;
153  }
154  if (m_EchoPackets)
155  {
156  std::cout << std::dec << "Wait command with timeout of " << timeout << " microseconds completed. " << std::endl;
157  }
158 }
159 
160 void GatordMockService::ReceiveLoop()
161 {
162  m_CloseReceivingThread.store(false);
163  while (!m_CloseReceivingThread.load())
164  {
165  try
166  {
167  profiling::Packet packet = m_BasePipeServer.get()->WaitForPacket(500);
168 
169  profiling::PacketVersionResolver packetVersionResolver;
170 
171  profiling::Version version =
172  packetVersionResolver.ResolvePacketVersion(packet.GetPacketFamily(), packet.GetPacketId());
173 
174  profiling::CommandHandlerFunctor* commandHandlerFunctor = m_HandlerRegistry.GetFunctor(
175  packet.GetPacketFamily(),
176  packet.GetPacketId(),
177  version.GetEncodedValue());
178 
179 
180 
181  ARMNN_ASSERT(commandHandlerFunctor);
182  commandHandlerFunctor->operator()(packet);
183  }
184  catch (const armnn::TimeoutException&)
185  {
186  // In this case we ignore timeouts and and keep trying to receive.
187  }
188  catch (const armnn::InvalidArgumentException& e)
189  {
190  // We couldn't find a functor to handle the packet?
191  std::cerr << "Packet received that could not be processed: " << e.what() << std::endl;
192  }
193  catch (const armnn::RuntimeException& e)
194  {
195  // A runtime exception occurred which means we must exit the loop.
196  std::cerr << "Receive thread closing: " << e.what() << std::endl;
197  m_CloseReceivingThread.store(true);
198  }
199  }
200 }
201 
202 } // namespace gatordmock
203 
204 } // namespace armnn
void WriteUint16(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint16_t value)
void WriteUint32(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint32_t value)
Version ResolvePacketVersion(uint32_t familyId, uint32_t packetId) const
virtual const char * what() const noexcept override
Definition: Exceptions.cpp:32
CommandHandlerFunctor * GetFunctor(uint32_t familyId, uint32_t packetId, uint32_t version) const
Copyright (c) 2020 ARM Limited.
void SendDeactivateTimelinePacket()
Send a deactivate timeline packet back to the client.
void SendActivateTimelinePacket()
Send a activate timeline packet back to the client.
bool WaitForStreamMetaData()
Once the connection is open wait to receive the stream meta data packet from the client.
void SendRequestCounterDir()
Send a request counter directory packet back to the client.
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
bool LaunchReceivingThread()
Start the thread that will receive all packets and print them nicely to stdout.
void WaitCommand(uint32_t timeout)
Execute the WAIT command from the comamnd file.
void SendPeriodicCounterSelectionList(uint32_t period, std::vector< uint16_t > counters)
Send the counter list to ArmNN.
void WaitForReceivingThread()
This is a placeholder method to prevent main exiting.
void SendConnectionAck()
Send a connection acknowledged packet back to the client.