blob: 12ac27333d3df0ff541af361562928f962950d62 [file] [log] [blame]
//
// Copyright © 2019 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#pragma once
#include <armnn/profiling/ILocalPacketHandler.hpp>
#include "DirectoryCaptureCommandHandler.hpp"
#include "IProfilingConnection.hpp"
#include "Packet.hpp"
#include "ProfilingUtils.hpp"
#include "Runtime.hpp"
#include <atomic>
#include <condition_variable>
#include <fstream>
#include <mutex>
#include <queue>
#include <thread>
namespace armnn
{
namespace profiling
{
enum class TargetEndianness
{
BeWire,
LeWire
};
enum class PackageActivity
{
StreamMetaData,
CounterDirectory,
Unknown
};
class FileOnlyProfilingConnection : public IProfilingConnection
{
public:
FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options,
const bool quietOp = true)
: m_Options(options)
, m_QuietOp(quietOp)
, m_Endianness(TargetEndianness::LeWire) // Set a sensible default. WaitForStreamMeta will set a real value.
, m_IsRunning(false)
, m_KeepRunning(false)
, m_Timeout(1000)
{
for (ILocalPacketHandlerSharedPtr localPacketHandler : options.m_LocalPacketHandlers)
{
AddLocalPacketHandler(localPacketHandler);
}
if (!options.m_LocalPacketHandlers.empty())
{
StartProcessingThread();
}
// NOTE: could add timeout to the external profiling options
};
~FileOnlyProfilingConnection();
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;
private:
void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
void StartProcessingThread();
void ClearReadableList();
void DispatchPacketToHandlers(const Packet& packet);
bool WaitForStreamMeta(const unsigned char* buffer, uint32_t length);
uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
void SendConnectionAck();
bool SendCounterSelectionPacket();
PackageActivity GetPackageActivity(const Packet& packet, uint32_t headerAsWords[2]);
void Fail(const std::string& errorMessage);
void ForwardPacketToHandlers(Packet& packet);
void ServiceLocalHandlers();
static const uint32_t PIPE_MAGIC = 0x45495434;
Runtime::CreationOptions::ExternalProfilingOptions m_Options;
bool m_QuietOp;
std::vector<uint16_t> m_IdList;
std::queue<Packet> m_PacketQueue;
TargetEndianness m_Endianness;
std::mutex m_PacketAvailableMutex;
std::condition_variable m_ConditionPacketAvailable;
std::vector<ILocalPacketHandlerSharedPtr> m_PacketHandlers;
std::map<uint32_t, std::vector<ILocalPacketHandlerSharedPtr>> m_IndexedHandlers;
std::vector<ILocalPacketHandlerSharedPtr> m_UniversalHandlers;
// List of readable packets for the local packet handlers
std::queue<Packet> 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<bool> m_IsRunning;
std::atomic<bool> m_KeepRunning;
int m_Timeout;
};
} // namespace profiling
} // namespace armnn