• 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 "ActivateTimelineReportingCommandHandler.hpp"
9 #include "BufferManager.hpp"
10 #include "CommandHandler.hpp"
11 #include "ConnectionAcknowledgedCommandHandler.hpp"
12 #include "DeactivateTimelineReportingCommandHandler.hpp"
13 #include "INotifyBackends.hpp"
14 #include "PeriodicCounterCapture.hpp"
15 #include "PeriodicCounterSelectionCommandHandler.hpp"
16 #include "PerJobCounterSelectionCommandHandler.hpp"
17 #include "ProfilingConnectionFactory.hpp"
18 #include "ProfilingStateMachine.hpp"
19 #include "RequestCounterDirectoryCommandHandler.hpp"
20 #include "SendCounterPacket.hpp"
21 #include "SendThread.hpp"
22 #include "SendTimelinePacket.hpp"
23 #include "TimelinePacketWriterFactory.hpp"
24 
25 #include <client/include/CounterIdMap.hpp>
26 #include <client/include/ICounterValues.hpp>
27 #include <client/include/ILocalPacketHandler.hpp>
28 #include <client/include/IProfilingService.hpp>
29 #include <client/include/IReportStructure.hpp>
30 
31 #include <client/include/backends/IBackendProfilingContext.hpp>
32 
33 #include <common/include/CounterDirectory.hpp>
34 
35 #include <list>
36 
37 namespace arm
38 {
39 
40 namespace pipe
41 {
42 
43 class ProfilingService : public IProfilingService, public INotifyBackends
44 {
45 public:
46     using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
47     using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
48     using CounterIndices = std::vector<std::atomic<uint32_t>*>;
49     using CounterValues = std::list<std::atomic<uint32_t>>;
50     using BackendProfilingContext = std::unordered_map<std::string,
51                                                        std::shared_ptr<IBackendProfilingContext>>;
52 
ProfilingService(uint16_t maxGlobalCounterId,IInitialiseProfilingService & initialiser,const std::string & softwareInfo,const std::string & softwareVersion,const std::string & hardwareVersion,arm::pipe::Optional<IReportStructure &> reportStructure=arm::pipe::EmptyOptional ())53     ProfilingService(uint16_t maxGlobalCounterId,
54                      IInitialiseProfilingService& initialiser,
55                      const std::string& softwareInfo,
56                      const std::string& softwareVersion,
57                      const std::string& hardwareVersion,
58                      arm::pipe::Optional<IReportStructure&> reportStructure = arm::pipe::EmptyOptional())
59         : m_Options()
60         , m_TimelineReporting(false)
61         , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
62         , m_ProfilingConnection()
63         , m_StateMachine()
64         , m_CounterIndex()
65         , m_CounterValues()
66         , m_CommandHandlerRegistry()
67         , m_PacketVersionResolver()
68         , m_CommandHandler(1000,
69                            false,
70                            m_CommandHandlerRegistry,
71                            m_PacketVersionResolver)
72         , m_BufferManager()
73         , m_SendCounterPacket(m_BufferManager, softwareInfo, softwareVersion, hardwareVersion)
74         , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket)
75         , m_SendTimelinePacket(m_BufferManager)
76         , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts)
77         , m_ConnectionAcknowledgedCommandHandler(0,
78                                                  1,
79                                                  m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
80                                                  m_CounterDirectory,
81                                                  m_SendCounterPacket,
82                                                  m_SendTimelinePacket,
83                                                  m_StateMachine,
84                                                  *this,
85                                                  m_BackendProfilingContexts)
86         , m_RequestCounterDirectoryCommandHandler(0,
87                                                   3,
88                                                   m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
89                                                   m_CounterDirectory,
90                                                   m_SendCounterPacket,
91                                                   m_SendTimelinePacket,
92                                                   m_StateMachine)
93         , m_PeriodicCounterSelectionCommandHandler(0,
94                                                    4,
95                                                    m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
96                                                    m_BackendProfilingContexts,
97                                                    m_CounterIdMap,
98                                                    m_Holder,
99                                                    maxGlobalCounterId,
100                                                    m_PeriodicCounterCapture,
101                                                    *this,
102                                                    m_SendCounterPacket,
103                                                    m_StateMachine)
104         , m_PerJobCounterSelectionCommandHandler(0,
105                                                  5,
106                                                  m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
107                                                  m_StateMachine)
108         , m_ActivateTimelineReportingCommandHandler(0,
109                                                     6,
110                                                     m_PacketVersionResolver.ResolvePacketVersion(0, 6)
111                                                                            .GetEncodedValue(),
112                                                     m_SendTimelinePacket,
113                                                     m_StateMachine,
114                                                     reportStructure,
115                                                     m_TimelineReporting,
116                                                     *this,
117                                                     *this)
118         , m_DeactivateTimelineReportingCommandHandler(0,
119                                                       7,
120                                                       m_PacketVersionResolver.ResolvePacketVersion(0, 7)
121                                                                              .GetEncodedValue(),
122                                                       m_TimelineReporting,
123                                                       m_StateMachine,
124                                                       *this)
125         , m_TimelinePacketWriterFactory(m_BufferManager)
126         , m_MaxGlobalCounterId(maxGlobalCounterId)
127         , m_ServiceActive(false)
128         , m_Initialiser(initialiser)
129     {
130         // Register the "Connection Acknowledged" command handler
131         m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
132 
133         // Register the "Request Counter Directory" command handler
134         m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
135 
136         // Register the "Periodic Counter Selection" command handler
137         m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
138 
139         // Register the "Per-Job Counter Selection" command handler
140         m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
141 
142         m_CommandHandlerRegistry.RegisterFunctor(&m_ActivateTimelineReportingCommandHandler);
143 
144         m_CommandHandlerRegistry.RegisterFunctor(&m_DeactivateTimelineReportingCommandHandler);
145     }
146 
147     ~ProfilingService();
148 
149     // Resets the profiling options, optionally clears the profiling service entirely
150     void ResetExternalProfilingOptions(const ProfilingOptions& options,
151                                        bool resetProfilingService = false) override;
152     ProfilingState ConfigureProfilingService(const ProfilingOptions& options,
153                                              bool resetProfilingService = false) override;
154 
155 
156     // Updates the profiling service, making it transition to a new state if necessary
157     void Update();
158 
159     // Disconnects the profiling service from the external server
160     void Disconnect() override;
161 
162     // Store a profiling context returned from a backend that support profiling.
163     void AddBackendProfilingContext(const std::string& backendId,
164         std::shared_ptr<IBackendProfilingContext> profilingContext) override;
165 
166     // Enable the recording of timeline events and entities
167     void NotifyBackendsForTimelineReporting() override;
168 
169     const ICounterDirectory& GetCounterDirectory() const;
170     ICounterRegistry& GetCounterRegistry() override;
171     ProfilingState GetCurrentState() const override;
172     bool IsCounterRegistered(uint16_t counterUid) const override;
173     uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override;
174     uint32_t GetDeltaCounterValue(uint16_t counterUid) override;
175     uint16_t GetCounterCount() const override;
176     // counter global/backend mapping functions
177     const ICounterMappings& GetCounterMappings() const override;
178     IRegisterCounterMapping& GetCounterMappingRegistry() override;
179     bool IsCategoryRegistered(const std::string& categoryName) const override;
180     bool IsCounterRegistered(const std::string& counterName) const override;
181 
182     // Getters for the profiling service state
183     bool IsProfilingEnabled() const override;
184 
185     CaptureData GetCaptureData() override;
186     void SetCaptureData(uint32_t capturePeriod,
187                         const std::vector<uint16_t>& counterIds,
188                         const std::set<std::string>& activeBackends);
189 
190     // Setters for the profiling service state
191     void SetCounterValue(uint16_t counterUid, uint32_t value) override;
192     uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
193     uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
194     uint32_t IncrementCounterValue(uint16_t counterUid) override;
195 
196     void InitializeCounterValue(uint16_t counterUid) override;
197 
198     std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override;
199 
GetSendCounterPacket()200     ISendCounterPacket& GetSendCounterPacket() override
201     {
202         return m_SendCounterPacket;
203     }
204 
IsTimelineReportingEnabled() const205     bool IsTimelineReportingEnabled() const override
206     {
207         return m_TimelineReporting;
208     }
209 
210     void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
211 
212     void NotifyProfilingServiceActive() override; // IProfilingServiceStatus
213     void WaitForProfilingServiceActivation(unsigned int timeout) override; // IProfilingServiceStatus
214 
215 private:
216     //Copy/move constructors/destructors and copy/move assignment operators are deleted
217     ProfilingService(const ProfilingService&) = delete;
218     ProfilingService(ProfilingService&&) = delete;
219     ProfilingService& operator=(const ProfilingService&) = delete;
220     ProfilingService& operator=(ProfilingService&&) = delete;
221 
222     // Initialization/reset functions
223     void Initialize();
224     void Reset();
225     void Stop();
226 
227     // Helper function
228     void CheckCounterUid(uint16_t counterUid) const;
229 
230     // Profiling service components
231     ProfilingOptions                   m_Options;
232     std::atomic<bool>                  m_TimelineReporting;
233     CounterDirectory                   m_CounterDirectory;
234     CounterIdMap                       m_CounterIdMap;
235     IProfilingConnectionFactoryPtr     m_ProfilingConnectionFactory;
236     IProfilingConnectionPtr            m_ProfilingConnection;
237     ProfilingStateMachine              m_StateMachine;
238     CounterIndices                     m_CounterIndex;
239     CounterValues                      m_CounterValues;
240     arm::pipe::CommandHandlerRegistry  m_CommandHandlerRegistry;
241     arm::pipe::PacketVersionResolver   m_PacketVersionResolver;
242     CommandHandler                     m_CommandHandler;
243     BufferManager                      m_BufferManager;
244     SendCounterPacket                  m_SendCounterPacket;
245     SendThread                         m_SendThread;
246     SendTimelinePacket                 m_SendTimelinePacket;
247 
248     Holder m_Holder;
249 
250     PeriodicCounterCapture m_PeriodicCounterCapture;
251 
252     ConnectionAcknowledgedCommandHandler      m_ConnectionAcknowledgedCommandHandler;
253     RequestCounterDirectoryCommandHandler     m_RequestCounterDirectoryCommandHandler;
254     PeriodicCounterSelectionCommandHandler    m_PeriodicCounterSelectionCommandHandler;
255     PerJobCounterSelectionCommandHandler      m_PerJobCounterSelectionCommandHandler;
256     ActivateTimelineReportingCommandHandler   m_ActivateTimelineReportingCommandHandler;
257     DeactivateTimelineReportingCommandHandler m_DeactivateTimelineReportingCommandHandler;
258 
259     TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
260     BackendProfilingContext     m_BackendProfilingContexts;
261     uint16_t                    m_MaxGlobalCounterId;
262 
263     // Signalling to let external actors know when service is active or not
264 #if !defined(ARMNN_DISABLE_THREADS)
265     std::mutex m_ServiceActiveMutex;
266     std::condition_variable m_ServiceActiveConditionVariable;
267 #endif
268     bool m_ServiceActive;
269 
270     IInitialiseProfilingService& m_Initialiser;
271 
272 protected:
273 
274     // Protected methods for testing
SwapProfilingConnectionFactory(ProfilingService & instance,IProfilingConnectionFactory * other,IProfilingConnectionFactory * & backup)275     void SwapProfilingConnectionFactory(ProfilingService& instance,
276                                         IProfilingConnectionFactory* other,
277                                         IProfilingConnectionFactory*& backup)
278     {
279         ARM_PIPE_ASSERT(instance.m_ProfilingConnectionFactory);
280         ARM_PIPE_ASSERT(other);
281 
282         backup = instance.m_ProfilingConnectionFactory.release();
283         instance.m_ProfilingConnectionFactory.reset(other);
284     }
GetProfilingConnection(ProfilingService & instance)285     IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
286     {
287         return instance.m_ProfilingConnection.get();
288     }
TransitionToState(ProfilingService & instance,ProfilingState newState)289     void TransitionToState(ProfilingService& instance, ProfilingState newState)
290     {
291         instance.m_StateMachine.TransitionToState(newState);
292     }
WaitForPacketSent(ProfilingService & instance,uint32_t timeout=1000)293     bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
294     {
295         return instance.m_SendThread.WaitForPacketSent(timeout);
296     }
297 
GetBufferManager(ProfilingService & instance)298     BufferManager& GetBufferManager(ProfilingService& instance)
299     {
300         return instance.m_BufferManager;
301     }
302 };
303 
304 } // namespace pipe
305 
306 } // namespace arm
307