1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #pragma once
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker #include "IBufferManager.hpp"
9*89c4ff92SAndroid Build Coastguard Worker #include "ProfilingUtils.hpp"
10*89c4ff92SAndroid Build Coastguard Worker
11*89c4ff92SAndroid Build Coastguard Worker #include <client/include/ISendTimelinePacket.hpp>
12*89c4ff92SAndroid Build Coastguard Worker
13*89c4ff92SAndroid Build Coastguard Worker #include <common/include/Assert.hpp>
14*89c4ff92SAndroid Build Coastguard Worker
15*89c4ff92SAndroid Build Coastguard Worker #include <memory>
16*89c4ff92SAndroid Build Coastguard Worker
17*89c4ff92SAndroid Build Coastguard Worker namespace arm
18*89c4ff92SAndroid Build Coastguard Worker {
19*89c4ff92SAndroid Build Coastguard Worker
20*89c4ff92SAndroid Build Coastguard Worker namespace pipe
21*89c4ff92SAndroid Build Coastguard Worker {
22*89c4ff92SAndroid Build Coastguard Worker
23*89c4ff92SAndroid Build Coastguard Worker class SendTimelinePacket : public ISendTimelinePacket
24*89c4ff92SAndroid Build Coastguard Worker {
25*89c4ff92SAndroid Build Coastguard Worker public:
SendTimelinePacket(IBufferManager & bufferManager)26*89c4ff92SAndroid Build Coastguard Worker SendTimelinePacket(IBufferManager& bufferManager)
27*89c4ff92SAndroid Build Coastguard Worker : m_BufferManager(bufferManager)
28*89c4ff92SAndroid Build Coastguard Worker , m_WriteBuffer(nullptr)
29*89c4ff92SAndroid Build Coastguard Worker , m_Offset(8u)
30*89c4ff92SAndroid Build Coastguard Worker , m_RemainingBufferSize(0u)
31*89c4ff92SAndroid Build Coastguard Worker , m_PacketDataLength(0u)
32*89c4ff92SAndroid Build Coastguard Worker {}
33*89c4ff92SAndroid Build Coastguard Worker
34*89c4ff92SAndroid Build Coastguard Worker /// Commits the current buffer and reset the member variables
35*89c4ff92SAndroid Build Coastguard Worker void Commit() override;
36*89c4ff92SAndroid Build Coastguard Worker
37*89c4ff92SAndroid Build Coastguard Worker /// Create and write a TimelineEntityBinaryPacket from the parameters to the buffer.
38*89c4ff92SAndroid Build Coastguard Worker void SendTimelineEntityBinaryPacket(uint64_t profilingGuid) override;
39*89c4ff92SAndroid Build Coastguard Worker
40*89c4ff92SAndroid Build Coastguard Worker /// Create and write a TimelineEventBinaryPacket from the parameters to the buffer.
41*89c4ff92SAndroid Build Coastguard Worker void SendTimelineEventBinaryPacket(uint64_t timestamp, int threadId, uint64_t profilingGuid) override;
42*89c4ff92SAndroid Build Coastguard Worker
43*89c4ff92SAndroid Build Coastguard Worker /// Create and write a TimelineEventClassBinaryPacket from the parameters to the buffer.
44*89c4ff92SAndroid Build Coastguard Worker void SendTimelineEventClassBinaryPacket(uint64_t profilingGuid, uint64_t nameGuid) override;
45*89c4ff92SAndroid Build Coastguard Worker
46*89c4ff92SAndroid Build Coastguard Worker /// Create and write a TimelineLabelBinaryPacket from the parameters to the buffer.
47*89c4ff92SAndroid Build Coastguard Worker void SendTimelineLabelBinaryPacket(uint64_t profilingGuid, const std::string& label) override;
48*89c4ff92SAndroid Build Coastguard Worker
49*89c4ff92SAndroid Build Coastguard Worker /// Create and write a TimelineMessageDirectoryPackage in the buffer
50*89c4ff92SAndroid Build Coastguard Worker void SendTimelineMessageDirectoryPackage() override;
51*89c4ff92SAndroid Build Coastguard Worker
52*89c4ff92SAndroid Build Coastguard Worker /// Create and write a TimelineRelationshipBinaryPacket from the parameters to the buffer.
53*89c4ff92SAndroid Build Coastguard Worker virtual void SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
54*89c4ff92SAndroid Build Coastguard Worker uint64_t relationshipGuid,
55*89c4ff92SAndroid Build Coastguard Worker uint64_t headGuid,
56*89c4ff92SAndroid Build Coastguard Worker uint64_t tailGuid,
57*89c4ff92SAndroid Build Coastguard Worker uint64_t attributeGuid) override;
58*89c4ff92SAndroid Build Coastguard Worker private:
59*89c4ff92SAndroid Build Coastguard Worker /// Reserves maximum packet size from buffer
60*89c4ff92SAndroid Build Coastguard Worker void ReserveBuffer();
61*89c4ff92SAndroid Build Coastguard Worker
62*89c4ff92SAndroid Build Coastguard Worker template <typename Func, typename ... Params>
63*89c4ff92SAndroid Build Coastguard Worker void ForwardWriteBinaryFunction(Func& func, Params&& ... params);
64*89c4ff92SAndroid Build Coastguard Worker
65*89c4ff92SAndroid Build Coastguard Worker IBufferManager& m_BufferManager;
66*89c4ff92SAndroid Build Coastguard Worker IPacketBufferPtr m_WriteBuffer;
67*89c4ff92SAndroid Build Coastguard Worker unsigned int m_Offset;
68*89c4ff92SAndroid Build Coastguard Worker unsigned int m_RemainingBufferSize;
69*89c4ff92SAndroid Build Coastguard Worker
70*89c4ff92SAndroid Build Coastguard Worker const unsigned int m_uint32_t_size = sizeof(uint32_t);
71*89c4ff92SAndroid Build Coastguard Worker
72*89c4ff92SAndroid Build Coastguard Worker std::pair<uint32_t, uint32_t> m_PacketHeader;
73*89c4ff92SAndroid Build Coastguard Worker uint32_t m_PacketDataLength;
74*89c4ff92SAndroid Build Coastguard Worker
75*89c4ff92SAndroid Build Coastguard Worker bool m_DirectoryPackage = false;
76*89c4ff92SAndroid Build Coastguard Worker };
77*89c4ff92SAndroid Build Coastguard Worker
78*89c4ff92SAndroid Build Coastguard Worker template<typename Func, typename ... Params>
ForwardWriteBinaryFunction(Func & func,Params &&...params)79*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::ForwardWriteBinaryFunction(Func& func, Params&& ... params)
80*89c4ff92SAndroid Build Coastguard Worker {
81*89c4ff92SAndroid Build Coastguard Worker try
82*89c4ff92SAndroid Build Coastguard Worker {
83*89c4ff92SAndroid Build Coastguard Worker ReserveBuffer();
84*89c4ff92SAndroid Build Coastguard Worker ARM_PIPE_ASSERT(m_WriteBuffer);
85*89c4ff92SAndroid Build Coastguard Worker unsigned int numberOfBytesWritten = 0;
86*89c4ff92SAndroid Build Coastguard Worker // Header will be prepended to the buffer on Commit()
87*89c4ff92SAndroid Build Coastguard Worker while ( true )
88*89c4ff92SAndroid Build Coastguard Worker {
89*89c4ff92SAndroid Build Coastguard Worker TimelinePacketStatus result = func(std::forward<Params>(params)...,
90*89c4ff92SAndroid Build Coastguard Worker &m_WriteBuffer->GetWritableData()[m_Offset],
91*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize,
92*89c4ff92SAndroid Build Coastguard Worker numberOfBytesWritten);
93*89c4ff92SAndroid Build Coastguard Worker switch ( result )
94*89c4ff92SAndroid Build Coastguard Worker {
95*89c4ff92SAndroid Build Coastguard Worker case TimelinePacketStatus::BufferExhaustion:
96*89c4ff92SAndroid Build Coastguard Worker Commit();
97*89c4ff92SAndroid Build Coastguard Worker ReserveBuffer();
98*89c4ff92SAndroid Build Coastguard Worker continue;
99*89c4ff92SAndroid Build Coastguard Worker
100*89c4ff92SAndroid Build Coastguard Worker case TimelinePacketStatus::Error:
101*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException("Error processing while sending TimelineBinaryPacket",
102*89c4ff92SAndroid Build Coastguard Worker LOCATION());
103*89c4ff92SAndroid Build Coastguard Worker
104*89c4ff92SAndroid Build Coastguard Worker default:
105*89c4ff92SAndroid Build Coastguard Worker m_Offset += numberOfBytesWritten;
106*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize -= numberOfBytesWritten;
107*89c4ff92SAndroid Build Coastguard Worker return;
108*89c4ff92SAndroid Build Coastguard Worker }
109*89c4ff92SAndroid Build Coastguard Worker }
110*89c4ff92SAndroid Build Coastguard Worker }
111*89c4ff92SAndroid Build Coastguard Worker catch (const arm::pipe::BufferExhaustion& ex)
112*89c4ff92SAndroid Build Coastguard Worker {
113*89c4ff92SAndroid Build Coastguard Worker // ditto
114*89c4ff92SAndroid Build Coastguard Worker throw ex;
115*89c4ff92SAndroid Build Coastguard Worker }
116*89c4ff92SAndroid Build Coastguard Worker catch (const arm::pipe::ProfilingException& ex)
117*89c4ff92SAndroid Build Coastguard Worker {
118*89c4ff92SAndroid Build Coastguard Worker // don't swallow in the catch all block
119*89c4ff92SAndroid Build Coastguard Worker throw ex;
120*89c4ff92SAndroid Build Coastguard Worker }
121*89c4ff92SAndroid Build Coastguard Worker catch ( ... )
122*89c4ff92SAndroid Build Coastguard Worker {
123*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException("Unknown Exception thrown while sending TimelineBinaryPacket", LOCATION());
124*89c4ff92SAndroid Build Coastguard Worker }
125*89c4ff92SAndroid Build Coastguard Worker }
126*89c4ff92SAndroid Build Coastguard Worker
127*89c4ff92SAndroid Build Coastguard Worker } // namespace pipe
128*89c4ff92SAndroid Build Coastguard Worker
129*89c4ff92SAndroid Build Coastguard Worker } // namespace arm
130