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 #include "SendTimelinePacket.hpp"
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker namespace arm
9*89c4ff92SAndroid Build Coastguard Worker {
10*89c4ff92SAndroid Build Coastguard Worker
11*89c4ff92SAndroid Build Coastguard Worker namespace pipe
12*89c4ff92SAndroid Build Coastguard Worker {
13*89c4ff92SAndroid Build Coastguard Worker
Commit()14*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::Commit()
15*89c4ff92SAndroid Build Coastguard Worker {
16*89c4ff92SAndroid Build Coastguard Worker if (m_WriteBuffer == nullptr)
17*89c4ff92SAndroid Build Coastguard Worker {
18*89c4ff92SAndroid Build Coastguard Worker // Can't commit from a null buffer
19*89c4ff92SAndroid Build Coastguard Worker return;
20*89c4ff92SAndroid Build Coastguard Worker }
21*89c4ff92SAndroid Build Coastguard Worker
22*89c4ff92SAndroid Build Coastguard Worker if (!m_DirectoryPackage)
23*89c4ff92SAndroid Build Coastguard Worker {
24*89c4ff92SAndroid Build Coastguard Worker // Datalength should be Offset minus the two header words
25*89c4ff92SAndroid Build Coastguard Worker m_PacketDataLength = m_Offset - m_uint32_t_size * 2;
26*89c4ff92SAndroid Build Coastguard Worker // Reset offset to prepend header with full packet datalength
27*89c4ff92SAndroid Build Coastguard Worker m_Offset = 0;
28*89c4ff92SAndroid Build Coastguard Worker
29*89c4ff92SAndroid Build Coastguard Worker // Add header before commit
30*89c4ff92SAndroid Build Coastguard Worker m_PacketHeader = CreateTimelinePacketHeader(1,0,1,0,0,m_PacketDataLength);
31*89c4ff92SAndroid Build Coastguard Worker
32*89c4ff92SAndroid Build Coastguard Worker // Write the timeline binary packet header to the buffer
33*89c4ff92SAndroid Build Coastguard Worker WriteUint32(m_WriteBuffer->GetWritableData(), m_Offset, m_PacketHeader.first);
34*89c4ff92SAndroid Build Coastguard Worker m_Offset += m_uint32_t_size;
35*89c4ff92SAndroid Build Coastguard Worker WriteUint32(m_WriteBuffer->GetWritableData(), m_Offset, m_PacketHeader.second);
36*89c4ff92SAndroid Build Coastguard Worker
37*89c4ff92SAndroid Build Coastguard Worker m_BufferManager.Commit(m_WriteBuffer, m_PacketDataLength + m_uint32_t_size * 2);
38*89c4ff92SAndroid Build Coastguard Worker
39*89c4ff92SAndroid Build Coastguard Worker }
40*89c4ff92SAndroid Build Coastguard Worker else
41*89c4ff92SAndroid Build Coastguard Worker {
42*89c4ff92SAndroid Build Coastguard Worker m_DirectoryPackage = false;
43*89c4ff92SAndroid Build Coastguard Worker m_BufferManager.Commit(m_WriteBuffer, m_Offset);
44*89c4ff92SAndroid Build Coastguard Worker }
45*89c4ff92SAndroid Build Coastguard Worker
46*89c4ff92SAndroid Build Coastguard Worker // Commit the message
47*89c4ff92SAndroid Build Coastguard Worker m_WriteBuffer.reset(nullptr);
48*89c4ff92SAndroid Build Coastguard Worker // Reset offset to start after prepended header
49*89c4ff92SAndroid Build Coastguard Worker m_Offset = 8;
50*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize = 0;
51*89c4ff92SAndroid Build Coastguard Worker }
52*89c4ff92SAndroid Build Coastguard Worker
ReserveBuffer()53*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::ReserveBuffer()
54*89c4ff92SAndroid Build Coastguard Worker {
55*89c4ff92SAndroid Build Coastguard Worker if (m_WriteBuffer != nullptr)
56*89c4ff92SAndroid Build Coastguard Worker {
57*89c4ff92SAndroid Build Coastguard Worker // Buffer already reserved
58*89c4ff92SAndroid Build Coastguard Worker return;
59*89c4ff92SAndroid Build Coastguard Worker }
60*89c4ff92SAndroid Build Coastguard Worker
61*89c4ff92SAndroid Build Coastguard Worker uint32_t reserved = 0;
62*89c4ff92SAndroid Build Coastguard Worker
63*89c4ff92SAndroid Build Coastguard Worker // Reserve the buffer
64*89c4ff92SAndroid Build Coastguard Worker m_WriteBuffer = m_BufferManager.Reserve(MAX_METADATA_PACKET_LENGTH, reserved);
65*89c4ff92SAndroid Build Coastguard Worker
66*89c4ff92SAndroid Build Coastguard Worker // Check if there is enough space in the buffer
67*89c4ff92SAndroid Build Coastguard Worker if (m_WriteBuffer == nullptr)
68*89c4ff92SAndroid Build Coastguard Worker {
69*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::BufferExhaustion("No free buffers left", LOCATION());
70*89c4ff92SAndroid Build Coastguard Worker }
71*89c4ff92SAndroid Build Coastguard Worker if (reserved < m_Offset)
72*89c4ff92SAndroid Build Coastguard Worker {
73*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::BufferExhaustion("Reserved space too small for use", LOCATION());
74*89c4ff92SAndroid Build Coastguard Worker }
75*89c4ff92SAndroid Build Coastguard Worker
76*89c4ff92SAndroid Build Coastguard Worker if (m_DirectoryPackage)
77*89c4ff92SAndroid Build Coastguard Worker {
78*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize = reserved;
79*89c4ff92SAndroid Build Coastguard Worker return;
80*89c4ff92SAndroid Build Coastguard Worker }
81*89c4ff92SAndroid Build Coastguard Worker // Account for the header size which is added at Commit()
82*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize = reserved - 8;
83*89c4ff92SAndroid Build Coastguard Worker }
84*89c4ff92SAndroid Build Coastguard Worker
SendTimelineEntityBinaryPacket(uint64_t profilingGuid)85*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::SendTimelineEntityBinaryPacket(uint64_t profilingGuid)
86*89c4ff92SAndroid Build Coastguard Worker {
87*89c4ff92SAndroid Build Coastguard Worker ForwardWriteBinaryFunction(WriteTimelineEntityBinary,
88*89c4ff92SAndroid Build Coastguard Worker profilingGuid);
89*89c4ff92SAndroid Build Coastguard Worker }
90*89c4ff92SAndroid Build Coastguard Worker
SendTimelineEventBinaryPacket(uint64_t timestamp,int threadId,uint64_t profilingGuid)91*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::SendTimelineEventBinaryPacket(uint64_t timestamp,
92*89c4ff92SAndroid Build Coastguard Worker int threadId,
93*89c4ff92SAndroid Build Coastguard Worker uint64_t profilingGuid)
94*89c4ff92SAndroid Build Coastguard Worker {
95*89c4ff92SAndroid Build Coastguard Worker ForwardWriteBinaryFunction(WriteTimelineEventBinary,
96*89c4ff92SAndroid Build Coastguard Worker timestamp,
97*89c4ff92SAndroid Build Coastguard Worker threadId,
98*89c4ff92SAndroid Build Coastguard Worker profilingGuid);
99*89c4ff92SAndroid Build Coastguard Worker }
100*89c4ff92SAndroid Build Coastguard Worker
SendTimelineEventClassBinaryPacket(uint64_t profilingGuid,uint64_t nameGuid)101*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::SendTimelineEventClassBinaryPacket(uint64_t profilingGuid, uint64_t nameGuid)
102*89c4ff92SAndroid Build Coastguard Worker {
103*89c4ff92SAndroid Build Coastguard Worker ForwardWriteBinaryFunction(WriteTimelineEventClassBinary,
104*89c4ff92SAndroid Build Coastguard Worker profilingGuid,
105*89c4ff92SAndroid Build Coastguard Worker nameGuid);
106*89c4ff92SAndroid Build Coastguard Worker }
107*89c4ff92SAndroid Build Coastguard Worker
SendTimelineLabelBinaryPacket(uint64_t profilingGuid,const std::string & label)108*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::SendTimelineLabelBinaryPacket(uint64_t profilingGuid, const std::string& label)
109*89c4ff92SAndroid Build Coastguard Worker {
110*89c4ff92SAndroid Build Coastguard Worker ForwardWriteBinaryFunction(WriteTimelineLabelBinaryPacket,
111*89c4ff92SAndroid Build Coastguard Worker profilingGuid,
112*89c4ff92SAndroid Build Coastguard Worker label);
113*89c4ff92SAndroid Build Coastguard Worker }
114*89c4ff92SAndroid Build Coastguard Worker
SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,uint64_t relationshipGuid,uint64_t headGuid,uint64_t tailGuid,uint64_t attributeGuid)115*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
116*89c4ff92SAndroid Build Coastguard Worker uint64_t relationshipGuid,
117*89c4ff92SAndroid Build Coastguard Worker uint64_t headGuid,
118*89c4ff92SAndroid Build Coastguard Worker uint64_t tailGuid,
119*89c4ff92SAndroid Build Coastguard Worker uint64_t attributeGuid)
120*89c4ff92SAndroid Build Coastguard Worker {
121*89c4ff92SAndroid Build Coastguard Worker ForwardWriteBinaryFunction(WriteTimelineRelationshipBinary,
122*89c4ff92SAndroid Build Coastguard Worker relationshipType,
123*89c4ff92SAndroid Build Coastguard Worker relationshipGuid,
124*89c4ff92SAndroid Build Coastguard Worker headGuid,
125*89c4ff92SAndroid Build Coastguard Worker tailGuid,
126*89c4ff92SAndroid Build Coastguard Worker attributeGuid);
127*89c4ff92SAndroid Build Coastguard Worker }
128*89c4ff92SAndroid Build Coastguard Worker
SendTimelineMessageDirectoryPackage()129*89c4ff92SAndroid Build Coastguard Worker void SendTimelinePacket::SendTimelineMessageDirectoryPackage()
130*89c4ff92SAndroid Build Coastguard Worker {
131*89c4ff92SAndroid Build Coastguard Worker try
132*89c4ff92SAndroid Build Coastguard Worker {
133*89c4ff92SAndroid Build Coastguard Worker // Flag to Reserve & Commit() that a DirectoryPackage is being sent
134*89c4ff92SAndroid Build Coastguard Worker m_DirectoryPackage = true;
135*89c4ff92SAndroid Build Coastguard Worker // Reserve buffer if it hasn't already been reserved
136*89c4ff92SAndroid Build Coastguard Worker ReserveBuffer();
137*89c4ff92SAndroid Build Coastguard Worker // Write to buffer
138*89c4ff92SAndroid Build Coastguard Worker unsigned int numberOfBytesWritten = 0;
139*89c4ff92SAndroid Build Coastguard Worker // Offset is initialised to 8
140*89c4ff92SAndroid Build Coastguard Worker m_Offset = 0;
141*89c4ff92SAndroid Build Coastguard Worker
142*89c4ff92SAndroid Build Coastguard Worker TimelinePacketStatus result = WriteTimelineMessageDirectoryPackage(&m_WriteBuffer->GetWritableData()[m_Offset],
143*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize,
144*89c4ff92SAndroid Build Coastguard Worker numberOfBytesWritten);
145*89c4ff92SAndroid Build Coastguard Worker if (result != TimelinePacketStatus::Ok)
146*89c4ff92SAndroid Build Coastguard Worker {
147*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException("Error processing TimelineMessageDirectoryPackage", LOCATION());
148*89c4ff92SAndroid Build Coastguard Worker }
149*89c4ff92SAndroid Build Coastguard Worker
150*89c4ff92SAndroid Build Coastguard Worker // Commit the message
151*89c4ff92SAndroid Build Coastguard Worker m_Offset += numberOfBytesWritten;
152*89c4ff92SAndroid Build Coastguard Worker m_RemainingBufferSize -= numberOfBytesWritten;
153*89c4ff92SAndroid Build Coastguard Worker Commit();
154*89c4ff92SAndroid Build Coastguard Worker }
155*89c4ff92SAndroid Build Coastguard Worker catch (...)
156*89c4ff92SAndroid Build Coastguard Worker {
157*89c4ff92SAndroid Build Coastguard Worker throw arm::pipe::ProfilingException("Error processing TimelineMessageDirectoryPackage", LOCATION());
158*89c4ff92SAndroid Build Coastguard Worker }
159*89c4ff92SAndroid Build Coastguard Worker }
160*89c4ff92SAndroid Build Coastguard Worker
161*89c4ff92SAndroid Build Coastguard Worker } // namespace pipe
162*89c4ff92SAndroid Build Coastguard Worker
163*89c4ff92SAndroid Build Coastguard Worker } // namespace arm
164