blob: d4fa85604cf7533eb5a7cb4325124fc71a5c9981 [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
8#include "ProfilingStateMachine.hpp"
9#include "ProfilingConnectionFactory.hpp"
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010010#include "CounterDirectory.hpp"
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010011#include "ICounterValues.hpp"
Matteo Martincigh54fb9572019-10-02 12:50:57 +010012#include "CommandHandler.hpp"
13#include "BufferManager.hpp"
14#include "SendCounterPacket.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010015#include "PeriodicCounterCapture.hpp"
Matteo Martincigh54fb9572019-10-02 12:50:57 +010016#include "ConnectionAcknowledgedCommandHandler.hpp"
Matteo Martincigh8efc5002019-10-10 14:30:29 +010017#include "RequestCounterDirectoryCommandHandler.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010018#include "PeriodicCounterSelectionCommandHandler.hpp"
Keith Davis02356de2019-08-26 18:28:17 +010019
20namespace armnn
21{
22
23namespace profiling
24{
25
Matteo Martincigh54fb9572019-10-02 12:50:57 +010026class ProfilingService : public IReadWriteCounterValues
Keith Davis02356de2019-08-26 18:28:17 +010027{
28public:
Matteo Martincigha84edee2019-10-02 12:50:57 +010029 using ExternalProfilingOptions = Runtime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010030 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010031 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
32 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
33 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis02356de2019-08-26 18:28:17 +010034
Matteo Martincigha84edee2019-10-02 12:50:57 +010035 // Getter for the singleton instance
36 static ProfilingService& Instance()
37 {
38 static ProfilingService instance;
39 return instance;
40 }
41
42 // Resets the profiling options, optionally clears the profiling service entirely
43 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
44
Matteo Martincigh54fb9572019-10-02 12:50:57 +010045 // Updates the profiling service, making it transition to a new state if necessary
46 void Update();
Keith Davis02356de2019-08-26 18:28:17 +010047
Jim Flynn53e46992019-10-14 12:31:10 +010048 // Disconnects the profiling service from the external server
49 void Disconnect();
50
Matteo Martincigha84edee2019-10-02 12:50:57 +010051 // Getters for the profiling service state
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010052 const ICounterDirectory& GetCounterDirectory() const;
Keith Davis02356de2019-08-26 18:28:17 +010053 ProfilingState GetCurrentState() const;
Matteo Martincighe8485382019-10-10 14:08:21 +010054 bool IsCounterRegistered(uint16_t counterUid) const override;
Matteo Martincigha84edee2019-10-02 12:50:57 +010055 uint16_t GetCounterCount() const override;
56 uint32_t GetCounterValue(uint16_t counterUid) const override;
Keith Davis02356de2019-08-26 18:28:17 +010057
Matteo Martincigha84edee2019-10-02 12:50:57 +010058 // Setters for the profiling service state
59 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
60 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
61 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
62 uint32_t IncrementCounterValue(uint16_t counterUid) override;
63 uint32_t DecrementCounterValue(uint16_t counterUid) override;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +010064
Keith Davis02356de2019-08-26 18:28:17 +010065private:
Matteo Martincigh54fb9572019-10-02 12:50:57 +010066 // Copy/move constructors/destructors and copy/move assignment operators are deleted
Matteo Martincigha84edee2019-10-02 12:50:57 +010067 ProfilingService(const ProfilingService&) = delete;
68 ProfilingService(ProfilingService&&) = delete;
69 ProfilingService& operator=(const ProfilingService&) = delete;
70 ProfilingService& operator=(ProfilingService&&) = delete;
Keith Davis02356de2019-08-26 18:28:17 +010071
Matteo Martincigh54fb9572019-10-02 12:50:57 +010072 // Initialization/reset functions
Matteo Martincigha84edee2019-10-02 12:50:57 +010073 void Initialize();
74 void InitializeCounterValue(uint16_t counterUid);
Matteo Martincigh54fb9572019-10-02 12:50:57 +010075 void Reset();
Jim Flynn53e46992019-10-14 12:31:10 +010076 void Stop();
Matteo Martincigha84edee2019-10-02 12:50:57 +010077
Matteo Martincighe8485382019-10-10 14:08:21 +010078 // Helper function
79 void CheckCounterUid(uint16_t counterUid) const;
80
Matteo Martincigh54fb9572019-10-02 12:50:57 +010081 // Profiling service components
Matteo Martincigha84edee2019-10-02 12:50:57 +010082 ExternalProfilingOptions m_Options;
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010083 CounterDirectory m_CounterDirectory;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010084 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
Matteo Martincigha84edee2019-10-02 12:50:57 +010085 IProfilingConnectionPtr m_ProfilingConnection;
86 ProfilingStateMachine m_StateMachine;
87 CounterIndices m_CounterIndex;
88 CounterValues m_CounterValues;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010089 CommandHandlerRegistry m_CommandHandlerRegistry;
90 PacketVersionResolver m_PacketVersionResolver;
91 CommandHandler m_CommandHandler;
92 BufferManager m_BufferManager;
93 SendCounterPacket m_SendCounterPacket;
Matteo Martincighe8485382019-10-10 14:08:21 +010094 Holder m_Holder;
95 PeriodicCounterCapture m_PeriodicCounterCapture;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010096 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
Matteo Martincigh8efc5002019-10-10 14:30:29 +010097 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
Matteo Martincighe8485382019-10-10 14:08:21 +010098 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010099
100protected:
101 // Default constructor/destructor kept protected for testing
102 ProfilingService()
103 : m_Options()
104 , m_CounterDirectory()
105 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
106 , m_ProfilingConnection()
107 , m_StateMachine()
108 , m_CounterIndex()
109 , m_CounterValues()
110 , m_CommandHandlerRegistry()
111 , m_PacketVersionResolver()
112 , m_CommandHandler(1000,
113 false,
114 m_CommandHandlerRegistry,
115 m_PacketVersionResolver)
116 , m_BufferManager()
117 , m_SendCounterPacket(m_StateMachine, m_BufferManager)
Matteo Martincighe8485382019-10-10 14:08:21 +0100118 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100119 , m_ConnectionAcknowledgedCommandHandler(1,
120 m_PacketVersionResolver.ResolvePacketVersion(1).GetEncodedValue(),
121 m_StateMachine)
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100122 , m_RequestCounterDirectoryCommandHandler(3,
123 m_PacketVersionResolver.ResolvePacketVersion(3).GetEncodedValue(),
124 m_CounterDirectory,
125 m_SendCounterPacket,
126 m_StateMachine)
Matteo Martincighe8485382019-10-10 14:08:21 +0100127 , m_PeriodicCounterSelectionCommandHandler(4,
128 m_PacketVersionResolver.ResolvePacketVersion(4).GetEncodedValue(),
129 m_Holder,
130 m_PeriodicCounterCapture,
131 *this,
132 m_SendCounterPacket,
133 m_StateMachine)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100134 {
135 // Register the "Connection Acknowledged" command handler
136 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100137
138 // Register the "Request Counter Directory" command handler
139 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100140
141 // Register the "Periodic Counter Selection" command handler
142 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100143 }
144 ~ProfilingService() = default;
145
Matteo Martincighd0613b52019-10-09 16:47:04 +0100146 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100147 void SwapProfilingConnectionFactory(ProfilingService& instance,
148 IProfilingConnectionFactory* other,
149 IProfilingConnectionFactory*& backup)
150 {
151 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
152 BOOST_ASSERT(other);
153
154 backup = instance.m_ProfilingConnectionFactory.release();
155 instance.m_ProfilingConnectionFactory.reset(other);
156 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100157 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
158 {
159 return instance.m_ProfilingConnection.get();
160 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100161 void TransitionToState(ProfilingService& instance, ProfilingState newState)
162 {
163 instance.m_StateMachine.TransitionToState(newState);
164 }
Matteo Martincighe8485382019-10-10 14:08:21 +0100165 void WaitForPacketSent(ProfilingService& instance)
166 {
167 return instance.m_SendCounterPacket.WaitForPacketSent();
168 }
Keith Davis02356de2019-08-26 18:28:17 +0100169};
170
171} // namespace profiling
172
Matteo Martincigha84edee2019-10-02 12:50:57 +0100173} // namespace armnn