blob: c57546d907052e6b131be95fabbafaa2eb3a1056 [file] [log] [blame]
Ferran Balaguer73882172019-09-02 16:39:42 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Narumol Prangnawarat404b2752019-09-24 17:23:16 +01008#include "IBufferManager.hpp"
Ferran Balaguer73882172019-09-02 16:39:42 +01009#include "ISendCounterPacket.hpp"
Matteo Martincigh24e8f922019-09-19 11:57:46 +010010#include "ICounterDirectory.hpp"
11#include "IProfilingConnection.hpp"
12
13#include <atomic>
14#include <mutex>
15#include <thread>
16#include <condition_variable>
Ferran Balaguer73882172019-09-02 16:39:42 +010017
18namespace armnn
19{
20
21namespace profiling
22{
23
24class SendCounterPacket : public ISendCounterPacket
25{
26public:
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010027 using CategoryRecord = std::vector<uint32_t>;
28 using DeviceRecord = std::vector<uint32_t>;
29 using CounterSetRecord = std::vector<uint32_t>;
30 using EventRecord = std::vector<uint32_t>;
31
Francis Murtagh3a161982019-09-04 15:25:02 +010032 using IndexValuePairsVector = std::vector<std::pair<uint16_t, uint32_t>>;
33
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010034 SendCounterPacket(IProfilingConnection& profilingConnection, IBufferManager& buffer)
Matteo Martincigh24e8f922019-09-19 11:57:46 +010035 : m_ProfilingConnection(profilingConnection)
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010036 , m_BufferManager(buffer)
Matteo Martincigh24e8f922019-09-19 11:57:46 +010037 , m_IsRunning(false)
38 , m_KeepRunning(false)
Matteo Martincigh149528e2019-09-05 12:02:04 +010039 {}
Matteo Martincigh24e8f922019-09-19 11:57:46 +010040 ~SendCounterPacket() { Stop(); }
Ferran Balaguer73882172019-09-02 16:39:42 +010041
42 void SendStreamMetaDataPacket() override;
43
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010044 void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory) override;
Ferran Balaguer73882172019-09-02 16:39:42 +010045
Francis Murtagh3a161982019-09-04 15:25:02 +010046 void SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values) override;
Ferran Balaguer73882172019-09-02 16:39:42 +010047
48 void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
49 const std::vector<uint16_t>& selectedCounterIds) override;
50
51 void SetReadyToRead() override;
52
Ferran Balaguer47d0fe92019-09-04 16:47:34 +010053 static const unsigned int PIPE_MAGIC = 0x45495434;
54 static const unsigned int MAX_METADATA_PACKET_LENGTH = 4096;
55
Matteo Martincigh24e8f922019-09-19 11:57:46 +010056 void Start();
57 void Stop();
58 bool IsRunning() { return m_IsRunning.load(); }
59
Ferran Balaguer73882172019-09-02 16:39:42 +010060private:
Matteo Martincigh24e8f922019-09-19 11:57:46 +010061 void Send();
62
Matteo Martincigh149528e2019-09-05 12:02:04 +010063 template <typename ExceptionType>
64 void CancelOperationAndThrow(const std::string& errorMessage)
65 {
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010066 // Throw a runtime exception with the given error message
67 throw ExceptionType(errorMessage);
68 }
69
70 template <typename ExceptionType>
71 void CancelOperationAndThrow(std::unique_ptr<IPacketBuffer>& writerBuffer, const std::string& errorMessage)
72 {
73 if (writerBuffer != nullptr)
74 {
75 // Cancel the operation
76 m_BufferManager.Release(writerBuffer);
77 }
Matteo Martincigh149528e2019-09-05 12:02:04 +010078
79 // Throw a runtime exception with the given error message
80 throw ExceptionType(errorMessage);
81 }
82
Matteo Martincigh24e8f922019-09-19 11:57:46 +010083 IProfilingConnection& m_ProfilingConnection;
Narumol Prangnawarat404b2752019-09-24 17:23:16 +010084 IBufferManager& m_BufferManager;
Matteo Martincigh24e8f922019-09-19 11:57:46 +010085 std::mutex m_WaitMutex;
86 std::condition_variable m_WaitCondition;
87 std::thread m_SendThread;
88 std::atomic<bool> m_IsRunning;
89 std::atomic<bool> m_KeepRunning;
Matteo Martincigh42f9d9e2019-09-05 12:02:04 +010090
91protected:
92 // Helper methods, protected for testing
93 bool CreateCategoryRecord(const CategoryPtr& category,
94 const Counters& counters,
95 CategoryRecord& categoryRecord,
96 std::string& errorMessage);
97 bool CreateDeviceRecord(const DevicePtr& device,
98 DeviceRecord& deviceRecord,
99 std::string& errorMessage);
100 bool CreateCounterSetRecord(const CounterSetPtr& counterSet,
101 CounterSetRecord& counterSetRecord,
102 std::string& errorMessage);
103 bool CreateEventRecord(const CounterPtr& counter,
104 EventRecord& eventRecord,
105 std::string& errorMessage);
Ferran Balaguer73882172019-09-02 16:39:42 +0100106};
107
108} // namespace profiling
109
110} // namespace armnn