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