xref: /aosp_15_r20/external/armnn/profiling/client/src/FileOnlyProfilingConnection.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
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