diff options
Diffstat (limited to 'profiling/client/src/ProfilingService.hpp')
-rw-r--r-- | profiling/client/src/ProfilingService.hpp | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/profiling/client/src/ProfilingService.hpp b/profiling/client/src/ProfilingService.hpp new file mode 100644 index 0000000000..b84b39d0df --- /dev/null +++ b/profiling/client/src/ProfilingService.hpp @@ -0,0 +1,304 @@ +// +// Copyright © 2019 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "ActivateTimelineReportingCommandHandler.hpp" +#include "BufferManager.hpp" +#include "CommandHandler.hpp" +#include "ConnectionAcknowledgedCommandHandler.hpp" +#include "DeactivateTimelineReportingCommandHandler.hpp" +#include "INotifyBackends.hpp" +#include "PeriodicCounterCapture.hpp" +#include "PeriodicCounterSelectionCommandHandler.hpp" +#include "PerJobCounterSelectionCommandHandler.hpp" +#include "ProfilingConnectionFactory.hpp" +#include "ProfilingStateMachine.hpp" +#include "RequestCounterDirectoryCommandHandler.hpp" +#include "SendCounterPacket.hpp" +#include "SendThread.hpp" +#include "SendTimelinePacket.hpp" +#include "TimelinePacketWriterFactory.hpp" + +#include <client/include/CounterIdMap.hpp> +#include <client/include/ICounterValues.hpp> +#include <client/include/ILocalPacketHandler.hpp> +#include <client/include/IProfilingService.hpp> +#include <client/include/IReportStructure.hpp> + +#include <client/include/backends/IBackendProfilingContext.hpp> + +#include <common/include/CounterDirectory.hpp> + +#include <list> + +namespace arm +{ + +namespace pipe +{ + +class ProfilingService : public IProfilingService, public INotifyBackends +{ +public: + using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>; + using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>; + using CounterIndices = std::vector<std::atomic<uint32_t>*>; + using CounterValues = std::list<std::atomic<uint32_t>>; + using BackendProfilingContext = std::unordered_map<std::string, + std::shared_ptr<IBackendProfilingContext>>; + + 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()) + : m_Options() + , m_TimelineReporting(false) + , m_ProfilingConnectionFactory(new ProfilingConnectionFactory()) + , m_ProfilingConnection() + , m_StateMachine() + , m_CounterIndex() + , m_CounterValues() + , m_CommandHandlerRegistry() + , m_PacketVersionResolver() + , m_CommandHandler(1000, + false, + m_CommandHandlerRegistry, + m_PacketVersionResolver) + , m_BufferManager() + , m_SendCounterPacket(m_BufferManager, softwareInfo, softwareVersion, hardwareVersion) + , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket) + , m_SendTimelinePacket(m_BufferManager) + , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts) + , m_ConnectionAcknowledgedCommandHandler(0, + 1, + m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(), + m_CounterDirectory, + m_SendCounterPacket, + m_SendTimelinePacket, + m_StateMachine, + *this, + m_BackendProfilingContexts) + , m_RequestCounterDirectoryCommandHandler(0, + 3, + m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(), + m_CounterDirectory, + m_SendCounterPacket, + m_SendTimelinePacket, + m_StateMachine) + , m_PeriodicCounterSelectionCommandHandler(0, + 4, + m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(), + m_BackendProfilingContexts, + m_CounterIdMap, + m_Holder, + maxGlobalCounterId, + m_PeriodicCounterCapture, + *this, + m_SendCounterPacket, + m_StateMachine) + , m_PerJobCounterSelectionCommandHandler(0, + 5, + m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(), + m_StateMachine) + , m_ActivateTimelineReportingCommandHandler(0, + 6, + m_PacketVersionResolver.ResolvePacketVersion(0, 6) + .GetEncodedValue(), + m_SendTimelinePacket, + m_StateMachine, + reportStructure, + m_TimelineReporting, + *this, + *this) + , m_DeactivateTimelineReportingCommandHandler(0, + 7, + m_PacketVersionResolver.ResolvePacketVersion(0, 7) + .GetEncodedValue(), + m_TimelineReporting, + m_StateMachine, + *this) + , m_TimelinePacketWriterFactory(m_BufferManager) + , m_MaxGlobalCounterId(maxGlobalCounterId) + , m_ServiceActive(false) + , m_Initialiser(initialiser) + { + // Register the "Connection Acknowledged" command handler + m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler); + + // Register the "Request Counter Directory" command handler + m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler); + + // Register the "Periodic Counter Selection" command handler + m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler); + + // Register the "Per-Job Counter Selection" command handler + m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler); + + m_CommandHandlerRegistry.RegisterFunctor(&m_ActivateTimelineReportingCommandHandler); + + m_CommandHandlerRegistry.RegisterFunctor(&m_DeactivateTimelineReportingCommandHandler); + } + + ~ProfilingService(); + + // Resets the profiling options, optionally clears the profiling service entirely + void ResetExternalProfilingOptions(const ProfilingOptions& options, + bool resetProfilingService = false) override; + ProfilingState ConfigureProfilingService(const ProfilingOptions& options, + bool resetProfilingService = false) override; + + + // Updates the profiling service, making it transition to a new state if necessary + void Update(); + + // Disconnects the profiling service from the external server + void Disconnect() override; + + // Store a profiling context returned from a backend that support profiling. + void AddBackendProfilingContext(const std::string& backendId, + std::shared_ptr<IBackendProfilingContext> profilingContext) override; + + // Enable the recording of timeline events and entities + void NotifyBackendsForTimelineReporting() override; + + const ICounterDirectory& GetCounterDirectory() const; + ICounterRegistry& GetCounterRegistry() override; + ProfilingState GetCurrentState() const override; + bool IsCounterRegistered(uint16_t counterUid) const override; + uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override; + uint32_t GetDeltaCounterValue(uint16_t counterUid) override; + uint16_t GetCounterCount() const override; + // counter global/backend mapping functions + const ICounterMappings& GetCounterMappings() const override; + IRegisterCounterMapping& GetCounterMappingRegistry() override; + bool IsCategoryRegistered(const std::string& categoryName) const override; + bool IsCounterRegistered(const std::string& counterName) const override; + + // Getters for the profiling service state + bool IsProfilingEnabled() const override; + + CaptureData GetCaptureData() override; + void SetCaptureData(uint32_t capturePeriod, + const std::vector<uint16_t>& counterIds, + const std::set<std::string>& activeBackends); + + // Setters for the profiling service state + void SetCounterValue(uint16_t counterUid, uint32_t value) override; + uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override; + uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override; + uint32_t IncrementCounterValue(uint16_t counterUid) override; + + void InitializeCounterValue(uint16_t counterUid) override; + + std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override; + + ISendCounterPacket& GetSendCounterPacket() override + { + return m_SendCounterPacket; + } + + bool IsTimelineReportingEnabled() const override + { + return m_TimelineReporting; + } + + void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler); + + void NotifyProfilingServiceActive() override; // IProfilingServiceStatus + void WaitForProfilingServiceActivation(unsigned int timeout) override; // IProfilingServiceStatus + +private: + //Copy/move constructors/destructors and copy/move assignment operators are deleted + ProfilingService(const ProfilingService&) = delete; + ProfilingService(ProfilingService&&) = delete; + ProfilingService& operator=(const ProfilingService&) = delete; + ProfilingService& operator=(ProfilingService&&) = delete; + + // Initialization/reset functions + void Initialize(); + void Reset(); + void Stop(); + + // Helper function + void CheckCounterUid(uint16_t counterUid) const; + + // Profiling service components + ProfilingOptions m_Options; + std::atomic<bool> m_TimelineReporting; + CounterDirectory m_CounterDirectory; + CounterIdMap m_CounterIdMap; + IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory; + IProfilingConnectionPtr m_ProfilingConnection; + ProfilingStateMachine m_StateMachine; + CounterIndices m_CounterIndex; + CounterValues m_CounterValues; + arm::pipe::CommandHandlerRegistry m_CommandHandlerRegistry; + arm::pipe::PacketVersionResolver m_PacketVersionResolver; + CommandHandler m_CommandHandler; + BufferManager m_BufferManager; + SendCounterPacket m_SendCounterPacket; + SendThread m_SendThread; + SendTimelinePacket m_SendTimelinePacket; + + Holder m_Holder; + + PeriodicCounterCapture m_PeriodicCounterCapture; + + ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler; + RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler; + PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler; + PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler; + ActivateTimelineReportingCommandHandler m_ActivateTimelineReportingCommandHandler; + DeactivateTimelineReportingCommandHandler m_DeactivateTimelineReportingCommandHandler; + + TimelinePacketWriterFactory m_TimelinePacketWriterFactory; + BackendProfilingContext m_BackendProfilingContexts; + uint16_t m_MaxGlobalCounterId; + + // Signalling to let external actors know when service is active or not + std::mutex m_ServiceActiveMutex; + std::condition_variable m_ServiceActiveConditionVariable; + bool m_ServiceActive; + + IInitialiseProfilingService& m_Initialiser; + +protected: + + // Protected methods for testing + void SwapProfilingConnectionFactory(ProfilingService& instance, + IProfilingConnectionFactory* other, + IProfilingConnectionFactory*& backup) + { + ARM_PIPE_ASSERT(instance.m_ProfilingConnectionFactory); + ARM_PIPE_ASSERT(other); + + backup = instance.m_ProfilingConnectionFactory.release(); + instance.m_ProfilingConnectionFactory.reset(other); + } + IProfilingConnection* GetProfilingConnection(ProfilingService& instance) + { + return instance.m_ProfilingConnection.get(); + } + void TransitionToState(ProfilingService& instance, ProfilingState newState) + { + instance.m_StateMachine.TransitionToState(newState); + } + bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000) + { + return instance.m_SendThread.WaitForPacketSent(timeout); + } + + BufferManager& GetBufferManager(ProfilingService& instance) + { + return instance.m_BufferManager; + } +}; + +} // namespace pipe + +} // namespace arm |