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