• 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 #pragma once
7 
8 #include "IProfilingConnection.hpp"
9 #include "ProfilingUtils.hpp"
10 
11 #include <client/include/ILocalPacketHandler.hpp>
12 #include <client/include/ProfilingOptions.hpp>
13 
14 #include <common/include/Assert.hpp>
15 #include <common/include/Packet.hpp>
16 
17 #include <server/include/timelineDecoder/DirectoryCaptureCommandHandler.hpp>
18 
19 #include <atomic>
20 #include <fstream>
21 #include <map>
22 #include <queue>
23 
24 #if !defined(ARMNN_DISABLE_THREADS)
25 #include <condition_variable>
26 #include <mutex>
27 #include <thread>
28 #endif
29 
30 namespace arm
31 {
32 
33 namespace pipe
34 {
35 
36 // forward declaration
37 class FileOnlyProfilingConnection;
38 
39 class StreamMetaDataProcessor : public ILocalPacketHandler
40 {
41 public:
StreamMetaDataProcessor(FileOnlyProfilingConnection * fileOnlyProfilingConnection)42     explicit StreamMetaDataProcessor(FileOnlyProfilingConnection* fileOnlyProfilingConnection) :
43             m_FileOnlyProfilingConnection(fileOnlyProfilingConnection),
44             m_MetaDataPacketHeader(ConstructHeader(0, 0)) {};
45 
46     std::vector<uint32_t> GetHeadersAccepted() override;
47 
48     void HandlePacket(const arm::pipe::Packet& packet) override;
49 
50 private:
51     FileOnlyProfilingConnection* m_FileOnlyProfilingConnection;
52     uint32_t m_MetaDataPacketHeader;
53 
54     static uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
55 };
56 
57 class FileOnlyProfilingConnection : public IProfilingConnection, public IInternalProfilingConnection
58 {
59 public:
FileOnlyProfilingConnection(const ProfilingOptions & options)60     explicit FileOnlyProfilingConnection(const ProfilingOptions& options)
61         : m_Options(options)
62         , m_Endianness(TargetEndianness::LeWire)    // Set a sensible default.
63                                                     // StreamMetaDataProcessor will set a real value.
64         , m_IsRunning(false)
65         , m_KeepRunning(false)
66         , m_Timeout(1000)
67     {
68         // add the StreamMetaDataProcessor
69         auto streamMetaDataProcessor = std::make_shared<StreamMetaDataProcessor>(this);
70         AddLocalPacketHandler(streamMetaDataProcessor);
71         // and any additional ones added by the users
72         for (const ILocalPacketHandlerSharedPtr& localPacketHandler : options.m_LocalPacketHandlers)
73         {
74             AddLocalPacketHandler(localPacketHandler);
75         }
76         if (!m_PacketHandlers.empty())
77         {
78             StartProcessingThread();
79         }
80         // NOTE: could add timeout to the external profiling options
81     };
82 
83     ~FileOnlyProfilingConnection() override;
84 
85     bool IsOpen() const override;
86 
87     void Close() override;
88 
89     // This is effectively receiving a data packet from ArmNN.
90     bool WritePacket(const unsigned char* buffer, uint32_t length) override;
91 
92     // Sending a packet back to ArmNN.
93     arm::pipe::Packet ReadPacket(uint32_t timeout) override;
94 
SetEndianess(const TargetEndianness & endianness)95     void SetEndianess(const TargetEndianness& endianness) override //IInternalProfilingConnection
96     {
97         m_Endianness = endianness;
98     }
99 
100     void ReturnPacket(arm::pipe::Packet& packet) override; //IInternalProfilingConnection
101 
102 private:
103     void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
104     void StartProcessingThread();
105     void ClearReadableList();
106     void DispatchPacketToHandlers(const arm::pipe::Packet& packet);
107 
108     void Fail(const std::string& errorMessage);
109 
110     void ForwardPacketToHandlers(arm::pipe::Packet& packet);
111     void ServiceLocalHandlers();
112 
113     ProfilingOptions m_Options;
114     std::queue<arm::pipe::Packet> m_PacketQueue;
115     TargetEndianness m_Endianness;
116 
117 #if !defined(ARMNN_DISABLE_THREADS)
118     std::mutex m_PacketAvailableMutex;
119     std::condition_variable m_ConditionPacketAvailable;
120 #endif
121 
122     std::vector<ILocalPacketHandlerSharedPtr> m_PacketHandlers;
123     std::map<uint32_t, std::vector<ILocalPacketHandlerSharedPtr>> m_IndexedHandlers;
124     std::vector<ILocalPacketHandlerSharedPtr> m_UniversalHandlers;
125 
126     // List of readable packets for the local packet handlers
127     std::queue<arm::pipe::Packet> m_ReadableList;
128     // Mutex and condition variable for the readable packet list
129 #if !defined(ARMNN_DISABLE_THREADS)
130     std::mutex m_ReadableMutex;
131     std::condition_variable m_ConditionPacketReadable;
132     // thread that takes items from the readable list and dispatches them
133     // to the handlers.
134     std::thread m_LocalHandlersThread;
135 #endif
136     // atomic booleans that control the operation of the local handlers thread
137     std::atomic<bool> m_IsRunning;
138     std::atomic<bool> m_KeepRunning;
139     int m_Timeout;
140 };
141 
142 }    // namespace pipe
143 
144 }    // namespace arm
145