1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #include "FileOnlyProfilingConnection.hpp"
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker #include <common/include/Constants.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include <common/include/ProfilingException.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <common/include/PacketVersionResolver.hpp>
11*89c4ff92SAndroid Build Coastguard Worker
12*89c4ff92SAndroid Build Coastguard Worker #include <algorithm>
13*89c4ff92SAndroid Build Coastguard Worker #include <iostream>
14*89c4ff92SAndroid Build Coastguard Worker
15*89c4ff92SAndroid Build Coastguard Worker #if defined(ARMNN_DISABLE_THREADS)
16*89c4ff92SAndroid Build Coastguard Worker #include <common/include/IgnoreUnused.hpp>
17*89c4ff92SAndroid Build Coastguard Worker #endif
18*89c4ff92SAndroid Build Coastguard Worker
19*89c4ff92SAndroid Build Coastguard Worker namespace arm
20*89c4ff92SAndroid Build Coastguard Worker {
21*89c4ff92SAndroid Build Coastguard Worker
22*89c4ff92SAndroid Build Coastguard Worker namespace pipe
23*89c4ff92SAndroid Build Coastguard Worker {
24*89c4ff92SAndroid Build Coastguard Worker
GetHeadersAccepted()25*89c4ff92SAndroid Build Coastguard Worker std::vector<uint32_t> StreamMetaDataProcessor::GetHeadersAccepted()
26*89c4ff92SAndroid Build Coastguard Worker {
27*89c4ff92SAndroid Build Coastguard Worker std::vector<uint32_t> headers;
28*89c4ff92SAndroid Build Coastguard Worker headers.push_back(m_MetaDataPacketHeader);
29*89c4ff92SAndroid Build Coastguard Worker return headers;
30*89c4ff92SAndroid Build Coastguard Worker }
31*89c4ff92SAndroid Build Coastguard Worker
HandlePacket(const arm::pipe::Packet & packet)32*89c4ff92SAndroid Build Coastguard Worker void StreamMetaDataProcessor::HandlePacket(const arm::pipe::Packet& packet)
33*89c4ff92SAndroid Build Coastguard Worker {
34*89c4ff92SAndroid Build Coastguard Worker if (packet.GetHeader() != m_MetaDataPacketHeader)
35*89c4ff92SAndroid Build Coastguard Worker {
36*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException("StreamMetaDataProcessor can only handle Stream Meta Data Packets");
37*89c4ff92SAndroid Build Coastguard Worker }
38*89c4ff92SAndroid Build Coastguard Worker // determine the endianness of the protocol
39*89c4ff92SAndroid Build Coastguard Worker TargetEndianness endianness;
40*89c4ff92SAndroid Build Coastguard Worker if (ToUint32(packet.GetData(),TargetEndianness::BeWire) == arm::pipe::PIPE_MAGIC)
41*89c4ff92SAndroid Build Coastguard Worker {
42*89c4ff92SAndroid Build Coastguard Worker endianness = TargetEndianness::BeWire;
43*89c4ff92SAndroid Build Coastguard Worker }
44*89c4ff92SAndroid Build Coastguard Worker else if (ToUint32(packet.GetData(), TargetEndianness::LeWire) == arm::pipe::PIPE_MAGIC)
45*89c4ff92SAndroid Build Coastguard Worker {
46*89c4ff92SAndroid Build Coastguard Worker endianness = TargetEndianness::LeWire;
47*89c4ff92SAndroid Build Coastguard Worker }
48*89c4ff92SAndroid Build Coastguard Worker else
49*89c4ff92SAndroid Build Coastguard Worker {
50*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException("Protocol read error. Unable to read the PIPE_MAGIC value.");
51*89c4ff92SAndroid Build Coastguard Worker }
52*89c4ff92SAndroid Build Coastguard Worker m_FileOnlyProfilingConnection->SetEndianess(endianness);
53*89c4ff92SAndroid Build Coastguard Worker // send back the acknowledgement
54*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<unsigned char[]> uniqueNullPtr = nullptr;
55*89c4ff92SAndroid Build Coastguard Worker arm::pipe::Packet returnPacket(0x10000, 0, uniqueNullPtr);
56*89c4ff92SAndroid Build Coastguard Worker m_FileOnlyProfilingConnection->ReturnPacket(returnPacket);
57*89c4ff92SAndroid Build Coastguard Worker }
58*89c4ff92SAndroid Build Coastguard Worker
ToUint32(const unsigned char * data,TargetEndianness endianness)59*89c4ff92SAndroid Build Coastguard Worker uint32_t StreamMetaDataProcessor::ToUint32(const unsigned char* data, TargetEndianness endianness)
60*89c4ff92SAndroid Build Coastguard Worker {
61*89c4ff92SAndroid Build Coastguard Worker // Extract the first 4 bytes starting at data and push them into a 32bit integer based on the
62*89c4ff92SAndroid Build Coastguard Worker // specified endianness.
63*89c4ff92SAndroid Build Coastguard Worker if (endianness == TargetEndianness::BeWire)
64*89c4ff92SAndroid Build Coastguard Worker {
65*89c4ff92SAndroid Build Coastguard Worker return static_cast<uint32_t>(data[0]) << 24 | static_cast<uint32_t>(data[1]) << 16 |
66*89c4ff92SAndroid Build Coastguard Worker static_cast<uint32_t>(data[2]) << 8 | static_cast<uint32_t>(data[3]);
67*89c4ff92SAndroid Build Coastguard Worker }
68*89c4ff92SAndroid Build Coastguard Worker else
69*89c4ff92SAndroid Build Coastguard Worker {
70*89c4ff92SAndroid Build Coastguard Worker return static_cast<uint32_t>(data[3]) << 24 | static_cast<uint32_t>(data[2]) << 16 |
71*89c4ff92SAndroid Build Coastguard Worker static_cast<uint32_t>(data[1]) << 8 | static_cast<uint32_t>(data[0]);
72*89c4ff92SAndroid Build Coastguard Worker }
73*89c4ff92SAndroid Build Coastguard Worker }
74*89c4ff92SAndroid Build Coastguard Worker
~FileOnlyProfilingConnection()75*89c4ff92SAndroid Build Coastguard Worker FileOnlyProfilingConnection::~FileOnlyProfilingConnection()
76*89c4ff92SAndroid Build Coastguard Worker {
77*89c4ff92SAndroid Build Coastguard Worker try
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker Close();
80*89c4ff92SAndroid Build Coastguard Worker }
81*89c4ff92SAndroid Build Coastguard Worker catch (...)
82*89c4ff92SAndroid Build Coastguard Worker {
83*89c4ff92SAndroid Build Coastguard Worker // do nothing
84*89c4ff92SAndroid Build Coastguard Worker }
85*89c4ff92SAndroid Build Coastguard Worker }
86*89c4ff92SAndroid Build Coastguard Worker
IsOpen() const87*89c4ff92SAndroid Build Coastguard Worker bool FileOnlyProfilingConnection::IsOpen() const
88*89c4ff92SAndroid Build Coastguard Worker {
89*89c4ff92SAndroid Build Coastguard Worker // This type of connection is always open.
90*89c4ff92SAndroid Build Coastguard Worker return true;
91*89c4ff92SAndroid Build Coastguard Worker }
92*89c4ff92SAndroid Build Coastguard Worker
Close()93*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::Close()
94*89c4ff92SAndroid Build Coastguard Worker {
95*89c4ff92SAndroid Build Coastguard Worker // Dump any unread packets out of the queue.
96*89c4ff92SAndroid Build Coastguard Worker size_t initialSize = m_PacketQueue.size();
97*89c4ff92SAndroid Build Coastguard Worker for (size_t i = 0; i < initialSize; ++i)
98*89c4ff92SAndroid Build Coastguard Worker {
99*89c4ff92SAndroid Build Coastguard Worker m_PacketQueue.pop();
100*89c4ff92SAndroid Build Coastguard Worker }
101*89c4ff92SAndroid Build Coastguard Worker // dispose of the processing thread
102*89c4ff92SAndroid Build Coastguard Worker m_KeepRunning.store(false);
103*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
104*89c4ff92SAndroid Build Coastguard Worker if (m_LocalHandlersThread.joinable())
105*89c4ff92SAndroid Build Coastguard Worker {
106*89c4ff92SAndroid Build Coastguard Worker // make sure the thread wakes up and sees it has to stop
107*89c4ff92SAndroid Build Coastguard Worker m_ConditionPacketReadable.notify_one();
108*89c4ff92SAndroid Build Coastguard Worker m_LocalHandlersThread.join();
109*89c4ff92SAndroid Build Coastguard Worker }
110*89c4ff92SAndroid Build Coastguard Worker #endif
111*89c4ff92SAndroid Build Coastguard Worker }
112*89c4ff92SAndroid Build Coastguard Worker
WritePacket(const unsigned char * buffer,uint32_t length)113*89c4ff92SAndroid Build Coastguard Worker bool FileOnlyProfilingConnection::WritePacket(const unsigned char* buffer, uint32_t length)
114*89c4ff92SAndroid Build Coastguard Worker {
115*89c4ff92SAndroid Build Coastguard Worker ARM_PIPE_ASSERT(buffer);
116*89c4ff92SAndroid Build Coastguard Worker arm::pipe::Packet packet = ReceivePacket(buffer, length);
117*89c4ff92SAndroid Build Coastguard Worker ForwardPacketToHandlers(packet);
118*89c4ff92SAndroid Build Coastguard Worker return true;
119*89c4ff92SAndroid Build Coastguard Worker }
120*89c4ff92SAndroid Build Coastguard Worker
ReturnPacket(arm::pipe::Packet & packet)121*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::ReturnPacket(arm::pipe::Packet& packet)
122*89c4ff92SAndroid Build Coastguard Worker {
123*89c4ff92SAndroid Build Coastguard Worker {
124*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
125*89c4ff92SAndroid Build Coastguard Worker std::lock_guard<std::mutex> lck(m_PacketAvailableMutex);
126*89c4ff92SAndroid Build Coastguard Worker #endif
127*89c4ff92SAndroid Build Coastguard Worker m_PacketQueue.push(std::move(packet));
128*89c4ff92SAndroid Build Coastguard Worker }
129*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
130*89c4ff92SAndroid Build Coastguard Worker m_ConditionPacketAvailable.notify_one();
131*89c4ff92SAndroid Build Coastguard Worker #endif
132*89c4ff92SAndroid Build Coastguard Worker }
133*89c4ff92SAndroid Build Coastguard Worker
ReadPacket(uint32_t timeout)134*89c4ff92SAndroid Build Coastguard Worker arm::pipe::Packet FileOnlyProfilingConnection::ReadPacket(uint32_t timeout)
135*89c4ff92SAndroid Build Coastguard Worker {
136*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
137*89c4ff92SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lck(m_PacketAvailableMutex);
138*89c4ff92SAndroid Build Coastguard Worker
139*89c4ff92SAndroid Build Coastguard Worker // Here we are using m_PacketQueue.empty() as a predicate variable
140*89c4ff92SAndroid Build Coastguard Worker // The conditional variable will wait until packetQueue is not empty or until a timeout
141*89c4ff92SAndroid Build Coastguard Worker if (!m_ConditionPacketAvailable.wait_for(lck,
142*89c4ff92SAndroid Build Coastguard Worker std::chrono::milliseconds(timeout),
143*89c4ff92SAndroid Build Coastguard Worker [&]{return !m_PacketQueue.empty();}))
144*89c4ff92SAndroid Build Coastguard Worker {
145*89c4ff92SAndroid Build Coastguard Worker arm::pipe::Packet empty;
146*89c4ff92SAndroid Build Coastguard Worker return empty;
147*89c4ff92SAndroid Build Coastguard Worker }
148*89c4ff92SAndroid Build Coastguard Worker #else
149*89c4ff92SAndroid Build Coastguard Worker IgnoreUnused(timeout);
150*89c4ff92SAndroid Build Coastguard Worker #endif
151*89c4ff92SAndroid Build Coastguard Worker
152*89c4ff92SAndroid Build Coastguard Worker arm::pipe::Packet returnedPacket = std::move(m_PacketQueue.front());
153*89c4ff92SAndroid Build Coastguard Worker m_PacketQueue.pop();
154*89c4ff92SAndroid Build Coastguard Worker return returnedPacket;
155*89c4ff92SAndroid Build Coastguard Worker }
156*89c4ff92SAndroid Build Coastguard Worker
Fail(const std::string & errorMessage)157*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::Fail(const std::string& errorMessage)
158*89c4ff92SAndroid Build Coastguard Worker {
159*89c4ff92SAndroid Build Coastguard Worker Close();
160*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException(errorMessage);
161*89c4ff92SAndroid Build Coastguard Worker }
162*89c4ff92SAndroid Build Coastguard Worker
163*89c4ff92SAndroid Build Coastguard Worker /// Adds a local packet handler to the FileOnlyProfilingConnection. Invoking this will start
164*89c4ff92SAndroid Build Coastguard Worker /// a processing thread that will ensure that processing of packets will happen on a separate
165*89c4ff92SAndroid Build Coastguard Worker /// thread from the profiling services send thread and will therefore protect against the
166*89c4ff92SAndroid Build Coastguard Worker /// profiling message buffer becoming exhausted because packet handling slows the dispatch.
AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler)167*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler)
168*89c4ff92SAndroid Build Coastguard Worker {
169*89c4ff92SAndroid Build Coastguard Worker m_PacketHandlers.push_back(std::move(localPacketHandler));
170*89c4ff92SAndroid Build Coastguard Worker ILocalPacketHandlerSharedPtr localCopy = m_PacketHandlers.back();
171*89c4ff92SAndroid Build Coastguard Worker localCopy->SetConnection(this);
172*89c4ff92SAndroid Build Coastguard Worker if (localCopy->GetHeadersAccepted().empty())
173*89c4ff92SAndroid Build Coastguard Worker {
174*89c4ff92SAndroid Build Coastguard Worker //this is a universal handler
175*89c4ff92SAndroid Build Coastguard Worker m_UniversalHandlers.push_back(localCopy);
176*89c4ff92SAndroid Build Coastguard Worker }
177*89c4ff92SAndroid Build Coastguard Worker else
178*89c4ff92SAndroid Build Coastguard Worker {
179*89c4ff92SAndroid Build Coastguard Worker for (uint32_t header : localCopy->GetHeadersAccepted())
180*89c4ff92SAndroid Build Coastguard Worker {
181*89c4ff92SAndroid Build Coastguard Worker auto iter = m_IndexedHandlers.find(header);
182*89c4ff92SAndroid Build Coastguard Worker if (iter == m_IndexedHandlers.end())
183*89c4ff92SAndroid Build Coastguard Worker {
184*89c4ff92SAndroid Build Coastguard Worker std::vector<ILocalPacketHandlerSharedPtr> handlers;
185*89c4ff92SAndroid Build Coastguard Worker handlers.push_back(localCopy);
186*89c4ff92SAndroid Build Coastguard Worker m_IndexedHandlers.emplace(std::make_pair(header, handlers));
187*89c4ff92SAndroid Build Coastguard Worker }
188*89c4ff92SAndroid Build Coastguard Worker else
189*89c4ff92SAndroid Build Coastguard Worker {
190*89c4ff92SAndroid Build Coastguard Worker iter->second.push_back(localCopy);
191*89c4ff92SAndroid Build Coastguard Worker }
192*89c4ff92SAndroid Build Coastguard Worker }
193*89c4ff92SAndroid Build Coastguard Worker }
194*89c4ff92SAndroid Build Coastguard Worker }
195*89c4ff92SAndroid Build Coastguard Worker
StartProcessingThread()196*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::StartProcessingThread()
197*89c4ff92SAndroid Build Coastguard Worker {
198*89c4ff92SAndroid Build Coastguard Worker // check if the thread has already started
199*89c4ff92SAndroid Build Coastguard Worker if (m_IsRunning.load())
200*89c4ff92SAndroid Build Coastguard Worker {
201*89c4ff92SAndroid Build Coastguard Worker return;
202*89c4ff92SAndroid Build Coastguard Worker }
203*89c4ff92SAndroid Build Coastguard Worker // make sure if there was one running before it is joined
204*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
205*89c4ff92SAndroid Build Coastguard Worker if (m_LocalHandlersThread.joinable())
206*89c4ff92SAndroid Build Coastguard Worker {
207*89c4ff92SAndroid Build Coastguard Worker m_LocalHandlersThread.join();
208*89c4ff92SAndroid Build Coastguard Worker }
209*89c4ff92SAndroid Build Coastguard Worker #endif
210*89c4ff92SAndroid Build Coastguard Worker m_IsRunning.store(true);
211*89c4ff92SAndroid Build Coastguard Worker m_KeepRunning.store(true);
212*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
213*89c4ff92SAndroid Build Coastguard Worker m_LocalHandlersThread = std::thread(&FileOnlyProfilingConnection::ServiceLocalHandlers, this);
214*89c4ff92SAndroid Build Coastguard Worker #endif
215*89c4ff92SAndroid Build Coastguard Worker }
216*89c4ff92SAndroid Build Coastguard Worker
ForwardPacketToHandlers(arm::pipe::Packet & packet)217*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::ForwardPacketToHandlers(arm::pipe::Packet& packet)
218*89c4ff92SAndroid Build Coastguard Worker {
219*89c4ff92SAndroid Build Coastguard Worker if (m_PacketHandlers.empty())
220*89c4ff92SAndroid Build Coastguard Worker {
221*89c4ff92SAndroid Build Coastguard Worker return;
222*89c4ff92SAndroid Build Coastguard Worker }
223*89c4ff92SAndroid Build Coastguard Worker if (!m_KeepRunning.load())
224*89c4ff92SAndroid Build Coastguard Worker {
225*89c4ff92SAndroid Build Coastguard Worker return;
226*89c4ff92SAndroid Build Coastguard Worker }
227*89c4ff92SAndroid Build Coastguard Worker {
228*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
229*89c4ff92SAndroid Build Coastguard Worker std::unique_lock<std::mutex> readableListLock(m_ReadableMutex);
230*89c4ff92SAndroid Build Coastguard Worker #endif
231*89c4ff92SAndroid Build Coastguard Worker if (!m_KeepRunning.load())
232*89c4ff92SAndroid Build Coastguard Worker {
233*89c4ff92SAndroid Build Coastguard Worker return;
234*89c4ff92SAndroid Build Coastguard Worker }
235*89c4ff92SAndroid Build Coastguard Worker m_ReadableList.push(std::move(packet));
236*89c4ff92SAndroid Build Coastguard Worker }
237*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
238*89c4ff92SAndroid Build Coastguard Worker m_ConditionPacketReadable.notify_one();
239*89c4ff92SAndroid Build Coastguard Worker #endif
240*89c4ff92SAndroid Build Coastguard Worker }
241*89c4ff92SAndroid Build Coastguard Worker
ServiceLocalHandlers()242*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::ServiceLocalHandlers()
243*89c4ff92SAndroid Build Coastguard Worker {
244*89c4ff92SAndroid Build Coastguard Worker do
245*89c4ff92SAndroid Build Coastguard Worker {
246*89c4ff92SAndroid Build Coastguard Worker arm::pipe::Packet returnedPacket;
247*89c4ff92SAndroid Build Coastguard Worker bool readPacket = false;
248*89c4ff92SAndroid Build Coastguard Worker { // only lock while we are taking the packet off the incoming list
249*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
250*89c4ff92SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lck(m_ReadableMutex);
251*89c4ff92SAndroid Build Coastguard Worker #endif
252*89c4ff92SAndroid Build Coastguard Worker if (m_Timeout < 0)
253*89c4ff92SAndroid Build Coastguard Worker {
254*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
255*89c4ff92SAndroid Build Coastguard Worker m_ConditionPacketReadable.wait(lck,
256*89c4ff92SAndroid Build Coastguard Worker [&] { return !m_ReadableList.empty(); });
257*89c4ff92SAndroid Build Coastguard Worker #endif
258*89c4ff92SAndroid Build Coastguard Worker }
259*89c4ff92SAndroid Build Coastguard Worker else
260*89c4ff92SAndroid Build Coastguard Worker {
261*89c4ff92SAndroid Build Coastguard Worker #if !defined(ARMNN_DISABLE_THREADS)
262*89c4ff92SAndroid Build Coastguard Worker m_ConditionPacketReadable.wait_for(lck,
263*89c4ff92SAndroid Build Coastguard Worker std::chrono::milliseconds(std::max(m_Timeout, 1000)),
264*89c4ff92SAndroid Build Coastguard Worker [&] { return !m_ReadableList.empty(); });
265*89c4ff92SAndroid Build Coastguard Worker #endif
266*89c4ff92SAndroid Build Coastguard Worker }
267*89c4ff92SAndroid Build Coastguard Worker if (m_KeepRunning.load())
268*89c4ff92SAndroid Build Coastguard Worker {
269*89c4ff92SAndroid Build Coastguard Worker if (!m_ReadableList.empty())
270*89c4ff92SAndroid Build Coastguard Worker {
271*89c4ff92SAndroid Build Coastguard Worker returnedPacket = std::move(m_ReadableList.front());
272*89c4ff92SAndroid Build Coastguard Worker m_ReadableList.pop();
273*89c4ff92SAndroid Build Coastguard Worker readPacket = true;
274*89c4ff92SAndroid Build Coastguard Worker }
275*89c4ff92SAndroid Build Coastguard Worker }
276*89c4ff92SAndroid Build Coastguard Worker else
277*89c4ff92SAndroid Build Coastguard Worker {
278*89c4ff92SAndroid Build Coastguard Worker ClearReadableList();
279*89c4ff92SAndroid Build Coastguard Worker }
280*89c4ff92SAndroid Build Coastguard Worker }
281*89c4ff92SAndroid Build Coastguard Worker if (m_KeepRunning.load() && readPacket)
282*89c4ff92SAndroid Build Coastguard Worker {
283*89c4ff92SAndroid Build Coastguard Worker DispatchPacketToHandlers(returnedPacket);
284*89c4ff92SAndroid Build Coastguard Worker }
285*89c4ff92SAndroid Build Coastguard Worker } while (m_KeepRunning.load());
286*89c4ff92SAndroid Build Coastguard Worker // make sure the readable list is cleared
287*89c4ff92SAndroid Build Coastguard Worker ClearReadableList();
288*89c4ff92SAndroid Build Coastguard Worker m_IsRunning.store(false);
289*89c4ff92SAndroid Build Coastguard Worker }
290*89c4ff92SAndroid Build Coastguard Worker
ClearReadableList()291*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::ClearReadableList()
292*89c4ff92SAndroid Build Coastguard Worker {
293*89c4ff92SAndroid Build Coastguard Worker // make sure the incoming packet queue gets emptied
294*89c4ff92SAndroid Build Coastguard Worker size_t initialSize = m_ReadableList.size();
295*89c4ff92SAndroid Build Coastguard Worker for (size_t i = 0; i < initialSize; ++i)
296*89c4ff92SAndroid Build Coastguard Worker {
297*89c4ff92SAndroid Build Coastguard Worker m_ReadableList.pop();
298*89c4ff92SAndroid Build Coastguard Worker }
299*89c4ff92SAndroid Build Coastguard Worker }
300*89c4ff92SAndroid Build Coastguard Worker
DispatchPacketToHandlers(const arm::pipe::Packet & packet)301*89c4ff92SAndroid Build Coastguard Worker void FileOnlyProfilingConnection::DispatchPacketToHandlers(const arm::pipe::Packet& packet)
302*89c4ff92SAndroid Build Coastguard Worker {
303*89c4ff92SAndroid Build Coastguard Worker for (auto& delegate : m_UniversalHandlers)
304*89c4ff92SAndroid Build Coastguard Worker {
305*89c4ff92SAndroid Build Coastguard Worker delegate->HandlePacket(packet);
306*89c4ff92SAndroid Build Coastguard Worker }
307*89c4ff92SAndroid Build Coastguard Worker auto iter = m_IndexedHandlers.find(packet.GetHeader());
308*89c4ff92SAndroid Build Coastguard Worker if (iter != m_IndexedHandlers.end())
309*89c4ff92SAndroid Build Coastguard Worker {
310*89c4ff92SAndroid Build Coastguard Worker for (auto& delegate : iter->second)
311*89c4ff92SAndroid Build Coastguard Worker {
312*89c4ff92SAndroid Build Coastguard Worker try
313*89c4ff92SAndroid Build Coastguard Worker {
314*89c4ff92SAndroid Build Coastguard Worker delegate->HandlePacket(packet);
315*89c4ff92SAndroid Build Coastguard Worker }
316*89c4ff92SAndroid Build Coastguard Worker catch (const arm::pipe::ProfilingException& ex)
317*89c4ff92SAndroid Build Coastguard Worker {
318*89c4ff92SAndroid Build Coastguard Worker Fail(ex.what());
319*89c4ff92SAndroid Build Coastguard Worker }
320*89c4ff92SAndroid Build Coastguard Worker catch (const std::exception& ex)
321*89c4ff92SAndroid Build Coastguard Worker {
322*89c4ff92SAndroid Build Coastguard Worker Fail(ex.what());
323*89c4ff92SAndroid Build Coastguard Worker }
324*89c4ff92SAndroid Build Coastguard Worker catch (...)
325*89c4ff92SAndroid Build Coastguard Worker {
326*89c4ff92SAndroid Build Coastguard Worker Fail("handler failed");
327*89c4ff92SAndroid Build Coastguard Worker }
328*89c4ff92SAndroid Build Coastguard Worker }
329*89c4ff92SAndroid Build Coastguard Worker }
330*89c4ff92SAndroid Build Coastguard Worker }
331*89c4ff92SAndroid Build Coastguard Worker
332*89c4ff92SAndroid Build Coastguard Worker } // namespace pipe
333*89c4ff92SAndroid Build Coastguard Worker
334*89c4ff92SAndroid Build Coastguard Worker } // namespace arm
335