blob: f9b057c68b6a47c30a2efa9f13905aa60f3c6176 [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"
Matteo Martincighcdfb9412019-11-08 11:23:06 +000021#include "SendTimelinePacket.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010022#include "TimelinePacketWriterFactory.hpp"
Keith Davis02356de2019-08-26 18:28:17 +010023
24namespace armnn
25{
26
27namespace profiling
28{
29
Jim Flynn00f3aaf2019-10-24 11:58:06 +010030class ProfilingService : public IReadWriteCounterValues, public IProfilingGuidGenerator
Keith Davis02356de2019-08-26 18:28:17 +010031{
32public:
Narumol Prangnawarat85ad78c2019-11-18 15:34:23 +000033 using ExternalProfilingOptions = IRuntime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010034 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010035 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
36 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
37 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis02356de2019-08-26 18:28:17 +010038
Matteo Martincigha84edee2019-10-02 12:50:57 +010039 // Getter for the singleton instance
40 static ProfilingService& Instance()
41 {
42 static ProfilingService instance;
43 return instance;
44 }
45
46 // Resets the profiling options, optionally clears the profiling service entirely
47 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
Jim Flynn672d06e2019-10-15 10:18:11 +010048 ProfilingState ConfigureProfilingService(const ExternalProfilingOptions& options,
49 bool resetProfilingService = false);
50
Matteo Martincigha84edee2019-10-02 12:50:57 +010051
Matteo Martincigh54fb9572019-10-02 12:50:57 +010052 // Updates the profiling service, making it transition to a new state if necessary
53 void Update();
Keith Davis02356de2019-08-26 18:28:17 +010054
Jim Flynn53e46992019-10-14 12:31:10 +010055 // Disconnects the profiling service from the external server
56 void Disconnect();
57
Matteo Martincigha84edee2019-10-02 12:50:57 +010058 // Getters for the profiling service state
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010059 const ICounterDirectory& GetCounterDirectory() const;
Keith Davis02356de2019-08-26 18:28:17 +010060 ProfilingState GetCurrentState() const;
Matteo Martincighe8485382019-10-10 14:08:21 +010061 bool IsCounterRegistered(uint16_t counterUid) const override;
Matteo Martincigha84edee2019-10-02 12:50:57 +010062 uint16_t GetCounterCount() const override;
63 uint32_t GetCounterValue(uint16_t counterUid) const override;
Keith Davis02356de2019-08-26 18:28:17 +010064
Matteo Martincigha84edee2019-10-02 12:50:57 +010065 // Setters for the profiling service state
66 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
67 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
68 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
69 uint32_t IncrementCounterValue(uint16_t counterUid) override;
70 uint32_t DecrementCounterValue(uint16_t counterUid) override;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +010071
Jim Flynn00f3aaf2019-10-24 11:58:06 +010072 // IProfilingGuidGenerator functions
73 /// Return the next random Guid in the sequence
74 ProfilingDynamicGuid NextGuid() override;
75 /// Create a ProfilingStaticGuid based on a hash of the string
76 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
77
Jim Flynn8b200652019-10-24 18:07:44 +010078 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const;
79
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +000080 /// Check if the profiling is enabled
81 bool IsEnabled() { return m_Options.m_EnableProfiling; }
82
Keith Davis02356de2019-08-26 18:28:17 +010083private:
Matteo Martincigh54fb9572019-10-02 12:50:57 +010084 // Copy/move constructors/destructors and copy/move assignment operators are deleted
Matteo Martincigha84edee2019-10-02 12:50:57 +010085 ProfilingService(const ProfilingService&) = delete;
86 ProfilingService(ProfilingService&&) = delete;
87 ProfilingService& operator=(const ProfilingService&) = delete;
88 ProfilingService& operator=(ProfilingService&&) = delete;
Keith Davis02356de2019-08-26 18:28:17 +010089
Matteo Martincigh54fb9572019-10-02 12:50:57 +010090 // Initialization/reset functions
Matteo Martincigha84edee2019-10-02 12:50:57 +010091 void Initialize();
92 void InitializeCounterValue(uint16_t counterUid);
Matteo Martincigh54fb9572019-10-02 12:50:57 +010093 void Reset();
Jim Flynn53e46992019-10-14 12:31:10 +010094 void Stop();
Matteo Martincigha84edee2019-10-02 12:50:57 +010095
Matteo Martincighe8485382019-10-10 14:08:21 +010096 // Helper function
97 void CheckCounterUid(uint16_t counterUid) const;
98
Matteo Martincigh54fb9572019-10-02 12:50:57 +010099 // Profiling service components
Matteo Martincigha84edee2019-10-02 12:50:57 +0100100 ExternalProfilingOptions m_Options;
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100101 CounterDirectory m_CounterDirectory;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100102 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100103 IProfilingConnectionPtr m_ProfilingConnection;
104 ProfilingStateMachine m_StateMachine;
105 CounterIndices m_CounterIndex;
106 CounterValues m_CounterValues;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100107 CommandHandlerRegistry m_CommandHandlerRegistry;
108 PacketVersionResolver m_PacketVersionResolver;
109 CommandHandler m_CommandHandler;
110 BufferManager m_BufferManager;
111 SendCounterPacket m_SendCounterPacket;
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000112 SendTimelinePacket m_SendTimelinePacket;
Matteo Martincighe8485382019-10-10 14:08:21 +0100113 Holder m_Holder;
114 PeriodicCounterCapture m_PeriodicCounterCapture;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100115 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100116 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
Matteo Martincighe8485382019-10-10 14:08:21 +0100117 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
Matteo Martincigh994b5342019-10-11 17:19:56 +0100118 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100119 ProfilingGuidGenerator m_GuidGenerator;
Jim Flynn8b200652019-10-24 18:07:44 +0100120 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100121
122protected:
123 // Default constructor/destructor kept protected for testing
124 ProfilingService()
125 : m_Options()
126 , m_CounterDirectory()
127 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
128 , m_ProfilingConnection()
129 , m_StateMachine()
130 , m_CounterIndex()
131 , m_CounterValues()
132 , m_CommandHandlerRegistry()
133 , m_PacketVersionResolver()
134 , m_CommandHandler(1000,
135 false,
136 m_CommandHandlerRegistry,
137 m_PacketVersionResolver)
138 , m_BufferManager()
139 , m_SendCounterPacket(m_StateMachine, m_BufferManager)
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000140 , m_SendTimelinePacket(m_BufferManager)
Matteo Martincighe8485382019-10-10 14:08:21 +0100141 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this)
Jim Flynn397043f2019-10-17 17:37:10 +0100142 , m_ConnectionAcknowledgedCommandHandler(0,
143 1,
Jim Flynned25e0e2019-10-18 13:21:43 +0100144 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +0100145 m_CounterDirectory,
146 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000147 m_SendTimelinePacket,
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100148 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100149 , m_RequestCounterDirectoryCommandHandler(0,
150 3,
Jim Flynned25e0e2019-10-18 13:21:43 +0100151 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100152 m_CounterDirectory,
153 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +0000154 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100155 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100156 , m_PeriodicCounterSelectionCommandHandler(0,
157 4,
Jim Flynned25e0e2019-10-18 13:21:43 +0100158 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Matteo Martincighe8485382019-10-10 14:08:21 +0100159 m_Holder,
160 m_PeriodicCounterCapture,
161 *this,
162 m_SendCounterPacket,
163 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100164 , m_PerJobCounterSelectionCommandHandler(0,
165 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100166 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100167 m_StateMachine)
Jim Flynn8b200652019-10-24 18:07:44 +0100168 , m_TimelinePacketWriterFactory(m_BufferManager)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100169 {
170 // Register the "Connection Acknowledged" command handler
171 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100172
173 // Register the "Request Counter Directory" command handler
174 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100175
176 // Register the "Periodic Counter Selection" command handler
177 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100178
179 // Register the "Per-Job Counter Selection" command handler
180 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100181 }
182 ~ProfilingService() = default;
183
Matteo Martincighd0613b52019-10-09 16:47:04 +0100184 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100185 void SwapProfilingConnectionFactory(ProfilingService& instance,
186 IProfilingConnectionFactory* other,
187 IProfilingConnectionFactory*& backup)
188 {
189 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
190 BOOST_ASSERT(other);
191
192 backup = instance.m_ProfilingConnectionFactory.release();
193 instance.m_ProfilingConnectionFactory.reset(other);
194 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100195 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
196 {
197 return instance.m_ProfilingConnection.get();
198 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100199 void TransitionToState(ProfilingService& instance, ProfilingState newState)
200 {
201 instance.m_StateMachine.TransitionToState(newState);
202 }
Colm Donelan2ba48d22019-11-29 09:10:59 +0000203 void WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100204 {
Colm Donelan2ba48d22019-11-29 09:10:59 +0000205 return instance.m_SendCounterPacket.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100206 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000207
208 BufferManager& GetBufferManager(ProfilingService& instance)
209 {
210 return instance.m_BufferManager;
211 }
Keith Davis02356de2019-08-26 18:28:17 +0100212};
213
214} // namespace profiling
215
Matteo Martincigha84edee2019-10-02 12:50:57 +0100216} // namespace armnn