From 404b27569523f4cdd49752e7ae1633e359ba2190 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Tue, 24 Sep 2019 17:23:16 +0100 Subject: IVGCVSW-3902 Create IReadOnlyPacketBuffer, IPacketBuffer and IBufferManager interfaces * Create IReadOnlyPacketBuffer, IPacketBuffer and IBufferManager interfaces * Add Read and Write util functions that use IPacketBuffer * Add MockBufferManager using IBufferManager for testing * Modify SendCounterPacket to use IBufferManager * Modify MockStreamCounterBuffer to use IBufferManager * Remove IBufferWrapper and MockBuffer * Add MockPacketBuffer for testing * Modify unit tests to use the new interfaces Signed-off-by: Narumol Prangnawarat Change-Id: Ib86768187e032f07169aa39367a418b7665c9f03 --- src/profiling/IBufferManager.hpp | 36 ++++ src/profiling/IBufferWrapper.hpp | 30 ---- src/profiling/IPacketBuffer.hpp | 40 +++++ src/profiling/ProfilingUtils.cpp | 49 +++++ src/profiling/ProfilingUtils.hpp | 29 ++- src/profiling/SendCounterPacket.cpp | 44 +++-- src/profiling/SendCounterPacket.hpp | 22 ++- src/profiling/test/ProfilingTests.cpp | 26 ++- src/profiling/test/SendCounterPacketTests.cpp | 221 ++++++++++++----------- src/profiling/test/SendCounterPacketTests.hpp | 250 ++++++++++++++++---------- 10 files changed, 475 insertions(+), 272 deletions(-) create mode 100644 src/profiling/IBufferManager.hpp delete mode 100644 src/profiling/IBufferWrapper.hpp create mode 100644 src/profiling/IPacketBuffer.hpp (limited to 'src') diff --git a/src/profiling/IBufferManager.hpp b/src/profiling/IBufferManager.hpp new file mode 100644 index 0000000000..190d9c4542 --- /dev/null +++ b/src/profiling/IBufferManager.hpp @@ -0,0 +1,36 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "IPacketBuffer.hpp" + +#include + +namespace armnn +{ + +namespace profiling +{ + +class IBufferManager +{ +public: + virtual ~IBufferManager() {}; + + virtual std::unique_ptr Reserve(unsigned int requestedSize, unsigned int& reservedSize) = 0; + + virtual void Commit(std::unique_ptr& packetBuffer, unsigned int size) = 0; + + virtual void Release(std::unique_ptr& packetBuffer) = 0; + + virtual std::unique_ptr GetReadableBuffer() = 0; + + virtual void MarkRead(std::unique_ptr& packetBuffer) = 0; +}; + +} // namespace profiling + +} // namespace armnn diff --git a/src/profiling/IBufferWrapper.hpp b/src/profiling/IBufferWrapper.hpp deleted file mode 100644 index 9c38ab1dc8..0000000000 --- a/src/profiling/IBufferWrapper.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#pragma once - -namespace armnn -{ - -namespace profiling -{ - -class IBufferWrapper -{ -public: - virtual ~IBufferWrapper() {} - - virtual unsigned char* Reserve(unsigned int requestedSize, unsigned int& reservedSize) = 0; - - virtual void Commit(unsigned int size) = 0; - - virtual const unsigned char* GetReadBuffer(unsigned int& size) = 0; - - virtual void Release(unsigned int size) = 0; -}; - -} // namespace profiling - -} // namespace armnn diff --git a/src/profiling/IPacketBuffer.hpp b/src/profiling/IPacketBuffer.hpp new file mode 100644 index 0000000000..b4bd615bab --- /dev/null +++ b/src/profiling/IPacketBuffer.hpp @@ -0,0 +1,40 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +namespace armnn +{ + +namespace profiling +{ + +class IReadOnlyPacketBuffer // interface used by the read thread +{ +public: + virtual ~IReadOnlyPacketBuffer() {} + + virtual const unsigned char* const GetReadableData() const = 0; + + virtual unsigned int GetSize() const = 0; + + virtual void MarkRead() = 0; +}; + +class IPacketBuffer : public IReadOnlyPacketBuffer // interface used by code that writes binary packets +{ +public: + virtual ~IPacketBuffer() {} + + virtual void Commit(unsigned int size) = 0; + + virtual void Release() = 0; + + virtual unsigned char* GetWritableData() = 0; +}; + +} // namespace profiling + +} // namespace armnn \ No newline at end of file diff --git a/src/profiling/ProfilingUtils.cpp b/src/profiling/ProfilingUtils.cpp index 7a8c678054..588fcc11e4 100644 --- a/src/profiling/ProfilingUtils.cpp +++ b/src/profiling/ProfilingUtils.cpp @@ -87,6 +87,27 @@ std::vector GetNextCounterUids(uint16_t cores) return counterUids; } +void WriteUint64(const std::unique_ptr& packetBuffer, unsigned int offset, uint64_t value) +{ + BOOST_ASSERT(packetBuffer); + + WriteUint64(packetBuffer->GetWritableData(), offset, value); +} + +void WriteUint32(const std::unique_ptr& packetBuffer, unsigned int offset, uint32_t value) +{ + BOOST_ASSERT(packetBuffer); + + WriteUint32(packetBuffer->GetWritableData(), offset, value); +} + +void WriteUint16(const std::unique_ptr& packetBuffer, unsigned int offset, uint16_t value) +{ + BOOST_ASSERT(packetBuffer); + + WriteUint16(packetBuffer->GetWritableData(), offset, value); +} + void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value) { BOOST_ASSERT(buffer); @@ -119,6 +140,34 @@ void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value) buffer[offset + 1] = static_cast((value >> 8) & 0xFF); } +uint64_t ReadUint64(const std::unique_ptr& packetBuffer, unsigned int offset) +{ + BOOST_ASSERT(packetBuffer); + + return ReadUint64(packetBuffer->GetReadableData(), offset); +} + +uint32_t ReadUint32(const std::unique_ptr& packetBuffer, unsigned int offset) +{ + BOOST_ASSERT(packetBuffer); + + return ReadUint32(packetBuffer->GetReadableData(), offset); +} + +uint16_t ReadUint16(const std::unique_ptr& packetBuffer, unsigned int offset) +{ + BOOST_ASSERT(packetBuffer); + + return ReadUint16(packetBuffer->GetReadableData(), offset); +} + +uint8_t ReadUint8(const std::unique_ptr& packetBuffer, unsigned int offset) +{ + BOOST_ASSERT(packetBuffer); + + return ReadUint8(packetBuffer->GetReadableData(), offset); +} + uint64_t ReadUint64(const unsigned char* buffer, unsigned int offset) { BOOST_ASSERT(buffer); diff --git a/src/profiling/ProfilingUtils.hpp b/src/profiling/ProfilingUtils.hpp index fa96eea6e2..09b04f186f 100644 --- a/src/profiling/ProfilingUtils.hpp +++ b/src/profiling/ProfilingUtils.hpp @@ -7,12 +7,15 @@ #include +#include "IPacketBuffer.hpp" + #include -#include -#include #include #include +#include +#include +#include namespace armnn { @@ -80,19 +83,33 @@ uint16_t GetNextUid(bool peekOnly = false); std::vector GetNextCounterUids(uint16_t cores); +void WriteUint64(const std::unique_ptr& packetBuffer, unsigned int offset, uint64_t value); + +void WriteUint32(const std::unique_ptr& packetBuffer, unsigned int offset, uint32_t value); + +void WriteUint16(const std::unique_ptr& packetBuffer, unsigned int offset, uint16_t value); + void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value); void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value); void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value); -uint64_t ReadUint64(const unsigned char* buffer, unsigned int offset); +uint64_t ReadUint64(const std::unique_ptr& packetBuffer, unsigned int offset); + +uint32_t ReadUint32(const std::unique_ptr& packetBuffer, unsigned int offset); + +uint16_t ReadUint16(const std::unique_ptr& packetBuffer, unsigned int offset); + +uint8_t ReadUint8(const std::unique_ptr& packetBuffer, unsigned int offset); + +uint64_t ReadUint64(unsigned const char* buffer, unsigned int offset); -uint32_t ReadUint32(const unsigned char* buffer, unsigned int offset); +uint32_t ReadUint32(unsigned const char* buffer, unsigned int offset); -uint16_t ReadUint16(const unsigned char* buffer, unsigned int offset); +uint16_t ReadUint16(unsigned const char* buffer, unsigned int offset); -uint8_t ReadUint8(const unsigned char* buffer, unsigned int offset); +uint8_t ReadUint8(unsigned const char* buffer, unsigned int offset); std::string GetSoftwareInfo(); diff --git a/src/profiling/SendCounterPacket.cpp b/src/profiling/SendCounterPacket.cpp index b222270546..33eaeabc3e 100644 --- a/src/profiling/SendCounterPacket.cpp +++ b/src/profiling/SendCounterPacket.cpp @@ -65,11 +65,12 @@ void SendCounterPacket::SendStreamMetaDataPacket() uint32_t offset = 0; uint32_t reserved = 0; - unsigned char *writeBuffer = m_Buffer.Reserve(totalSize, reserved); + std::unique_ptr writeBuffer = m_BufferManager.Reserve(totalSize, reserved); if (reserved < totalSize) { CancelOperationAndThrow( + writeBuffer, boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize)); } @@ -120,25 +121,25 @@ void SendCounterPacket::SendStreamMetaDataPacket() if (infoSize) { - memcpy(&writeBuffer[offset], info.c_str(), infoSize); + memcpy(&writeBuffer->GetWritableData()[offset], info.c_str(), infoSize); offset += infoSize; } if (hardwareVersionSize) { - memcpy(&writeBuffer[offset], hardwareVersion.c_str(), hardwareVersionSize); + memcpy(&writeBuffer->GetWritableData()[offset], hardwareVersion.c_str(), hardwareVersionSize); offset += hardwareVersionSize; } if (softwareVersionSize) { - memcpy(&writeBuffer[offset], softwareVersion.c_str(), softwareVersionSize); + memcpy(&writeBuffer->GetWritableData()[offset], softwareVersion.c_str(), softwareVersionSize); offset += softwareVersionSize; } if (processNameSize) { - memcpy(&writeBuffer[offset], processName.c_str(), processNameSize); + memcpy(&writeBuffer->GetWritableData()[offset], processName.c_str(), processNameSize); offset += processNameSize; } @@ -170,10 +171,10 @@ void SendCounterPacket::SendStreamMetaDataPacket() } catch(...) { - CancelOperationAndThrow("Error processing packet."); + CancelOperationAndThrow(writeBuffer, "Error processing packet."); } - m_Buffer.Commit(totalSize); + m_BufferManager.Commit(writeBuffer, totalSize); } bool SendCounterPacket::CreateCategoryRecord(const CategoryPtr& category, @@ -792,12 +793,13 @@ void SendCounterPacket::SendCounterDirectoryPacket(const ICounterDirectory& coun // Reserve space in the buffer for the packet uint32_t reserved = 0; - unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved); + std::unique_ptr writeBuffer = m_BufferManager.Reserve(totalSize, reserved); // Check that the reserved buffer size is enough to hold the counter directory packet if (reserved < totalSize) { CancelOperationAndThrow( + writeBuffer, boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes") % totalSize)); } @@ -818,7 +820,7 @@ void SendCounterPacket::SendCounterDirectoryPacket(const ICounterDirectory& coun offset += numeric_cast(uint32_t_size); } - m_Buffer.Commit(totalSize); + m_BufferManager.Commit(writeBuffer, totalSize); } void SendCounterPacket::SendPeriodicCounterCapturePacket(uint64_t timestamp, const IndexValuePairsVector& values) @@ -833,11 +835,12 @@ void SendCounterPacket::SendPeriodicCounterCapturePacket(uint64_t timestamp, con uint32_t offset = 0; uint32_t reserved = 0; - unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved); + std::unique_ptr writeBuffer = m_BufferManager.Reserve(totalSize, reserved); if (reserved < totalSize) { CancelOperationAndThrow( + writeBuffer, boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize)); } @@ -868,7 +871,7 @@ void SendCounterPacket::SendPeriodicCounterCapturePacket(uint64_t timestamp, con offset += numeric_cast(sizeof(uint32_t)); } - m_Buffer.Commit(totalSize); + m_BufferManager.Commit(writeBuffer, totalSize); } void SendCounterPacket::SendPeriodicCounterSelectionPacket(uint32_t capturePeriod, @@ -883,11 +886,12 @@ void SendCounterPacket::SendPeriodicCounterSelectionPacket(uint32_t capturePerio uint32_t offset = 0; uint32_t reserved = 0; - unsigned char* writeBuffer = m_Buffer.Reserve(totalSize, reserved); + std::unique_ptr writeBuffer = m_BufferManager.Reserve(totalSize, reserved); if (reserved < totalSize) { CancelOperationAndThrow( + writeBuffer, boost::str(boost::format("No space left in buffer. Unable to reserve (%1%) bytes.") % totalSize)); } @@ -914,7 +918,7 @@ void SendCounterPacket::SendPeriodicCounterSelectionPacket(uint32_t capturePerio offset += numeric_cast(sizeof(uint16_t)); } - m_Buffer.Commit(totalSize); + m_BufferManager.Commit(writeBuffer, totalSize); } void SendCounterPacket::SetReadyToRead() @@ -973,9 +977,17 @@ void SendCounterPacket::Send() } // Wait condition lock scope - End + + + std::unique_ptr packetBuffer = m_BufferManager.GetReadableBuffer(); + if (packetBuffer == nullptr) + { + continue; + } + const unsigned char* readBuffer = packetBuffer->GetReadableData(); // Get the data to send from the buffer - unsigned int readBufferSize = 0; - const unsigned char* readBuffer = m_Buffer.GetReadBuffer(readBufferSize); + unsigned int readBufferSize = packetBuffer->GetSize(); + if (readBuffer == nullptr || readBufferSize == 0) { // Nothing to send, ignore and continue @@ -988,6 +1000,8 @@ void SendCounterPacket::Send() // Write a packet to the profiling connection. Silently ignore any write error and continue m_ProfilingConnection.WritePacket(readBuffer, boost::numeric_cast(readBufferSize)); } + + m_BufferManager.MarkRead(packetBuffer); } // Mark the send thread as not running diff --git a/src/profiling/SendCounterPacket.hpp b/src/profiling/SendCounterPacket.hpp index 8dd44ecd81..c57546d907 100644 --- a/src/profiling/SendCounterPacket.hpp +++ b/src/profiling/SendCounterPacket.hpp @@ -5,7 +5,7 @@ #pragma once -#include "IBufferWrapper.hpp" +#include "IBufferManager.hpp" #include "ISendCounterPacket.hpp" #include "ICounterDirectory.hpp" #include "IProfilingConnection.hpp" @@ -31,9 +31,9 @@ public: using IndexValuePairsVector = std::vector>; - SendCounterPacket(IProfilingConnection& profilingConnection, IBufferWrapper& buffer) + SendCounterPacket(IProfilingConnection& profilingConnection, IBufferManager& buffer) : m_ProfilingConnection(profilingConnection) - , m_Buffer(buffer) + , m_BufferManager(buffer) , m_IsRunning(false) , m_KeepRunning(false) {} @@ -63,15 +63,25 @@ private: template void CancelOperationAndThrow(const std::string& errorMessage) { - // Cancel the operation - m_Buffer.Commit(0); + // Throw a runtime exception with the given error message + throw ExceptionType(errorMessage); + } + + template + void CancelOperationAndThrow(std::unique_ptr& writerBuffer, const std::string& errorMessage) + { + if (writerBuffer != nullptr) + { + // Cancel the operation + m_BufferManager.Release(writerBuffer); + } // Throw a runtime exception with the given error message throw ExceptionType(errorMessage); } IProfilingConnection& m_ProfilingConnection; - IBufferWrapper& m_Buffer; + IBufferManager& m_BufferManager; std::mutex m_WaitMutex; std::condition_variable m_WaitCondition; std::thread m_SendThread; diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp index 1741160f96..a474c309e8 100644 --- a/src/profiling/test/ProfilingTests.cpp +++ b/src/profiling/test/ProfilingTests.cpp @@ -1756,7 +1756,7 @@ BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData) Holder holder; TestCaptureThread captureThread; MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(512); + MockBufferManager mockBuffer(512); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); uint32_t sizeOfUint32 = numeric_cast(sizeof(uint32_t)); @@ -1789,9 +1789,7 @@ BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData) BOOST_TEST(counterIds[0] == 4000); BOOST_TEST(counterIds[1] == 5000); - unsigned int size = 0; - - const unsigned char* readBuffer = mockBuffer.GetReadBuffer(size); + auto readBuffer = mockBuffer.GetReadableBuffer(); offset = 0; @@ -1814,6 +1812,8 @@ BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData) counterId = ReadUint16(readBuffer, offset); BOOST_TEST(counterId == 5000); + mockBuffer.MarkRead(readBuffer); + // Data with period only uint32_t period2 = 11; uint32_t dataLength2 = 4; @@ -1831,7 +1831,7 @@ BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData) BOOST_TEST(holder.GetCaptureData().GetCapturePeriod() == period2); BOOST_TEST(counterIds.size() == 0); - readBuffer = mockBuffer.GetReadBuffer(size); + readBuffer = mockBuffer.GetReadableBuffer(); offset = 0; @@ -2115,7 +2115,7 @@ BOOST_AUTO_TEST_CASE(CheckPeriodicCounterCaptureThread) std::vector captureIds2; MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(512); + MockBufferManager mockBuffer(512); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); std::vector counterIds; @@ -2146,9 +2146,7 @@ BOOST_AUTO_TEST_CASE(CheckPeriodicCounterCaptureThread) periodicCounterCapture.Join(); - unsigned int size = 0; - - const unsigned char* buffer = mockBuffer.GetReadBuffer(size); + auto buffer = mockBuffer.GetReadableBuffer(); uint32_t headerWord0 = ReadUint32(buffer, 0); uint32_t headerWord1 = ReadUint32(buffer, 4); @@ -2187,7 +2185,7 @@ BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest0) Packet packetA(packetId, 0, packetData); MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); CounterDirectory counterDirectory; @@ -2195,8 +2193,7 @@ BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest0) RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket); commandHandler(packetA); - unsigned int size = 0; - const unsigned char* readBuffer = mockBuffer.GetReadBuffer(size); + auto readBuffer = mockBuffer.GetReadableBuffer(); uint32_t headerWord0 = ReadUint32(readBuffer, 0); uint32_t headerWord1 = ReadUint32(readBuffer, 4); @@ -2222,7 +2219,7 @@ BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest1) Packet packetA(packetId, 0, packetData); MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); CounterDirectory counterDirectory; @@ -2235,8 +2232,7 @@ BOOST_AUTO_TEST_CASE(RequestCounterDirectoryCommandHandlerTest1) RequestCounterDirectoryCommandHandler commandHandler(packetId, version, counterDirectory, sendCounterPacket); commandHandler(packetA); - unsigned int size = 0; - const unsigned char* readBuffer = mockBuffer.GetReadBuffer(size); + auto readBuffer = mockBuffer.GetReadableBuffer(); uint32_t headerWord0 = ReadUint32(readBuffer, 0); uint32_t headerWord1 = ReadUint32(readBuffer, 4); diff --git a/src/profiling/test/SendCounterPacketTests.cpp b/src/profiling/test/SendCounterPacketTests.cpp index 3dda2e7b37..96596066c1 100644 --- a/src/profiling/test/SendCounterPacketTests.cpp +++ b/src/profiling/test/SendCounterPacketTests.cpp @@ -20,57 +20,61 @@ using namespace armnn::profiling; -size_t GetDataLength(const MockStreamCounterBuffer& mockStreamCounterBuffer, size_t packetOffset) -{ - // The data length is the written in the second byte - return ReadUint32(mockStreamCounterBuffer.GetBuffer(), - boost::numeric_cast(packetOffset + sizeof(uint32_t))); -} - -size_t GetPacketSize(const MockStreamCounterBuffer& mockStreamCounterBuffer, size_t packetOffset) -{ - // The packet size is the data length plus the size of the packet header (always two words big) - return GetDataLength(mockStreamCounterBuffer, packetOffset) + 2 * sizeof(uint32_t); -} - BOOST_AUTO_TEST_SUITE(SendCounterPacketTests) BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest) { - unsigned int size = 0; - - MockBuffer mockBuffer(512); + MockBufferManager mockBuffer(512); MockSendCounterPacket sendCounterPacket(mockBuffer); sendCounterPacket.SendStreamMetaDataPacket(); - const char* buffer = reinterpret_cast(mockBuffer.GetReadBuffer(size)); + + auto packetBuffer = mockBuffer.GetReadableBuffer(); + const char* buffer = reinterpret_cast(packetBuffer->GetReadableData()); BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0); + mockBuffer.MarkRead(packetBuffer); + CounterDirectory counterDirectory; sendCounterPacket.SendCounterDirectoryPacket(counterDirectory); + packetBuffer = mockBuffer.GetReadableBuffer(); + buffer = reinterpret_cast(packetBuffer->GetReadableData()); + BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0); + mockBuffer.MarkRead(packetBuffer); + uint64_t timestamp = 0; std::vector> indexValuePairs; sendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, indexValuePairs); + packetBuffer = mockBuffer.GetReadableBuffer(); + buffer = reinterpret_cast(packetBuffer->GetReadableData()); + BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0); + mockBuffer.MarkRead(packetBuffer); + uint32_t capturePeriod = 0; std::vector selectedCounterIds; sendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds); + packetBuffer = mockBuffer.GetReadableBuffer(); + buffer = reinterpret_cast(packetBuffer->GetReadableData()); + BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0); + + mockBuffer.MarkRead(packetBuffer); } BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest) { // Error no space left in buffer MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer1(10); + MockBufferManager mockBuffer1(10); SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1); uint32_t capturePeriod = 1000; @@ -79,12 +83,11 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest) BufferExhaustion); // Packet without any counters - MockBuffer mockBuffer2(512); + MockBufferManager mockBuffer2(512); SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2); sendPacket2.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds); - unsigned int sizeRead = 0; - const unsigned char* readBuffer2 = mockBuffer2.GetReadBuffer(sizeRead); + auto readBuffer2 = mockBuffer2.GetReadableBuffer(); uint32_t headerWord0 = ReadUint32(readBuffer2, 0); uint32_t headerWord1 = ReadUint32(readBuffer2, 4); @@ -96,7 +99,7 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest) BOOST_TEST(period == 1000); // capture period // Full packet message - MockBuffer mockBuffer3(512); + MockBufferManager mockBuffer3(512); SendCounterPacket sendPacket3(mockProfilingConnection, mockBuffer3); selectedCounterIds.reserve(5); @@ -106,8 +109,7 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterSelectionPacketTest) selectedCounterIds.emplace_back(400); selectedCounterIds.emplace_back(500); sendPacket3.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds); - sizeRead = 0; - const unsigned char* readBuffer3 = mockBuffer3.GetReadBuffer(sizeRead); + auto readBuffer3 = mockBuffer3.GetReadableBuffer(); headerWord0 = ReadUint32(readBuffer3, 0); headerWord1 = ReadUint32(readBuffer3, 4); @@ -134,7 +136,7 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest) { // Error no space left in buffer MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer1(10); + MockBufferManager mockBuffer1(10); SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1); auto captureTimestamp = std::chrono::steady_clock::now(); @@ -145,12 +147,11 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest) BufferExhaustion); // Packet without any counters - MockBuffer mockBuffer2(512); + MockBufferManager mockBuffer2(512); SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2); sendPacket2.SendPeriodicCounterCapturePacket(time, indexValuePairs); - unsigned int sizeRead = 0; - const unsigned char* readBuffer2 = mockBuffer2.GetReadBuffer(sizeRead); + auto readBuffer2 = mockBuffer2.GetReadableBuffer(); uint32_t headerWord0 = ReadUint32(readBuffer2, 0); uint32_t headerWord1 = ReadUint32(readBuffer2, 4); @@ -163,7 +164,7 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest) BOOST_TEST(time == readTimestamp); // capture period // Full packet message - MockBuffer mockBuffer3(512); + MockBufferManager mockBuffer3(512); SendCounterPacket sendPacket3(mockProfilingConnection, mockBuffer3); indexValuePairs.reserve(5); @@ -173,8 +174,7 @@ BOOST_AUTO_TEST_CASE(SendPeriodicCounterCapturePacketTest) indexValuePairs.emplace_back(std::make_pair(3, 400)); indexValuePairs.emplace_back(std::make_pair(4, 500)); sendPacket3.SendPeriodicCounterCapturePacket(time, indexValuePairs); - sizeRead = 0; - const unsigned char* readBuffer3 = mockBuffer3.GetReadBuffer(sizeRead); + auto readBuffer3 = mockBuffer3.GetReadableBuffer(); headerWord0 = ReadUint32(readBuffer3, 0); headerWord1 = ReadUint32(readBuffer3, 4); @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest) // Error no space left in buffer MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer1(10); + MockBufferManager mockBuffer1(10); SendCounterPacket sendPacket1(mockProfilingConnection, mockBuffer1); BOOST_CHECK_THROW(sendPacket1.SendStreamMetaDataPacket(), armnn::profiling::BufferExhaustion); @@ -235,11 +235,10 @@ BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest) uint32_t packetEntries = 6; - MockBuffer mockBuffer2(512); + MockBufferManager mockBuffer2(512); SendCounterPacket sendPacket2(mockProfilingConnection, mockBuffer2); sendPacket2.SendStreamMetaDataPacket(); - unsigned int sizeRead = 0; - const unsigned char* readBuffer2 = mockBuffer2.GetReadBuffer(sizeRead); + auto readBuffer2 = mockBuffer2.GetReadableBuffer(); uint32_t headerWord0 = ReadUint32(readBuffer2, 0); uint32_t headerWord1 = ReadUint32(readBuffer2, sizeUint32); @@ -279,28 +278,30 @@ BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest) offset += sizeUint32; BOOST_TEST(ReadUint32(readBuffer2, offset) == 0); // reserved + const unsigned char* readData2 = readBuffer2->GetReadableData(); + offset += sizeUint32; if (infoSize) { - BOOST_TEST(strcmp(reinterpret_cast(&readBuffer2[offset]), GetSoftwareInfo().c_str()) == 0); + BOOST_TEST(strcmp(reinterpret_cast(&readData2[offset]), GetSoftwareInfo().c_str()) == 0); offset += infoSize; } if (hardwareVersionSize) { - BOOST_TEST(strcmp(reinterpret_cast(&readBuffer2[offset]), GetHardwareVersion().c_str()) == 0); + BOOST_TEST(strcmp(reinterpret_cast(&readData2[offset]), GetHardwareVersion().c_str()) == 0); offset += hardwareVersionSize; } if (softwareVersionSize) { - BOOST_TEST(strcmp(reinterpret_cast(&readBuffer2[offset]), GetSoftwareVersion().c_str()) == 0); + BOOST_TEST(strcmp(reinterpret_cast(&readData2[offset]), GetSoftwareVersion().c_str()) == 0); offset += softwareVersionSize; } if (processNameSize) { - BOOST_TEST(strcmp(reinterpret_cast(&readBuffer2[offset]), GetProcessName().c_str()) == 0); + BOOST_TEST(strcmp(reinterpret_cast(&readData2[offset]), GetProcessName().c_str()) == 0); offset += processNameSize; } @@ -330,7 +331,7 @@ BOOST_AUTO_TEST_CASE(SendStreamMetaDataPacketTest) BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a device for testing @@ -363,7 +364,7 @@ BOOST_AUTO_TEST_CASE(CreateDeviceRecordTest) BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a device for testing @@ -385,7 +386,7 @@ BOOST_AUTO_TEST_CASE(CreateInvalidDeviceRecordTest) BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter set for testing @@ -418,7 +419,7 @@ BOOST_AUTO_TEST_CASE(CreateCounterSetRecordTest) BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter set for testing @@ -440,7 +441,7 @@ BOOST_AUTO_TEST_CASE(CreateInvalidCounterSetRecordTest) BOOST_AUTO_TEST_CASE(CreateEventRecordTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter for testing @@ -561,7 +562,7 @@ BOOST_AUTO_TEST_CASE(CreateEventRecordTest) BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter for testing @@ -665,7 +666,7 @@ BOOST_AUTO_TEST_CASE(CreateEventRecordNoUnitsTest) BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter for testing @@ -704,7 +705,7 @@ BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest1) BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter for testing @@ -743,7 +744,7 @@ BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest2) BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a counter for testing @@ -782,7 +783,7 @@ BOOST_AUTO_TEST_CASE(CreateInvalidEventRecordTest3) BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a category for testing @@ -984,7 +985,7 @@ BOOST_AUTO_TEST_CASE(CreateCategoryRecordTest) BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a category for testing @@ -1008,7 +1009,7 @@ BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest1) BOOST_AUTO_TEST_CASE(CreateInvalidCategoryRecordTest2) { MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(0); + MockBufferManager mockBuffer(0); SendCounterPacketTest sendCounterPacketTest(mockProfilingConnection, mockBuffer); // Create a category for testing @@ -1067,7 +1068,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest1) // Buffer with not enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(10); + MockBufferManager mockBuffer(10); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::profiling::BufferExhaustion); @@ -1160,13 +1161,12 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) // Buffer with enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_NO_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory)); - // Get the read buffer - unsigned int sizeRead = 0; - const unsigned char* readBuffer = mockBuffer.GetReadBuffer(sizeRead); + // Get the readable buffer + auto readBuffer = mockBuffer.GetReadableBuffer(); // Check the packet header uint32_t packetHeaderWord0 = ReadUint32(readBuffer, 0); @@ -1229,6 +1229,9 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) uint32_t deviceRecordsPointerTableOffset = 2u * uint32_t_size + // packet_header 6u * uint32_t_size + // body_header bodyHeaderWord1; // device_records_pointer_table_offset + + const unsigned char* readData = readBuffer->GetReadableData(); + for (uint32_t i = 0; i < deviceRecordCount; i++) { // Get the device record offset @@ -1255,7 +1258,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) BOOST_CHECK(deviceRecordNameNullTerminator == '\0'); std::vector deviceRecordNameBuffer(deviceRecord.name_length - 1); std::memcpy(deviceRecordNameBuffer.data(), - readBuffer + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size()); + readData + deviceRecordPoolOffset + uint32_t_size, deviceRecordNameBuffer.size()); deviceRecord.name.assign(deviceRecordNameBuffer.begin(), deviceRecordNameBuffer.end()); // name deviceRecords.push_back(deviceRecord); @@ -1312,7 +1315,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) BOOST_CHECK(counterSetRecordNameNullTerminator == '\0'); std::vector counterSetRecordNameBuffer(counterSetRecord.name_length - 1); std::memcpy(counterSetRecordNameBuffer.data(), - readBuffer + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size()); + readData + counterSetRecordPoolOffset + uint32_t_size, counterSetRecordNameBuffer.size()); counterSetRecord.name.assign(counterSetRecordNameBuffer.begin(), counterSetRecordNameBuffer.end()); // name counterSetRecords.push_back(counterSetRecord); @@ -1403,7 +1406,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) BOOST_CHECK(categoryRecordNameNullTerminator == '\0'); std::vector categoryRecordNameBuffer(categoryRecord.name_length - 1); std::memcpy(categoryRecordNameBuffer.data(), - readBuffer + + readData + categoryRecordPoolOffset + categoryRecord.name_offset + uint32_t_size, @@ -1462,7 +1465,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) BOOST_CHECK(eventRecordNameNullTerminator == '\0'); std::vector eventRecordNameBuffer(eventRecord.name_length - 1); std::memcpy(eventRecordNameBuffer.data(), - readBuffer + + readData + eventRecordPoolOffset + eventRecord.name_offset + uint32_t_size, @@ -1481,7 +1484,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) BOOST_CHECK(eventRecordDescriptionNullTerminator == '\0'); std::vector eventRecordDescriptionBuffer(eventRecord.description_length - 1); std::memcpy(eventRecordDescriptionBuffer.data(), - readBuffer + + readData + eventRecordPoolOffset + eventRecord.description_offset + uint32_t_size, @@ -1503,7 +1506,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest2) BOOST_CHECK(eventRecordUnitsNullTerminator == '\0'); std::vector eventRecordUnitsBuffer(eventRecord.units_length - 1); std::memcpy(eventRecordUnitsBuffer.data(), - readBuffer + + readData + eventRecordPoolOffset + eventRecord.units_offset + uint32_t_size, @@ -1560,7 +1563,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest3) // Buffer with enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException); } @@ -1579,7 +1582,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest4) // Buffer with enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException); } @@ -1598,7 +1601,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest5) // Buffer with enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException); } @@ -1633,7 +1636,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest6) // Buffer with enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException); } @@ -1683,7 +1686,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7) // Buffer with enough space MockProfilingConnection mockProfilingConnection; - MockBuffer mockBuffer(1024); + MockBufferManager mockBuffer(1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockBuffer); BOOST_CHECK_THROW(sendCounterPacket.SendCounterDirectoryPacket(counterDirectory), armnn::RuntimeException); } @@ -1691,7 +1694,7 @@ BOOST_AUTO_TEST_CASE(SendCounterDirectoryPacketTest7) BOOST_AUTO_TEST_CASE(SendThreadTest0) { MockProfilingConnection mockProfilingConnection; - MockStreamCounterBuffer mockStreamCounterBuffer(0); + MockStreamCounterBuffer mockStreamCounterBuffer(1, 0); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer); // Try to start the send thread many times, it must only start once @@ -1712,10 +1715,10 @@ BOOST_AUTO_TEST_CASE(SendThreadTest0) BOOST_AUTO_TEST_CASE(SendThreadTest1) { - size_t totalWrittenSize = 0; + unsigned int totalWrittenSize = 0; MockProfilingConnection mockProfilingConnection; - MockStreamCounterBuffer mockStreamCounterBuffer(100); + MockStreamCounterBuffer mockStreamCounterBuffer(5,1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer); sendCounterPacket.Start(); @@ -1728,7 +1731,10 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) sendCounterPacket.SendStreamMetaDataPacket(); // Get the size of the Stream Metadata Packet - size_t streamMetadataPacketsize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + std::string processName = GetProcessName().substr(0, 60); + unsigned int processNameSize = boost::numeric_cast(processName.size()) > 0 ? + boost::numeric_cast(processName.size()) + 1 : 0; + unsigned int streamMetadataPacketsize = 118 + processNameSize; totalWrittenSize += streamMetadataPacketsize; sendCounterPacket.SetReadyToRead(); @@ -1738,7 +1744,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) sendCounterPacket.SendCounterDirectoryPacket(counterDirectory); // Get the size of the Counter Directory Packet - size_t counterDirectoryPacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + unsigned int counterDirectoryPacketSize = 32; totalWrittenSize += counterDirectoryPacketSize; sendCounterPacket.SetReadyToRead(); @@ -1752,7 +1758,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) }); // Get the size of the Periodic Counter Capture Packet - size_t periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + unsigned int periodicCounterCapturePacketSize = 28; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -1765,7 +1771,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 22; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SendPeriodicCounterCapturePacket(1234u, @@ -1778,7 +1784,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 46; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SendPeriodicCounterCapturePacket(997u, @@ -1790,7 +1796,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 40; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -1800,28 +1806,28 @@ BOOST_AUTO_TEST_CASE(SendThreadTest1) sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 30; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); // To test an exact value of the "read size" in the mock buffer, wait a second to allow the send thread to // read all what's remaining in the buffer - std::this_thread::sleep_for(std::chrono::seconds(1)); + std::this_thread::sleep_for(std::chrono::seconds(2)); sendCounterPacket.Stop(); - BOOST_CHECK(mockStreamCounterBuffer.GetBufferSize() == totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadableBufferSize() == totalWrittenSize); BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize); - BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize); } BOOST_AUTO_TEST_CASE(SendThreadTest2) { - size_t totalWrittenSize = 0; + unsigned int totalWrittenSize = 0; MockProfilingConnection mockProfilingConnection; - MockStreamCounterBuffer mockStreamCounterBuffer(100); + MockStreamCounterBuffer mockStreamCounterBuffer(5, 1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer); sendCounterPacket.Start(); @@ -1836,7 +1842,10 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) sendCounterPacket.SendStreamMetaDataPacket(); // Get the size of the Stream Metadata Packet - size_t streamMetadataPacketsize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + std::string processName = GetProcessName().substr(0, 60); + unsigned int processNameSize = boost::numeric_cast(processName.size()) > 0 ? + boost::numeric_cast(processName.size()) + 1 : 0; + unsigned int streamMetadataPacketsize = 118 + processNameSize; totalWrittenSize += streamMetadataPacketsize; sendCounterPacket.SetReadyToRead(); @@ -1846,7 +1855,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) sendCounterPacket.SendCounterDirectoryPacket(counterDirectory); // Get the size of the Counter Directory Packet - size_t counterDirectoryPacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + unsigned int counterDirectoryPacketSize = 32; totalWrittenSize += counterDirectoryPacketSize; sendCounterPacket.SetReadyToRead(); @@ -1861,7 +1870,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) }); // Get the size of the Periodic Counter Capture Packet - size_t periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + unsigned int periodicCounterCapturePacketSize = 28; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -1881,7 +1890,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 22; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SendPeriodicCounterCapturePacket(1234u, @@ -1894,7 +1903,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 46; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -1907,7 +1916,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 40; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -1918,28 +1927,28 @@ BOOST_AUTO_TEST_CASE(SendThreadTest2) sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 30; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); // To test an exact value of the "read size" in the mock buffer, wait a second to allow the send thread to // read all what's remaining in the buffer - std::this_thread::sleep_for(std::chrono::seconds(1)); + std::this_thread::sleep_for(std::chrono::seconds(2)); sendCounterPacket.Stop(); - BOOST_CHECK(mockStreamCounterBuffer.GetBufferSize() == totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadableBufferSize() == totalWrittenSize); BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize); - BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() == totalWrittenSize); } BOOST_AUTO_TEST_CASE(SendThreadTest3) { - size_t totalWrittenSize = 0; + unsigned int totalWrittenSize = 0; MockProfilingConnection mockProfilingConnection; - MockStreamCounterBuffer mockStreamCounterBuffer(100); + MockStreamCounterBuffer mockStreamCounterBuffer(10, 1024); SendCounterPacket sendCounterPacket(mockProfilingConnection, mockStreamCounterBuffer); sendCounterPacket.Start(); @@ -1951,14 +1960,17 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) sendCounterPacket.SendStreamMetaDataPacket(); // Get the size of the Stream Metadata Packet - size_t streamMetadataPacketsize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + std::string processName = GetProcessName().substr(0, 60); + unsigned int processNameSize = boost::numeric_cast(processName.size()) > 0 ? + boost::numeric_cast(processName.size()) + 1 : 0; + unsigned int streamMetadataPacketsize = 118 + processNameSize; totalWrittenSize += streamMetadataPacketsize; sendCounterPacket.SetReadyToRead(); sendCounterPacket.SendCounterDirectoryPacket(counterDirectory); // Get the size of the Counter Directory Packet - size_t counterDirectoryPacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + unsigned int counterDirectoryPacketSize =32; totalWrittenSize += counterDirectoryPacketSize; sendCounterPacket.SetReadyToRead(); @@ -1970,7 +1982,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) }); // Get the size of the Periodic Counter Capture Packet - size_t periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + unsigned int periodicCounterCapturePacketSize = 28; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -1984,7 +1996,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 22; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SendPeriodicCounterCapturePacket(1234u, @@ -1997,7 +2009,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 46; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -2011,7 +2023,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 40; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -2019,7 +2031,7 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) sendCounterPacket.SendPeriodicCounterSelectionPacket(1000u, { 1345u, 254u, 4536u, 408u, 54u, 6323u, 428u, 1u, 6u }); // Get the size of the Periodic Counter Capture Packet - periodicCounterCapturePacketSize = GetPacketSize(mockStreamCounterBuffer, totalWrittenSize); + periodicCounterCapturePacketSize = 30; totalWrittenSize += periodicCounterCapturePacketSize; sendCounterPacket.SetReadyToRead(); @@ -2028,9 +2040,10 @@ BOOST_AUTO_TEST_CASE(SendThreadTest3) // thread is not guaranteed to flush the buffer) sendCounterPacket.Stop(); - BOOST_CHECK(mockStreamCounterBuffer.GetBufferSize() == totalWrittenSize); - BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() == totalWrittenSize); - BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadableBufferSize() <= totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetCommittedSize() <= totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= totalWrittenSize); + BOOST_CHECK(mockStreamCounterBuffer.GetReadSize() <= mockStreamCounterBuffer.GetCommittedSize()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/profiling/test/SendCounterPacketTests.hpp b/src/profiling/test/SendCounterPacketTests.hpp index 3616816ae2..c3d47157d0 100644 --- a/src/profiling/test/SendCounterPacketTests.hpp +++ b/src/profiling/test/SendCounterPacketTests.hpp @@ -42,15 +42,46 @@ private: bool m_IsOpen; }; -class MockBuffer : public IBufferWrapper +class MockPacketBuffer : public IPacketBuffer { public: - MockBuffer(unsigned int size) - : m_BufferSize(size) - , m_Buffer(std::make_unique(size)) - {} + MockPacketBuffer(unsigned int maxSize) + : m_MaxSize(maxSize), + m_Size(0) + { + m_Data = std::make_unique(m_MaxSize); + } + + ~MockPacketBuffer() {} + + const unsigned char* const GetReadableData() const override { return m_Data.get(); } + + unsigned int GetSize() const override { return m_Size; } + + void MarkRead() override { m_Size = 0;} + + void Commit(unsigned int size) override { m_Size = size; } + + void Release() override { m_Size = 0; } + + unsigned char* GetWritableData() override { return m_Data.get(); } + +private: + unsigned int m_MaxSize; + unsigned int m_Size; + std::unique_ptr m_Data; +}; - unsigned char* Reserve(unsigned int requestedSize, unsigned int& reservedSize) override +class MockBufferManager : public IBufferManager +{ +public: + MockBufferManager(unsigned int size) + : m_BufferSize(size), + m_Buffer(std::make_unique(size)) {} + + ~MockBufferManager() {} + + std::unique_ptr Reserve(unsigned int requestedSize, unsigned int& reservedSize) override { if (requestedSize > m_BufferSize) { @@ -61,145 +92,171 @@ public: reservedSize = requestedSize; } - return m_Buffer.get(); + return std::move(m_Buffer); + } + + void Commit(std::unique_ptr& packetBuffer, unsigned int size) override + { + packetBuffer->Commit(size); + m_Buffer = std::move(packetBuffer); } - void Commit(unsigned int size) override {} + std::unique_ptr GetReadableBuffer() override + { + return std::move(m_Buffer); + } - const unsigned char* GetReadBuffer(unsigned int& size) override + void Release(std::unique_ptr& packetBuffer) override { - size = static_cast(strlen(reinterpret_cast(m_Buffer.get())) + 1); - return m_Buffer.get(); + packetBuffer->Release(); + m_Buffer = std::move(packetBuffer); } - void Release(unsigned int size) override {} + void MarkRead(std::unique_ptr& packetBuffer) override + { + packetBuffer->MarkRead(); + m_Buffer = std::move(packetBuffer); + } private: unsigned int m_BufferSize; - std::unique_ptr m_Buffer; + std::unique_ptr m_Buffer; }; -class MockStreamCounterBuffer : public IBufferWrapper +class MockStreamCounterBuffer : public IBufferManager { public: - MockStreamCounterBuffer(unsigned int size) - : m_Buffer(size, 0) - , m_CommittedSize(0) - , m_ReadSize(0) - {} - - unsigned char* Reserve(unsigned int requestedSize, unsigned int& reservedSize) override + MockStreamCounterBuffer(unsigned int numberOfBuffers = 5, unsigned int maxPacketSize = 4096) + : m_MaxBufferSize(maxPacketSize) + , m_ReadableSize(0) + , m_CommittedSize(0) + , m_ReadSize(0) { - std::unique_lock(m_Mutex); + m_AvailableList.reserve(numberOfBuffers); + for (unsigned int i = 0; i < numberOfBuffers; ++i) + { + std::unique_ptr buffer = std::make_unique(maxPacketSize); + m_AvailableList.emplace_back(std::move(buffer)); + } + m_ReadableList.reserve(numberOfBuffers); + } - // Get the buffer size and the available size in the buffer past the committed size - size_t bufferSize = m_Buffer.size(); - size_t availableSize = bufferSize - m_CommittedSize; + ~MockStreamCounterBuffer() {} - // Check whether the buffer needs to be resized - if (requestedSize > availableSize) + std::unique_ptr Reserve(unsigned int requestedSize, unsigned int& reservedSize) override + { + std::unique_lock availableListLock(m_AvailableMutex, std::defer_lock); + if (requestedSize > m_MaxBufferSize) + { + throw armnn::Exception("Maximum buffer size that can be requested is [" + + std::to_string(m_MaxBufferSize) + "] bytes"); + } + availableListLock.lock(); + if (m_AvailableList.empty()) { - // Resize the buffer - size_t newSize = m_CommittedSize + requestedSize; - m_Buffer.resize(newSize, 0); + throw armnn::profiling::BufferExhaustion("Buffer not available"); } - - // Set the reserved size + std::unique_ptr buffer = std::move(m_AvailableList.back()); + m_AvailableList.pop_back(); + availableListLock.unlock(); reservedSize = requestedSize; - - // Get a pointer to the beginning of the part of buffer available for writing - return m_Buffer.data() + m_CommittedSize; + return buffer; } - void Commit(unsigned int size) override + void Commit(std::unique_ptr& packetBuffer, unsigned int size) override { - std::unique_lock(m_Mutex); - - // Update the committed size + std::unique_lock readableListLock(m_ReadableMutex, std::defer_lock); + packetBuffer.get()->Commit(size); + readableListLock.lock(); + m_ReadableList.push_back(std::move(packetBuffer)); + readableListLock.unlock(); + m_ReadDataAvailable.notify_one(); m_CommittedSize += size; } - const unsigned char* GetReadBuffer(unsigned int& size) override + void Release(std::unique_ptr& packetBuffer) override { - std::unique_lock(m_Mutex); - - // Get the size available for reading - size = boost::numeric_cast(m_CommittedSize - m_ReadSize); - - // Get a pointer to the beginning of the part of buffer available for reading - const unsigned char* readBuffer = m_Buffer.data() + m_ReadSize; - - // Update the read size - m_ReadSize = m_CommittedSize; - - return readBuffer; + std::unique_lock availableListLock(m_AvailableMutex, std::defer_lock); + packetBuffer.get()->Release(); + availableListLock.lock(); + m_AvailableList.push_back(std::move(packetBuffer)); + availableListLock.unlock(); + m_CommittedSize = 0; + m_ReadSize = 0; + m_ReadableSize = 0; } - void Release(unsigned int size) override + std::unique_ptr GetReadableBuffer() override { - std::unique_lock(m_Mutex); - - if (size == 0) + std::unique_lock readableListLock(m_ReadableMutex); + if (!m_ReadableList.empty()) { - // Nothing to release - return; + std::unique_ptr buffer = std::move(m_ReadableList.back()); + m_ReadableSize+=buffer->GetSize(); + m_ReadableList.pop_back(); + readableListLock.unlock(); + return buffer; } + return nullptr; + } - // Get the buffer size - size_t bufferSize = m_Buffer.size(); - - // Remove the last "size" bytes from the buffer - if (size < bufferSize) - { - // Resize the buffer - size_t newSize = bufferSize - size; - m_Buffer.resize(newSize); - } - else - { - // Clear the whole buffer - m_Buffer.clear(); - } + void MarkRead(std::unique_ptr& packetBuffer) override + { + std::unique_lock availableListLock(m_AvailableMutex, std::defer_lock); + // increase read size + m_ReadSize += packetBuffer->GetSize(); + packetBuffer->MarkRead(); + availableListLock.lock(); + m_AvailableList.push_back(std::move(packetBuffer)); + availableListLock.unlock(); } - size_t GetBufferSize() const { return m_Buffer.size(); } - size_t GetCommittedSize() const { return m_CommittedSize; } - size_t GetReadSize() const { return m_ReadSize; } - const unsigned char* GetBuffer() const { return m_Buffer.data(); } + unsigned int GetReadableBufferSize() const + { + return m_ReadableSize; + } + unsigned int GetCommittedSize() const { return m_CommittedSize; } + unsigned int GetReadSize() const { return m_ReadSize; } private: - // This mock uses an ever-expanding vector to simulate a counter stream buffer - std::vector m_Buffer; + unsigned int m_MaxBufferSize; + std::vector> m_AvailableList; + std::vector> m_ReadableList; + std::mutex m_AvailableMutex; + std::mutex m_ReadableMutex; + std::condition_variable m_ReadDataAvailable; + + // The size of the buffer that can be read + unsigned int m_ReadableSize; // The size of the buffer that has been committed for reading - size_t m_CommittedSize; + unsigned int m_CommittedSize; // The size of the buffer that has already been read - size_t m_ReadSize; - - // This mock buffer provides basic synchronization - std::mutex m_Mutex; + unsigned int m_ReadSize; }; class MockSendCounterPacket : public ISendCounterPacket { public: - MockSendCounterPacket(IBufferWrapper& sendBuffer) : m_Buffer(sendBuffer) {} + MockSendCounterPacket(IBufferManager& sendBuffer) : m_BufferManager(sendBuffer) {} void SendStreamMetaDataPacket() override { std::string message("SendStreamMetaDataPacket"); unsigned int reserved = 0; - unsigned char* buffer = m_Buffer.Reserve(1024, reserved); - memcpy(buffer, message.c_str(), static_cast(message.size()) + 1); + std::unique_ptr buffer = m_BufferManager.Reserve(1024, reserved); + memcpy(buffer->GetWritableData(), message.c_str(), static_cast(message.size()) + 1); + m_BufferManager.Commit(buffer, reserved); } void SendCounterDirectoryPacket(const ICounterDirectory& counterDirectory) override { std::string message("SendCounterDirectoryPacket"); unsigned int reserved = 0; - unsigned char* buffer = m_Buffer.Reserve(1024, reserved); - memcpy(buffer, message.c_str(), static_cast(message.size()) + 1); + std::unique_ptr buffer = m_BufferManager.Reserve(1024, reserved); + memcpy(buffer->GetWritableData(), message.c_str(), static_cast(message.size()) + 1); + m_BufferManager.Commit(buffer, reserved); } void SendPeriodicCounterCapturePacket(uint64_t timestamp, @@ -207,8 +264,9 @@ public: { std::string message("SendPeriodicCounterCapturePacket"); unsigned int reserved = 0; - unsigned char* buffer = m_Buffer.Reserve(1024, reserved); - memcpy(buffer, message.c_str(), static_cast(message.size()) + 1); + std::unique_ptr buffer = m_BufferManager.Reserve(1024, reserved); + memcpy(buffer->GetWritableData(), message.c_str(), static_cast(message.size()) + 1); + m_BufferManager.Commit(buffer, reserved); } void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod, @@ -216,15 +274,15 @@ public: { std::string message("SendPeriodicCounterSelectionPacket"); unsigned int reserved = 0; - unsigned char* buffer = m_Buffer.Reserve(1024, reserved); - memcpy(buffer, message.c_str(), static_cast(message.size()) + 1); - m_Buffer.Commit(reserved); + std::unique_ptr buffer = m_BufferManager.Reserve(1024, reserved); + memcpy(buffer->GetWritableData(), message.c_str(), static_cast(message.size()) + 1); + m_BufferManager.Commit(buffer, reserved); } void SetReadyToRead() override {} private: - IBufferWrapper& m_Buffer; + IBufferManager& m_BufferManager; }; class MockCounterDirectory : public ICounterDirectory @@ -434,7 +492,7 @@ private: class SendCounterPacketTest : public SendCounterPacket { public: - SendCounterPacketTest(IProfilingConnection& profilingconnection, IBufferWrapper& buffer) + SendCounterPacketTest(IProfilingConnection& profilingconnection, IBufferManager& buffer) : SendCounterPacket(profilingconnection, buffer) {} -- cgit v1.2.1