blob: 2ca5f5470bcfd0e375696a887ef4ab1f66b77f8e [file] [log] [blame]
//
// Copyright © 2019 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include "SendTimelinePacket.hpp"
namespace armnn
{
namespace profiling
{
void SendTimelinePacket::Commit()
{
if (m_WriteBuffer == nullptr)
{
// Can't commit from a null buffer
return;
}
if (!m_DirectoryPackage)
{
// Datalength should be Offset minus the two header words
m_PacketDataLength = m_Offset - m_uint32_t_size * 2;
// Reset offset to prepend header with full packet datalength
m_Offset = 0;
// Add header before commit
m_PacketHeader = CreateTimelinePacketHeader(1,0,1,0,0,m_PacketDataLength);
// Write the timeline binary packet header to the buffer
WriteUint32(m_WriteBuffer->GetWritableData(), m_Offset, m_PacketHeader.first);
m_Offset += m_uint32_t_size;
WriteUint32(m_WriteBuffer->GetWritableData(), m_Offset, m_PacketHeader.second);
m_BufferManager.Commit(m_WriteBuffer, m_PacketDataLength + m_uint32_t_size * 2);
}
else
{
m_DirectoryPackage = false;
m_BufferManager.Commit(m_WriteBuffer, m_Offset);
}
// Commit the message
m_WriteBuffer.reset(nullptr);
// Reset offset to start after prepended header
m_Offset = 8;
m_RemainingBufferSize = 0;
}
void SendTimelinePacket::ReserveBuffer()
{
if (m_WriteBuffer != nullptr)
{
// Buffer already reserved
return;
}
uint32_t reserved = 0;
// Reserve the buffer
m_WriteBuffer = m_BufferManager.Reserve(MAX_METADATA_PACKET_LENGTH, reserved);
// Check if there is enough space in the buffer
if (m_WriteBuffer == nullptr)
{
throw BufferExhaustion("No free buffers left", CHECK_LOCATION());
}
if (reserved < m_Offset)
{
throw BufferExhaustion("Reserved space too small for use", CHECK_LOCATION());
}
if (m_DirectoryPackage)
{
m_RemainingBufferSize = reserved;
return;
}
// Account for the header size which is added at Commit()
m_RemainingBufferSize = reserved - 8;
}
void SendTimelinePacket::SendTimelineEntityBinaryPacket(uint64_t profilingGuid)
{
ForwardWriteBinaryFunction(WriteTimelineEntityBinary,
profilingGuid);
}
void SendTimelinePacket::SendTimelineEventBinaryPacket(uint64_t timestamp,
std::thread::id threadId,
uint64_t profilingGuid)
{
ForwardWriteBinaryFunction(WriteTimelineEventBinary,
timestamp,
threadId,
profilingGuid);
}
void SendTimelinePacket::SendTimelineEventClassBinaryPacket(uint64_t profilingGuid, uint64_t nameGuid)
{
ForwardWriteBinaryFunction(WriteTimelineEventClassBinary,
profilingGuid,
nameGuid);
}
void SendTimelinePacket::SendTimelineLabelBinaryPacket(uint64_t profilingGuid, const std::string& label)
{
ForwardWriteBinaryFunction(WriteTimelineLabelBinaryPacket,
profilingGuid,
label);
}
void SendTimelinePacket::SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType relationshipType,
uint64_t relationshipGuid,
uint64_t headGuid,
uint64_t tailGuid,
uint64_t attributeGuid)
{
ForwardWriteBinaryFunction(WriteTimelineRelationshipBinary,
relationshipType,
relationshipGuid,
headGuid,
tailGuid,
attributeGuid);
}
void SendTimelinePacket::SendTimelineMessageDirectoryPackage()
{
try
{
// Flag to Reserve & Commit() that a DirectoryPackage is being sent
m_DirectoryPackage = true;
// Reserve buffer if it hasn't already been reserved
ReserveBuffer();
// Write to buffer
unsigned int numberOfBytesWritten = 0;
// Offset is initialised to 8
m_Offset = 0;
TimelinePacketStatus result = WriteTimelineMessageDirectoryPackage(&m_WriteBuffer->GetWritableData()[m_Offset],
m_RemainingBufferSize,
numberOfBytesWritten);
if (result != armnn::profiling::TimelinePacketStatus::Ok)
{
throw RuntimeException("Error processing TimelineMessageDirectoryPackage", CHECK_LOCATION());
}
// Commit the message
m_Offset += numberOfBytesWritten;
m_RemainingBufferSize -= numberOfBytesWritten;
Commit();
}
catch (...)
{
throw RuntimeException("Error processing TimelineMessageDirectoryPackage", CHECK_LOCATION());
}
}
} // namespace profiling
} // namespace armnn