blob: 54b0f93694caec3bb18bb18501589b07d6b910d5 [file] [log] [blame]
Keith Davis02356de2019-08-26 18:28:17 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Jim Flynn8b200652019-10-24 18:07:44 +01008#include "BufferManager.hpp"
9#include "CommandHandler.hpp"
10#include "ConnectionAcknowledgedCommandHandler.hpp"
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010011#include "CounterDirectory.hpp"
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010012#include "ICounterValues.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010013#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010014#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010015#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010016#include "ProfilingConnectionFactory.hpp"
Jim Flynn00f3aaf2019-10-24 11:58:06 +010017#include "ProfilingGuidGenerator.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010018#include "ProfilingStateMachine.hpp"
19#include "RequestCounterDirectoryCommandHandler.hpp"
20#include "SendCounterPacket.hpp"
21#include "TimelinePacketWriterFactory.hpp"
Keith Davis02356de2019-08-26 18:28:17 +010022
23namespace armnn
24{
25
26namespace profiling
27{
28
Jim Flynn00f3aaf2019-10-24 11:58:06 +010029class ProfilingService : public IReadWriteCounterValues, public IProfilingGuidGenerator
Keith Davis02356de2019-08-26 18:28:17 +010030{
31public:
Matteo Martincigha84edee2019-10-02 12:50:57 +010032 using ExternalProfilingOptions = Runtime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010033 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010034 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
35 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
36 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis02356de2019-08-26 18:28:17 +010037
Matteo Martincigha84edee2019-10-02 12:50:57 +010038 // Getter for the singleton instance
39 static ProfilingService& Instance()
40 {
41 static ProfilingService instance;
42 return instance;
43 }
44
45 // Resets the profiling options, optionally clears the profiling service entirely
46 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
Jim Flynn672d06e2019-10-15 10:18:11 +010047 ProfilingState ConfigureProfilingService(const ExternalProfilingOptions& options,
48 bool resetProfilingService = false);
49
Matteo Martincigha84edee2019-10-02 12:50:57 +010050
Matteo Martincigh54fb9572019-10-02 12:50:57 +010051 // Updates the profiling service, making it transition to a new state if necessary
52 void Update();
Keith Davis02356de2019-08-26 18:28:17 +010053
Jim Flynn53e46992019-10-14 12:31:10 +010054 // Disconnects the profiling service from the external server
55 void Disconnect();
56
Matteo Martincigha84edee2019-10-02 12:50:57 +010057 // Getters for the profiling service state
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010058 const ICounterDirectory& GetCounterDirectory() const;
Keith Davis02356de2019-08-26 18:28:17 +010059 ProfilingState GetCurrentState() const;
Matteo Martincighe8485382019-10-10 14:08:21 +010060 bool IsCounterRegistered(uint16_t counterUid) const override;
Matteo Martincigha84edee2019-10-02 12:50:57 +010061 uint16_t GetCounterCount() const override;
62 uint32_t GetCounterValue(uint16_t counterUid) const override;
Keith Davis02356de2019-08-26 18:28:17 +010063
Matteo Martincigha84edee2019-10-02 12:50:57 +010064 // Setters for the profiling service state
65 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
66 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
67 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
68 uint32_t IncrementCounterValue(uint16_t counterUid) override;
69 uint32_t DecrementCounterValue(uint16_t counterUid) override;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +010070
Jim Flynn00f3aaf2019-10-24 11:58:06 +010071 // IProfilingGuidGenerator functions
72 /// Return the next random Guid in the sequence
73 ProfilingDynamicGuid NextGuid() override;
74 /// Create a ProfilingStaticGuid based on a hash of the string
75 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
76
Jim Flynn8b200652019-10-24 18:07:44 +010077 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const;
78
Keith Davis02356de2019-08-26 18:28:17 +010079private:
Matteo Martincigh54fb9572019-10-02 12:50:57 +010080 // Copy/move constructors/destructors and copy/move assignment operators are deleted
Matteo Martincigha84edee2019-10-02 12:50:57 +010081 ProfilingService(const ProfilingService&) = delete;
82 ProfilingService(ProfilingService&&) = delete;
83 ProfilingService& operator=(const ProfilingService&) = delete;
84 ProfilingService& operator=(ProfilingService&&) = delete;
Keith Davis02356de2019-08-26 18:28:17 +010085
Matteo Martincigh54fb9572019-10-02 12:50:57 +010086 // Initialization/reset functions
Matteo Martincigha84edee2019-10-02 12:50:57 +010087 void Initialize();
88 void InitializeCounterValue(uint16_t counterUid);
Matteo Martincigh54fb9572019-10-02 12:50:57 +010089 void Reset();
Jim Flynn53e46992019-10-14 12:31:10 +010090 void Stop();
Matteo Martincigha84edee2019-10-02 12:50:57 +010091
Matteo Martincighe8485382019-10-10 14:08:21 +010092 // Helper function
93 void CheckCounterUid(uint16_t counterUid) const;
94
Matteo Martincigh54fb9572019-10-02 12:50:57 +010095 // Profiling service components
Matteo Martincigha84edee2019-10-02 12:50:57 +010096 ExternalProfilingOptions m_Options;
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010097 CounterDirectory m_CounterDirectory;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010098 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
Matteo Martincigha84edee2019-10-02 12:50:57 +010099 IProfilingConnectionPtr m_ProfilingConnection;
100 ProfilingStateMachine m_StateMachine;
101 CounterIndices m_CounterIndex;
102 CounterValues m_CounterValues;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100103 CommandHandlerRegistry m_CommandHandlerRegistry;
104 PacketVersionResolver m_PacketVersionResolver;
105 CommandHandler m_CommandHandler;
106 BufferManager m_BufferManager;
107 SendCounterPacket m_SendCounterPacket;
Matteo Martincighe8485382019-10-10 14:08:21 +0100108 Holder m_Holder;
109 PeriodicCounterCapture m_PeriodicCounterCapture;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100110 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100111 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
Matteo Martincighe8485382019-10-10 14:08:21 +0100112 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
Matteo Martincigh994b5342019-10-11 17:19:56 +0100113 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100114 ProfilingGuidGenerator m_GuidGenerator;
Jim Flynn8b200652019-10-24 18:07:44 +0100115 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100116
117protected:
118 // Default constructor/destructor kept protected for testing
119 ProfilingService()
120 : m_Options()
121 , m_CounterDirectory()
122 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
123 , m_ProfilingConnection()
124 , m_StateMachine()
125 , m_CounterIndex()
126 , m_CounterValues()
127 , m_CommandHandlerRegistry()
128 , m_PacketVersionResolver()
129 , m_CommandHandler(1000,
130 false,
131 m_CommandHandlerRegistry,
132 m_PacketVersionResolver)
133 , m_BufferManager()
134 , m_SendCounterPacket(m_StateMachine, m_BufferManager)
Matteo Martincighe8485382019-10-10 14:08:21 +0100135 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this)
Jim Flynn397043f2019-10-17 17:37:10 +0100136 , m_ConnectionAcknowledgedCommandHandler(0,
137 1,
Jim Flynned25e0e2019-10-18 13:21:43 +0100138 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100139 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100140 , m_RequestCounterDirectoryCommandHandler(0,
141 3,
Jim Flynned25e0e2019-10-18 13:21:43 +0100142 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100143 m_CounterDirectory,
144 m_SendCounterPacket,
145 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100146 , m_PeriodicCounterSelectionCommandHandler(0,
147 4,
Jim Flynned25e0e2019-10-18 13:21:43 +0100148 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Matteo Martincighe8485382019-10-10 14:08:21 +0100149 m_Holder,
150 m_PeriodicCounterCapture,
151 *this,
152 m_SendCounterPacket,
153 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100154 , m_PerJobCounterSelectionCommandHandler(0,
155 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100156 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100157 m_StateMachine)
Jim Flynn8b200652019-10-24 18:07:44 +0100158 , m_TimelinePacketWriterFactory(m_BufferManager)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100159 {
160 // Register the "Connection Acknowledged" command handler
161 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100162
163 // Register the "Request Counter Directory" command handler
164 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100165
166 // Register the "Periodic Counter Selection" command handler
167 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100168
169 // Register the "Per-Job Counter Selection" command handler
170 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100171 }
172 ~ProfilingService() = default;
173
Matteo Martincighd0613b52019-10-09 16:47:04 +0100174 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100175 void SwapProfilingConnectionFactory(ProfilingService& instance,
176 IProfilingConnectionFactory* other,
177 IProfilingConnectionFactory*& backup)
178 {
179 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
180 BOOST_ASSERT(other);
181
182 backup = instance.m_ProfilingConnectionFactory.release();
183 instance.m_ProfilingConnectionFactory.reset(other);
184 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100185 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
186 {
187 return instance.m_ProfilingConnection.get();
188 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100189 void TransitionToState(ProfilingService& instance, ProfilingState newState)
190 {
191 instance.m_StateMachine.TransitionToState(newState);
192 }
Matteo Martincighe8485382019-10-10 14:08:21 +0100193 void WaitForPacketSent(ProfilingService& instance)
194 {
195 return instance.m_SendCounterPacket.WaitForPacketSent();
196 }
Keith Davis02356de2019-08-26 18:28:17 +0100197};
198
199} // namespace profiling
200
Matteo Martincigha84edee2019-10-02 12:50:57 +0100201} // namespace armnn