diff options
author | Jim Flynn <jim.flynn@arm.com> | 2020-07-20 16:57:44 +0100 |
---|---|---|
committer | Jim Flynn <jim.flynn@arm.com> | 2020-07-29 15:35:15 +0100 |
commit | bbfe603e5ae42317a2b67d713d00882bea341c88 (patch) | |
tree | 8d8a78d6836384fb92fb9741c865443624dfec68 /profiling/server/include | |
parent | a9c2ce123a6a5a68728d040a0323c482bbe46903 (diff) | |
download | armnn-bbfe603e5ae42317a2b67d713d00882bea341c88.tar.gz |
IVGCVSW-5166 Pull out the common and server side code into standalone libraries
Change-Id: I180f84c493a9b2be4b93b25d312ebdd9e71b1735
Signed-off-by: Jim Flynn <jim.flynn@arm.com>
Diffstat (limited to 'profiling/server/include')
6 files changed, 444 insertions, 0 deletions
diff --git a/profiling/server/include/basePipeServer/BasePipeServer.hpp b/profiling/server/include/basePipeServer/BasePipeServer.hpp new file mode 100644 index 0000000000..1b6dec54ff --- /dev/null +++ b/profiling/server/include/basePipeServer/BasePipeServer.hpp @@ -0,0 +1,120 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <common/include/NetworkSockets.hpp> +#include <common/include/Packet.hpp> +#include <common/include/SocketConnectionException.hpp> + +#include <string> +#include <atomic> + +namespace arm +{ + +namespace pipe +{ + +enum class TargetEndianness +{ + BeWire, + LeWire +}; + +enum class PacketDirection +{ + Sending, + ReceivedHeader, + ReceivedData +}; +class ConnectionHandler; + +class BasePipeServer +{ + +public: + + BasePipeServer(arm::pipe::Socket clientConnection, bool echoPackets) + : m_ClientConnection(clientConnection) + , m_EchoPackets(echoPackets) + {} + + ~BasePipeServer() + { + // We have set SOCK_CLOEXEC on this socket but we'll close it to be good citizens. + arm::pipe::Close(m_ClientConnection); + } + + BasePipeServer(const BasePipeServer&) = delete; + BasePipeServer& operator=(const BasePipeServer&) = delete; + + BasePipeServer(BasePipeServer&&) = delete; + BasePipeServer& operator=(BasePipeServer&&) = delete; + + /// Close the client connection + /// @return 0 if successful + int Close() + { + return arm::pipe::Close(m_ClientConnection); + } + + /// Send a packet to the client + /// @return true if a valid packet has been sent. + bool SendPacket(uint32_t packetFamily, uint32_t packetId, const uint8_t* data, uint32_t dataLength); + + /// Set the client socket to nonblocking + /// @return true if successful. + bool SetNonBlocking() + { + return arm::pipe::SetNonBlocking(m_ClientConnection); + } + + /// Block on the client connection until a complete packet has been received. + /// @return true if a valid packet has been received. + arm::pipe::Packet WaitForPacket(uint32_t timeoutMs); + + /// Once the connection is open wait to receive the stream meta data packet from the client. Reading this + /// packet differs from others as we need to determine endianness. + /// @return true only if a valid stream meta data packet has been received. + bool WaitForStreamMetaData(); + + uint32_t GetStreamMetadataVersion() + { + return m_StreamMetaDataVersion; + } + + uint32_t GetStreamMetadataMaxDataLen() + { + return m_StreamMetaDataMaxDataLen; + } + + uint32_t GetStreamMetadataPid() + { + return m_StreamMetaDataPid; + } + +private: + + void EchoPacket(PacketDirection direction, uint8_t* packet, size_t lengthInBytes); + bool ReadFromSocket(uint8_t* packetData, uint32_t expectedLength); + bool ReadHeader(uint32_t headerAsWords[2]); + + arm::pipe::Packet ReceivePacket(); + + uint32_t ToUint32(uint8_t* data, TargetEndianness endianness); + void InsertU32(uint32_t value, uint8_t* data, TargetEndianness endianness); + + arm::pipe::Socket m_ClientConnection; + bool m_EchoPackets; + TargetEndianness m_Endianness; + + uint32_t m_StreamMetaDataVersion; + uint32_t m_StreamMetaDataMaxDataLen; + uint32_t m_StreamMetaDataPid; +}; + +} // namespace pipe +} // namespace arm diff --git a/profiling/server/include/basePipeServer/ConnectionHandler.hpp b/profiling/server/include/basePipeServer/ConnectionHandler.hpp new file mode 100644 index 0000000000..4859fced0d --- /dev/null +++ b/profiling/server/include/basePipeServer/ConnectionHandler.hpp @@ -0,0 +1,48 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "BasePipeServer.hpp" +#include <string> + +namespace arm +{ + +namespace pipe +{ + +class ConnectionHandler +{ +public: + /// Constructor establishes the Unix domain socket and sets it to listen for connections. + /// @param udsNamespace the namespace (socket address) associated with the listener. + /// @throws SocketConnectionException if the socket has been incorrectly setup. + ConnectionHandler(const std::string& udsNamespace, const bool setNonBlocking); + + ~ConnectionHandler() + { + // We have set SOCK_CLOEXEC on this socket but we'll close it to be good citizens. + arm::pipe::Close(m_ListeningSocket); + } + + ConnectionHandler(const ConnectionHandler&) = delete; + ConnectionHandler& operator=(const ConnectionHandler&) = delete; + + ConnectionHandler(ConnectionHandler&&) = delete; + ConnectionHandler& operator=(ConnectionHandler&&) = delete; + + /// Attempt to open a new socket to the client and use it to construct a new basePipeServer + /// @param echoPackets if true the raw packets will be printed to stdout. + /// @return if successful a unique_ptr to a basePipeServer otherwise a nullptr + std::unique_ptr<BasePipeServer> GetNewBasePipeServer(const bool echoPackets); + +private: + + arm::pipe::Socket m_ListeningSocket; +}; + +} // namespace pipe +} // namespace arm diff --git a/profiling/server/include/timelineDecoder/ITimelineDecoder.hpp b/profiling/server/include/timelineDecoder/ITimelineDecoder.hpp new file mode 100644 index 0000000000..18b8cc7006 --- /dev/null +++ b/profiling/server/include/timelineDecoder/ITimelineDecoder.hpp @@ -0,0 +1,91 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include <cstdint> +#include <string> + +namespace arm +{ + +namespace pipe +{ + +class ITimelineDecoder +{ + +public: + + enum class TimelineStatus + { + TimelineStatus_Success, + TimelineStatus_Fail + }; + + enum class RelationshipType + { + RetentionLink, /// Head retains(parents) Tail + ExecutionLink, /// Head execution start depends on Tail execution completion + DataLink, /// Head uses data of Tail + LabelLink /// Head uses label Tail (Tail MUST be a guid of a label). + }; + + static char const* GetRelationshipAsCString(RelationshipType rType) + { + switch (rType) + { + case RelationshipType::RetentionLink: return "RetentionLink"; + case RelationshipType::ExecutionLink: return "ExecutionLink"; + case RelationshipType::DataLink: return "DataLink"; + case RelationshipType::LabelLink: return "LabelLink"; + default: return "Unknown"; + } + } + + struct Entity + { + uint64_t m_Guid; + }; + + struct EventClass + { + uint64_t m_Guid; + uint64_t m_NameGuid; + }; + + struct Event + { + uint64_t m_Guid; + uint64_t m_TimeStamp; + uint64_t m_ThreadId; + }; + + struct Label + { + uint64_t m_Guid; + std::string m_Name; + }; + + struct Relationship + { + RelationshipType m_RelationshipType; + uint64_t m_Guid; + uint64_t m_HeadGuid; + uint64_t m_TailGuid; + uint64_t m_AttributeGuid; + }; + + virtual ~ITimelineDecoder() = default; + + virtual TimelineStatus CreateEntity(const Entity&) = 0; + virtual TimelineStatus CreateEventClass(const EventClass&) = 0; + virtual TimelineStatus CreateEvent(const Event&) = 0; + virtual TimelineStatus CreateLabel(const Label&) = 0; + virtual TimelineStatus CreateRelationship(const Relationship&) = 0; +}; + +} // namespace pipe +} // namespace arm diff --git a/profiling/server/include/timelineDecoder/TimelineCaptureCommandHandler.hpp b/profiling/server/include/timelineDecoder/TimelineCaptureCommandHandler.hpp new file mode 100644 index 0000000000..c51cfd32cd --- /dev/null +++ b/profiling/server/include/timelineDecoder/TimelineCaptureCommandHandler.hpp @@ -0,0 +1,63 @@ +// +// Copyright © 2019 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "ITimelineDecoder.hpp" + +#include <common/include/CommandHandlerFunctor.hpp> +#include <common/include/Packet.hpp> + +namespace arm +{ + +namespace pipe +{ + +class TimelineCaptureCommandHandler : public arm::pipe::CommandHandlerFunctor +{ + // Utils + uint32_t uint32_t_size = sizeof(uint32_t); + uint32_t uint64_t_size = sizeof(uint64_t); + + using ReadFunction = ITimelineDecoder::TimelineStatus (TimelineCaptureCommandHandler::*)( + const unsigned char*, uint32_t&); + +public: + TimelineCaptureCommandHandler(uint32_t familyId, + uint32_t packetId, + uint32_t version, + ITimelineDecoder& timelineDecoder, + uint32_t threadIdSize = 0) + : CommandHandlerFunctor(familyId, packetId, version) + , m_TimelineDecoder(timelineDecoder) + , m_ThreadIdSize(threadIdSize) + , m_PacketLength(0) + {} + + void operator()(const arm::pipe::Packet& packet) override; + + + void SetThreadIdSize(uint32_t size); + +private: + void ParseData(const arm::pipe::Packet& packet); + + ITimelineDecoder::TimelineStatus ReadLabel(const unsigned char* data, uint32_t& offset); + ITimelineDecoder::TimelineStatus ReadEntity(const unsigned char* data, uint32_t& offset); + ITimelineDecoder::TimelineStatus ReadEventClass(const unsigned char* data, uint32_t& offset); + ITimelineDecoder::TimelineStatus ReadRelationship(const unsigned char* data, uint32_t& offset); + ITimelineDecoder::TimelineStatus ReadEvent(const unsigned char* data, uint32_t& offset); + + ITimelineDecoder& m_TimelineDecoder; + uint32_t m_ThreadIdSize; + unsigned int m_PacketLength; + static const ReadFunction m_ReadFunctions[]; + +}; + +} //namespace pipe + +} //namespace arm diff --git a/profiling/server/include/timelineDecoder/TimelineDecoder.hpp b/profiling/server/include/timelineDecoder/TimelineDecoder.hpp new file mode 100644 index 0000000000..ea4b144860 --- /dev/null +++ b/profiling/server/include/timelineDecoder/TimelineDecoder.hpp @@ -0,0 +1,72 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "ITimelineDecoder.hpp" + +#include <vector> + +namespace arm +{ + +namespace pipe +{ + +class TimelineDecoder : public ITimelineDecoder +{ + +public: + + struct Model + { + std::vector<Entity> m_Entities; + std::vector<EventClass> m_EventClasses; + std::vector<Event> m_Events; + std::vector<Label> m_Labels; + std::vector<Relationship> m_Relationships; + }; + + using OnNewEntityCallback = void (*)(Model &, const Entity); + using OnNewEventClassCallback = void (*)(Model &, const EventClass); + using OnNewEventCallback = void (*)(Model &, const Event); + using OnNewLabelCallback = void (*)(Model &, const Label); + using OnNewRelationshipCallback = void (*)(Model &, const Relationship); + + virtual TimelineStatus CreateEntity(const Entity &) override; + virtual TimelineStatus CreateEventClass(const EventClass &) override; + virtual TimelineStatus CreateEvent(const Event &) override; + virtual TimelineStatus CreateLabel(const Label &) override; + virtual TimelineStatus CreateRelationship(const Relationship &) override; + + const Model& GetModel(); + + TimelineStatus SetEntityCallback(const OnNewEntityCallback); + TimelineStatus SetEventClassCallback(const OnNewEventClassCallback); + TimelineStatus SetEventCallback(const OnNewEventCallback); + TimelineStatus SetLabelCallback(const OnNewLabelCallback); + TimelineStatus SetRelationshipCallback(const OnNewRelationshipCallback); + + void SetDefaultCallbacks(); + + void print(); + +private: + Model m_Model; + + OnNewEntityCallback m_OnNewEntityCallback; + OnNewEventClassCallback m_OnNewEventClassCallback; + OnNewEventCallback m_OnNewEventCallback; + OnNewLabelCallback m_OnNewLabelCallback; + OnNewRelationshipCallback m_OnNewRelationshipCallback; + + void printLabels(); + void printEntities(); + void printEventClasses(); + void printRelationships(); + void printEvents(); +}; + +} // namespace pipe +} // namespace arm
\ No newline at end of file diff --git a/profiling/server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp b/profiling/server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp new file mode 100644 index 0000000000..826ee1f10d --- /dev/null +++ b/profiling/server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp @@ -0,0 +1,50 @@ +// +// Copyright © 2019 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "TimelineCaptureCommandHandler.hpp" + +#include <common/include/SwTrace.hpp> + +namespace arm +{ + +namespace pipe +{ + +class TimelineDirectoryCaptureCommandHandler : public arm::pipe::CommandHandlerFunctor +{ + // Utils + uint32_t uint8_t_size = sizeof(uint8_t); + uint32_t uint32_t_size = sizeof(uint32_t); + +public: + TimelineDirectoryCaptureCommandHandler(uint32_t familyId, + uint32_t packetId, + uint32_t version, + TimelineCaptureCommandHandler& timelineCaptureCommandHandler, + bool quietOperation = false) + : CommandHandlerFunctor(familyId, packetId, version) + , m_TimelineCaptureCommandHandler(timelineCaptureCommandHandler) + , m_QuietOperation(quietOperation) + {} + + void operator()(const arm::pipe::Packet& packet) override; + + arm::pipe::SwTraceHeader m_SwTraceHeader; + std::vector<arm::pipe::SwTraceMessage> m_SwTraceMessages; + +private: + void ParseData(const arm::pipe::Packet& packet); + void Print(); + + TimelineCaptureCommandHandler& m_TimelineCaptureCommandHandler; + bool m_QuietOperation; +}; + +} //namespace pipe + +} //namespace arm |