From bbfe603e5ae42317a2b67d713d00882bea341c88 Mon Sep 17 00:00:00 2001 From: Jim Flynn Date: Mon, 20 Jul 2020 16:57:44 +0100 Subject: IVGCVSW-5166 Pull out the common and server side code into standalone libraries Change-Id: I180f84c493a9b2be4b93b25d312ebdd9e71b1735 Signed-off-by: Jim Flynn --- profiling/common/src/CMakeLists.txt | 30 +++++ profiling/common/src/CommandHandlerFunctor.cpp | 31 +++++ profiling/common/src/CommandHandlerKey.cpp | 77 +++++++++++++ profiling/common/src/CommandHandlerRegistry.cpp | 61 ++++++++++ profiling/common/src/CommonProfilingUtils.cpp | 145 ++++++++++++++++++++++++ profiling/common/src/NetworkSockets.cpp | 51 ++++++--- profiling/common/src/PacketVersionResolver.cpp | 71 ++++++++++++ profiling/common/src/SwTrace.cpp | 128 +++++++++++++++++++++ 8 files changed, 576 insertions(+), 18 deletions(-) create mode 100644 profiling/common/src/CMakeLists.txt create mode 100644 profiling/common/src/CommandHandlerFunctor.cpp create mode 100644 profiling/common/src/CommandHandlerKey.cpp create mode 100644 profiling/common/src/CommandHandlerRegistry.cpp create mode 100644 profiling/common/src/CommonProfilingUtils.cpp create mode 100644 profiling/common/src/PacketVersionResolver.cpp create mode 100644 profiling/common/src/SwTrace.cpp (limited to 'profiling/common/src') diff --git a/profiling/common/src/CMakeLists.txt b/profiling/common/src/CMakeLists.txt new file mode 100644 index 0000000000..9505fb8869 --- /dev/null +++ b/profiling/common/src/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +# SPDX-License-Identifier: MIT +# + +if(BUILD_TIMELINE_DECODER) + set(pipeCommon_sources) + list(APPEND pipeCommon_sources + CommandHandlerFunctor.cpp + CommandHandlerKey.cpp + CommandHandlerRegistry.cpp + CommonProfilingUtils.cpp + NetworkSockets.cpp + PacketVersionResolver.cpp + SwTrace.cpp) + + include_directories(${PROJECT_SOURCE_DIR}/profiling/common/include) + include_directories(${PROJECT_SOURCE_DIR}/common/include) + + if(BUILD_UNIT_TESTS) + include_directories(${PROJECT_SOURCE_DIR}/src/profiling + ${PROJECT_SOURCE_DIR}/src/armnnUtils) + target_include_directories(UnitTests PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include) + endif() + + # will only build a static version of this common code + # to simplify the build. No extra .so file to deploy to boards etc. + add_library_ex(pipeCommon STATIC ${pipeCommon_sources}) + +endif() diff --git a/profiling/common/src/CommandHandlerFunctor.cpp b/profiling/common/src/CommandHandlerFunctor.cpp new file mode 100644 index 0000000000..ea24cfb34e --- /dev/null +++ b/profiling/common/src/CommandHandlerFunctor.cpp @@ -0,0 +1,31 @@ +// +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "CommandHandlerFunctor.hpp" + +namespace arm +{ + +namespace pipe +{ + +uint32_t CommandHandlerFunctor::GetFamilyId() const +{ + return m_FamilyId; +} + +uint32_t CommandHandlerFunctor::GetPacketId() const +{ + return m_PacketId; +} + +uint32_t CommandHandlerFunctor::GetVersion() const +{ + return m_Version; +} + +} // namespace pipe + +} // namespace arm diff --git a/profiling/common/src/CommandHandlerKey.cpp b/profiling/common/src/CommandHandlerKey.cpp new file mode 100644 index 0000000000..98e4567348 --- /dev/null +++ b/profiling/common/src/CommandHandlerKey.cpp @@ -0,0 +1,77 @@ +// +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "CommandHandlerKey.hpp" + +namespace arm +{ + +namespace pipe +{ + +uint32_t CommandHandlerKey::GetFamilyId() const +{ + return m_FamilyId; +} + +uint32_t CommandHandlerKey::GetPacketId() const +{ + return m_PacketId; +} + +uint32_t CommandHandlerKey::GetVersion() const +{ + return m_Version; +} + +bool CommandHandlerKey::operator<(const CommandHandlerKey& rhs) const +{ + bool result = true; + if (m_FamilyId == rhs.m_FamilyId) + { + if (m_PacketId == rhs.m_PacketId) + { + result = m_Version < rhs.m_Version; + } + else if (m_PacketId > rhs.m_PacketId) + { + result = false; + } + } + else if (m_FamilyId > rhs.m_FamilyId) + { + result = false; + } + return result; +} + +bool CommandHandlerKey::operator>(const CommandHandlerKey& rhs) const +{ + return rhs < *this; +} + +bool CommandHandlerKey::operator<=(const CommandHandlerKey& rhs) const +{ + return !(*this > rhs); +} + +bool CommandHandlerKey::operator>=(const CommandHandlerKey& rhs) const +{ + return !(*this < rhs); +} + +bool CommandHandlerKey::operator==(const CommandHandlerKey& rhs) const +{ + return m_FamilyId == rhs.m_FamilyId && m_PacketId == rhs.m_PacketId && m_Version == rhs.m_Version; +} + +bool CommandHandlerKey::operator!=(const CommandHandlerKey& rhs) const +{ + return !(*this == rhs); +} + +} // namespace pipe + +} // namespace arm diff --git a/profiling/common/src/CommandHandlerRegistry.cpp b/profiling/common/src/CommandHandlerRegistry.cpp new file mode 100644 index 0000000000..324737eda5 --- /dev/null +++ b/profiling/common/src/CommandHandlerRegistry.cpp @@ -0,0 +1,61 @@ +// +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + + +#include +#include + +#include + +namespace arm +{ + +namespace pipe +{ + +void CommandHandlerRegistry::RegisterFunctor(CommandHandlerFunctor* functor, + uint32_t familyId, + uint32_t packetId, + uint32_t version) +{ + ARM_PIPE_ASSERT_MSG(functor, "Provided functor should not be a nullptr"); + + CommandHandlerKey key(familyId, packetId, version); + registry[key] = functor; +} + +void CommandHandlerRegistry::RegisterFunctor(CommandHandlerFunctor* functor) +{ + ARM_PIPE_ASSERT_MSG(functor, "Provided functor should not be a nullptr"); + + RegisterFunctor(functor, functor->GetFamilyId(), functor->GetPacketId(), functor->GetVersion()); +} + +CommandHandlerFunctor* CommandHandlerRegistry::GetFunctor(uint32_t familyId,uint32_t packetId, uint32_t version) const +{ + CommandHandlerKey key(familyId, packetId, version); + + // Check that the requested key exists + if (registry.find(key) == registry.end()) + { + std::stringstream ss; + ss << "Functor with requested PacketId=" << packetId << " and Version=" << version << " does not exist"; + throw ProfilingException(ss.str()); + } + + CommandHandlerFunctor* commandHandlerFunctor = registry.at(key); + if (commandHandlerFunctor == nullptr) + { + std::stringstream ss; + ss << "Invalid functor registered for PacketId=" << packetId << " and Version=" << version; + throw ProfilingException(ss.str()); + } + + return commandHandlerFunctor; +} + +} // namespace pipe + +} // namespace arm diff --git a/profiling/common/src/CommonProfilingUtils.cpp b/profiling/common/src/CommonProfilingUtils.cpp new file mode 100644 index 0000000000..fe98e0aaa9 --- /dev/null +++ b/profiling/common/src/CommonProfilingUtils.cpp @@ -0,0 +1,145 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include +#include + +#include + +namespace arm +{ + +namespace pipe +{ +void ReadBytes(const unsigned char* buffer, unsigned int offset, unsigned int valueSize, uint8_t outValue[]) +{ + ARM_PIPE_ASSERT(buffer); + ARM_PIPE_ASSERT(outValue); + + for (unsigned int i = 0; i < valueSize; i++, offset++) + { + outValue[i] = static_cast(buffer[offset]); + } +} + +uint64_t ReadUint64(const unsigned char* buffer, unsigned int offset) +{ + ARM_PIPE_ASSERT(buffer); + + uint64_t value = 0; + value = static_cast(buffer[offset]); + value |= static_cast(buffer[offset + 1]) << 8; + value |= static_cast(buffer[offset + 2]) << 16; + value |= static_cast(buffer[offset + 3]) << 24; + value |= static_cast(buffer[offset + 4]) << 32; + value |= static_cast(buffer[offset + 5]) << 40; + value |= static_cast(buffer[offset + 6]) << 48; + value |= static_cast(buffer[offset + 7]) << 56; + + return value; +} + +uint32_t ReadUint32(const unsigned char* buffer, unsigned int offset) +{ + ARM_PIPE_ASSERT(buffer); + + uint32_t value = 0; + value = static_cast(buffer[offset]); + value |= static_cast(buffer[offset + 1]) << 8; + value |= static_cast(buffer[offset + 2]) << 16; + value |= static_cast(buffer[offset + 3]) << 24; + return value; +} + +uint16_t ReadUint16(const unsigned char* buffer, unsigned int offset) +{ + ARM_PIPE_ASSERT(buffer); + + uint32_t value = 0; + value = static_cast(buffer[offset]); + value |= static_cast(buffer[offset + 1]) << 8; + return static_cast(value); +} + +uint8_t ReadUint8(const unsigned char* buffer, unsigned int offset) +{ + ARM_PIPE_ASSERT(buffer); + + return buffer[offset]; +} + +void WriteBytes(unsigned char* buffer, unsigned int offset, const void* value, unsigned int valueSize) +{ + ARM_PIPE_ASSERT(buffer); + ARM_PIPE_ASSERT(value); + + for (unsigned int i = 0; i < valueSize; i++, offset++) + { + buffer[offset] = *(reinterpret_cast(value) + i); + } +} + +void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value) +{ + ARM_PIPE_ASSERT(buffer); + + buffer[offset] = static_cast(value & 0xFF); + buffer[offset + 1] = static_cast((value >> 8) & 0xFF); + buffer[offset + 2] = static_cast((value >> 16) & 0xFF); + buffer[offset + 3] = static_cast((value >> 24) & 0xFF); + buffer[offset + 4] = static_cast((value >> 32) & 0xFF); + buffer[offset + 5] = static_cast((value >> 40) & 0xFF); + buffer[offset + 6] = static_cast((value >> 48) & 0xFF); + buffer[offset + 7] = static_cast((value >> 56) & 0xFF); +} + +void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value) +{ + ARM_PIPE_ASSERT(buffer); + + buffer[offset] = static_cast(value & 0xFF); + buffer[offset + 1] = static_cast((value >> 8) & 0xFF); + buffer[offset + 2] = static_cast((value >> 16) & 0xFF); + buffer[offset + 3] = static_cast((value >> 24) & 0xFF); +} + +void WriteUint16(unsigned char* buffer, unsigned int offset, uint16_t value) +{ + ARM_PIPE_ASSERT(buffer); + + buffer[offset] = static_cast(value & 0xFF); + buffer[offset + 1] = static_cast((value >> 8) & 0xFF); +} + +void WriteUint8(unsigned char* buffer, unsigned int offset, uint8_t value) +{ + ARM_PIPE_ASSERT(buffer); + + buffer[offset] = static_cast(value); +} + +std::string CentreAlignFormatting(const std::string& stringToPass, const int spacingWidth) +{ + std::stringstream outputStream, centrePadding; + int padding = spacingWidth - static_cast(stringToPass.size()); + + for (int i = 0; i < padding / 2; ++i) + { + centrePadding << " "; + } + + outputStream << centrePadding.str() << stringToPass << centrePadding.str(); + + if (padding > 0 && padding %2 != 0) + { + outputStream << " "; + } + + return outputStream.str(); +} + + +} // namespace pipe +} // namespace arm \ No newline at end of file diff --git a/profiling/common/src/NetworkSockets.cpp b/profiling/common/src/NetworkSockets.cpp index 7f47c79b31..2a656552f1 100644 --- a/profiling/common/src/NetworkSockets.cpp +++ b/profiling/common/src/NetworkSockets.cpp @@ -1,27 +1,35 @@ // -// Copyright © 2020 Arm Ltd. All rights reserved. +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // -#include "common/include/NetworkSockets.hpp" +#include #if defined(__unix__) || defined(__APPLE__) #include #include -#include +#include +#endif + +#if defined(__APPLE__) || defined(_MSC_VER) || defined(__MINGW32__) +#include +#endif +#if defined(__MINGW32__) +#include +#include #endif -namespace armnnUtils +namespace arm { -namespace Sockets +namespace pipe { bool Initialize() { #if defined(__unix__) || defined(__APPLE__) return true; -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(__MINGW32__) WSADATA wsaData; return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0; #endif @@ -31,7 +39,7 @@ int Close(Socket s) { #if defined(__unix__) || defined(__APPLE__) return close(s); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(__MINGW32__) return closesocket(s); #endif } @@ -45,6 +53,9 @@ bool SetNonBlocking(Socket s) #elif defined(_MSC_VER) u_long mode = 1; return ioctlsocket(s, FIONBIO, &mode) == 0; +#elif defined(__MINGW32__) + u_long mode = 1; + return ioctlsocket(s, arm::pipe::numeric_cast(FIONBIO), &mode) == 0; #endif } @@ -53,7 +64,7 @@ long Write(Socket s, const void* buf, size_t len) { #if defined(__unix__) || defined(__APPLE__) return write(s, buf, len); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(__MINGW32__) return send(s, static_cast(buf), static_cast(len), 0); #endif } @@ -63,7 +74,7 @@ long Read(Socket s, void* buf, size_t len) { #if defined(__unix__) || defined(__APPLE__) return read(s, buf, len); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(__MINGW32__) return recv(s, static_cast(buf), static_cast(len), 0); #endif } @@ -71,11 +82,13 @@ long Read(Socket s, void* buf, size_t len) int Ioctl(Socket s, unsigned long int cmd, void* arg) { #if defined(__unix__) || defined(__APPLE__) - ARMNN_NO_CONVERSION_WARN_BEGIN + ARM_PIPE_NO_CONVERSION_WARN_BEGIN return ioctl(s, static_cast(cmd), arg); - ARMNN_NO_CONVERSION_WARN_END -#elif defined(_MSC_VER) + ARM_PIPE_NO_CONVERSION_WARN_END +#elif defined(_MSC_VER) || defined(__MINGW32__) + ARM_PIPE_NO_CONVERSION_WARN_BEGIN return ioctlsocket(s, cmd, static_cast(arg)); + ARM_PIPE_NO_CONVERSION_WARN_END #endif } @@ -84,22 +97,24 @@ int Poll(PollFd* fds, nfds_t numFds, int timeout) { #if defined(__unix__) || defined(__APPLE__) return poll(fds, numFds, timeout); -#elif defined(_MSC_VER) - return WSAPoll(fds, numFds, timeout); +#elif defined(_MSC_VER) || defined(__MINGW32__) + return WSAPoll(fds, arm::pipe::numeric_cast(numFds), timeout); #endif } -armnnUtils::Sockets::Socket Accept(Socket s, sockaddr* addr, socklen_t* addrlen, int flags) +arm::pipe::Socket Accept(Socket s, sockaddr* addr, socklen_t* addrlen, int flags) { #if defined(__unix__) return accept4(s, addr, addrlen, flags); #elif defined(__APPLE__) + IgnoreUnused(flags); return accept(s, addr, addrlen); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(__MINGW32__) + IgnoreUnused(flags); return accept(s, addr, reinterpret_cast(addrlen)); #endif } -} -} +} // pipe +} // arm diff --git a/profiling/common/src/PacketVersionResolver.cpp b/profiling/common/src/PacketVersionResolver.cpp new file mode 100644 index 0000000000..25d92b0c5d --- /dev/null +++ b/profiling/common/src/PacketVersionResolver.cpp @@ -0,0 +1,71 @@ +// +// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include + +namespace arm +{ + +namespace pipe +{ + +bool PacketKey::operator<(const PacketKey& rhs) const +{ + bool result = true; + if (m_FamilyId == rhs.m_FamilyId) + { + result = m_PacketId < rhs.m_PacketId; + } + else if (m_FamilyId > rhs.m_FamilyId) + { + result = false; + } + return result; +} + +bool PacketKey::operator>(const PacketKey& rhs) const +{ + return rhs < *this; +} + +bool PacketKey::operator<=(const PacketKey& rhs) const +{ + return !(*this > rhs); +} + +bool PacketKey::operator>=(const PacketKey& rhs) const +{ + return !(*this < rhs); +} + +bool PacketKey::operator==(const PacketKey& rhs) const +{ + return m_FamilyId == rhs.m_FamilyId && m_PacketId == rhs.m_PacketId; +} + +bool PacketKey::operator!=(const PacketKey& rhs) const +{ + return !(*this == rhs); +} + +Version PacketVersionResolver::ResolvePacketVersion(uint32_t familyId, uint32_t packetId) const +{ + const PacketKey packetKey(familyId, packetId); + + if( packetKey == ActivateTimeLinePacket ) + { + return Version(1, 1, 0); + } + if( packetKey == DeactivateTimeLinePacket ) + { + return Version(1, 1, 0); + } + + return Version(1, 0, 0); +} + +} // namespace pipe + +} // namespace arm diff --git a/profiling/common/src/SwTrace.cpp b/profiling/common/src/SwTrace.cpp new file mode 100644 index 0000000000..5860d8cf06 --- /dev/null +++ b/profiling/common/src/SwTrace.cpp @@ -0,0 +1,128 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include +#include +#include +#include + +#include + +namespace arm +{ + +namespace pipe +{ + +// Calculate the actual length an SwString will be including the terminating null character +// padding to bring it to the next uint32_t boundary but minus the leading uint32_t encoding +// the size to allow the offset to be correctly updated when decoding a binary packet. +uint32_t CalculateSizeOfPaddedSwString(const std::string& str) +{ + std::vector swTraceString; + StringToSwTraceString(str, swTraceString); + unsigned int uint32_t_size = sizeof(uint32_t); + uint32_t size = (numeric_cast(swTraceString.size()) - 1) * uint32_t_size; + return size; +} + +// Read TimelineMessageDirectoryPacket from given IPacketBuffer and offset +SwTraceMessage ReadSwTraceMessage(const unsigned char* packetBuffer, + unsigned int& offset, + const unsigned int& packetLength) +{ + ARM_PIPE_ASSERT(packetBuffer); + + unsigned int uint32_t_size = sizeof(uint32_t); + + SwTraceMessage swTraceMessage; + + // Read the decl_id + uint32_t readDeclId = ReadUint32(packetBuffer, offset); + swTraceMessage.m_Id = readDeclId; + + // SWTrace "namestring" format + // length of the string (first 4 bytes) + string + null terminator + + // Check the decl_name + offset += uint32_t_size; + uint32_t swTraceDeclNameLength = ReadUint32(packetBuffer, offset); + + if (swTraceDeclNameLength == 0 || swTraceDeclNameLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceDeclNameLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + std::vector swTraceStringBuffer(swTraceDeclNameLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceMessage.m_Name.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // name + + // Check the ui_name + offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_Name); + uint32_t swTraceUINameLength = ReadUint32(packetBuffer, offset); + + if (swTraceUINameLength == 0 || swTraceUINameLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceUINameLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + swTraceStringBuffer.resize(swTraceUINameLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceMessage.m_UiName.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // ui_name + + // Check arg_types + offset += CalculateSizeOfPaddedSwString(swTraceMessage.m_UiName); + uint32_t swTraceArgTypesLength = ReadUint32(packetBuffer, offset); + + if (swTraceArgTypesLength == 0 || swTraceArgTypesLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceArgTypesLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + swTraceStringBuffer.resize(swTraceArgTypesLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceMessage.m_ArgTypes.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); // arg_types + + std::string swTraceString(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); + + // Check arg_names + offset += CalculateSizeOfPaddedSwString(swTraceString); + uint32_t swTraceArgNamesLength = ReadUint32(packetBuffer, offset); + + if (swTraceArgNamesLength == 0 || swTraceArgNamesLength > packetLength) + { + throw arm::pipe::ProfilingException("Error swTraceArgNamesLength is an invalid size", LOCATION()); + } + + offset += uint32_t_size; + swTraceStringBuffer.resize(swTraceArgNamesLength - 1); + std::memcpy(swTraceStringBuffer.data(), + packetBuffer + offset, swTraceStringBuffer.size()); + + swTraceString.assign(swTraceStringBuffer.begin(), swTraceStringBuffer.end()); + std::stringstream stringStream(swTraceString); + std::string argName; + while (std::getline(stringStream, argName, ',')) + { + swTraceMessage.m_ArgNames.push_back(argName); + } + + offset += CalculateSizeOfPaddedSwString(swTraceString); + + return swTraceMessage; +} + +} // namespace pipe + +} // namespace arm -- cgit v1.2.1