// // Copyright © 2019 Arm Ltd. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include "DirectoryCaptureCommandHandler.hpp" #include "IProfilingConnection.hpp" #include #include "ProfilingUtils.hpp" #include "Runtime.hpp" #include #include #include #include #include #include namespace armnn { namespace profiling { // forward declaration class FileOnlyProfilingConnection; class StreamMetaDataProcessor : public ILocalPacketHandler { public: explicit StreamMetaDataProcessor(FileOnlyProfilingConnection* fileOnlyProfilingConnection) : m_FileOnlyProfilingConnection(fileOnlyProfilingConnection), m_MetaDataPacketHeader(ConstructHeader(0, 0)) {}; std::vector GetHeadersAccepted() override; void HandlePacket(const Packet& packet) override; private: FileOnlyProfilingConnection* m_FileOnlyProfilingConnection; uint32_t m_MetaDataPacketHeader; static uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness); }; class FileOnlyProfilingConnection : public IProfilingConnection, public IInternalProfilingConnection { public: explicit FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options) : m_Options(options) , m_Endianness(TargetEndianness::LeWire) // Set a sensible default. // StreamMetaDataProcessor will set a real value. , m_IsRunning(false) , m_KeepRunning(false) , m_Timeout(1000) { // add the StreamMetaDataProcessor auto streamMetaDataProcessor = std::make_shared(this); AddLocalPacketHandler(streamMetaDataProcessor); // and any additional ones added by the users for (const ILocalPacketHandlerSharedPtr& localPacketHandler : options.m_LocalPacketHandlers) { AddLocalPacketHandler(localPacketHandler); } if (!m_PacketHandlers.empty()) { StartProcessingThread(); } // NOTE: could add timeout to the external profiling options }; ~FileOnlyProfilingConnection() override; bool IsOpen() const override; void Close() override; // This is effectively receiving a data packet from ArmNN. bool WritePacket(const unsigned char* buffer, uint32_t length) override; // Sending a packet back to ArmNN. Packet ReadPacket(uint32_t timeout) override; void SetEndianess(const TargetEndianness& endianness) override //IInternalProfilingConnection { m_Endianness = endianness; } void ReturnPacket(Packet& packet) override; //IInternalProfilingConnection private: void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler); void StartProcessingThread(); void ClearReadableList(); void DispatchPacketToHandlers(const Packet& packet); void Fail(const std::string& errorMessage); void ForwardPacketToHandlers(Packet& packet); void ServiceLocalHandlers(); Runtime::CreationOptions::ExternalProfilingOptions m_Options; std::queue m_PacketQueue; TargetEndianness m_Endianness; std::mutex m_PacketAvailableMutex; std::condition_variable m_ConditionPacketAvailable; std::vector m_PacketHandlers; std::map> m_IndexedHandlers; std::vector m_UniversalHandlers; // List of readable packets for the local packet handlers std::queue m_ReadableList; // Mutex and condition variable for the readable packet list std::mutex m_ReadableMutex; std::condition_variable m_ConditionPacketReadable; // thread that takes items from the readable list and dispatches them // to the handlers. std::thread m_LocalHandlersThread; // atomic booleans that control the operation of the local handlers thread std::atomic m_IsRunning; std::atomic m_KeepRunning; int m_Timeout; }; } // namespace profiling } // namespace armnn