aboutsummaryrefslogtreecommitdiff
path: root/src/profiling/SocketProfilingConnection.cpp
diff options
context:
space:
mode:
authorColm Donelan <Colm.Donelan@arm.com>2019-10-11 13:09:49 +0100
committerColm Donelan <Colm.Donelan@arm.com>2019-10-11 13:12:37 +0100
commita21620d32a8a0a8d527c061e2a22d51009d75877 (patch)
treeb08ffee4cddb1bb3b1d206c67ea80bc2093d7bf5 /src/profiling/SocketProfilingConnection.cpp
parent67ef2a52c3cdcc37538d77711bbcea2f0e5655e5 (diff)
downloadarmnn-a21620d32a8a0a8d527c061e2a22d51009d75877.tar.gz
IVGCVSW-3721 Add support for startup sequence (Mock Gatord service).
* Receive and process the stream metadata from the client. * Send the connection ack packet. * Wait in a receiving thread and print the packets. * GatordMockTest and Impl for PeriodicCounterCapture CommandHandler * CaptureData class to retain packet data * MockUtils * Update SocketProfilingConnection to fix non blocking receipt of packets. * Restructure directory layout following review comments. * Extract the mock service into a static library in the cmake files. Signed-off-by: Colm Donelan <Colm.Donelan@arm.com> Signed-off-by: Keith Davis <keith.davis@arm.com> Signed-off-by: Mike Kelly <mike.kelly@arm.com> Signed-off-by: Finn Williams <Finn.Williams@arm.com> Signed-off-by: Kevin May <kevin.may@arm.com> Change-Id: I33c1c9f93976708c9315f71290d42cff53b8c075
Diffstat (limited to 'src/profiling/SocketProfilingConnection.cpp')
-rw-r--r--src/profiling/SocketProfilingConnection.cpp102
1 files changed, 58 insertions, 44 deletions
diff --git a/src/profiling/SocketProfilingConnection.cpp b/src/profiling/SocketProfilingConnection.cpp
index ad629928f9..6f7101b254 100644
--- a/src/profiling/SocketProfilingConnection.cpp
+++ b/src/profiling/SocketProfilingConnection.cpp
@@ -5,10 +5,11 @@
#include "SocketProfilingConnection.hpp"
+#include <cerrno>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <cerrno>
#include <string>
namespace armnn
@@ -23,7 +24,7 @@ SocketProfilingConnection::SocketProfilingConnection()
m_Socket[0].fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (m_Socket[0].fd == -1)
{
- throw RuntimeException(std::string("Socket construction failed: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Socket construction failed: ") + strerror(errno));
}
// Connect to the named unix domain socket.
@@ -35,7 +36,7 @@ SocketProfilingConnection::SocketProfilingConnection()
if (0 != connect(m_Socket[0].fd, reinterpret_cast<const sockaddr*>(&server), sizeof(sockaddr_un)))
{
close(m_Socket[0].fd);
- throw RuntimeException(std::string("Cannot connect to stream socket: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Cannot connect to stream socket: ") + strerror(errno));
}
// Our socket will only be interested in polling reads.
@@ -46,7 +47,7 @@ SocketProfilingConnection::SocketProfilingConnection()
if (0 != fcntl(m_Socket[0].fd, F_SETFL, currentFlags | O_NONBLOCK))
{
close(m_Socket[0].fd);
- throw RuntimeException(std::string("Failed to set socket as non blocking: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Failed to set socket as non blocking: ") + strerror(errno));
}
}
@@ -59,7 +60,7 @@ void SocketProfilingConnection::Close()
{
if (close(m_Socket[0].fd) != 0)
{
- throw RuntimeException(std::string("Cannot close stream socket: ") + strerror(errno));
+ throw armnn::RuntimeException(std::string("Cannot close stream socket: ") + strerror(errno));
}
memset(m_Socket, 0, sizeof(m_Socket));
@@ -77,54 +78,67 @@ bool SocketProfilingConnection::WritePacket(const unsigned char* buffer, uint32_
Packet SocketProfilingConnection::ReadPacket(uint32_t timeout)
{
- // Poll for data on the socket or until timeout occurs
- int pollResult = poll(m_Socket, 1, static_cast<int>(timeout));
-
- switch (pollResult)
+ // Is there currently at least a headers worth of data waiting to be read?
+ int bytes_available;
+ ioctl(m_Socket[0].fd, FIONREAD, &bytes_available);
+ if (bytes_available >= 8)
{
- case -1: // Error
- throw RuntimeException(std::string("Read failure from socket: ") + strerror(errno));
+ // Yes there is. Read it:
+ return ReceivePacket();
+ }
+ else
+ {
+ // Poll for data on the socket or until timeout occurs
+ int pollResult = poll(m_Socket, 1, static_cast<int>(timeout));
+
+ switch (pollResult)
+ {
+ case -1: // Error
+ throw armnn::RuntimeException(std::string("Read failure from socket: ") + strerror(errno));
- case 0: // Timeout
- throw RuntimeException("Timeout while reading from socket");
+ case 0: // Timeout
+ throw TimeoutException("Timeout while reading from socket");
- default: // Normal poll return but it could still contain an error signal
+ default: // Normal poll return but it could still contain an error signal
- // Check if the socket reported an error
- if (m_Socket[0].revents & (POLLNVAL | POLLERR | POLLHUP))
- {
- throw Exception(std::string("Socket 0 reported an error: ") + strerror(errno));
- }
+ // Check if the socket reported an error
+ if (m_Socket[0].revents & (POLLNVAL | POLLERR | POLLHUP))
+ {
+ throw armnn::RuntimeException(std::string("Socket reported an error: ") + strerror(errno));
+ }
- // Check if there is data to read
- if (!(m_Socket[0].revents & (POLLIN)))
- {
- // No data to read from the socket. Silently ignore and continue
- return Packet();
- }
+ // Check if there is data to read
+ if (!(m_Socket[0].revents & (POLLIN)))
+ {
+ // This is a very odd case. The file descriptor was woken up but no data was written.
+ throw armnn::RuntimeException("Poll resulted in : no data to read");
+ }
- // There is data to read, read the header first
- char header[8] = {};
- if (8 != recv(m_Socket[0].fd, &header, sizeof(header), 0))
- {
- // What do we do here if there's not a valid 8 byte header to read?
- throw RuntimeException("The received packet did not contains a valid MIPE header");
+ return ReceivePacket();
}
+ }
+}
- // stream_metadata_identifier is the first 4 bytes
- uint32_t metadataIdentifier = 0;
- std::memcpy(&metadataIdentifier, header, sizeof(metadataIdentifier));
+Packet SocketProfilingConnection::ReceivePacket()
+{
+ char header[8] = {};
+ if (8 != recv(m_Socket[0].fd, &header, sizeof(header), 0))
+ {
+ // What do we do here if there's not a valid 8 byte header to read?
+ throw armnn::RuntimeException("The received packet did not contains a valid MIPE header");
+ }
+ // stream_metadata_identifier is the first 4 bytes
+ uint32_t metadataIdentifier = 0;
+ std::memcpy(&metadataIdentifier, header, sizeof(metadataIdentifier));
- // data_length is the next 4 bytes
- uint32_t dataLength = 0;
- std::memcpy(&dataLength, header + 4u, sizeof(dataLength));
+ // data_length is the next 4 bytes
+ uint32_t dataLength = 0;
+ std::memcpy(&dataLength, header + 4u, sizeof(dataLength));
std::unique_ptr<unsigned char[]> packetData;
- if (dataLength > 0)
- {
+ if (dataLength > 0)
+ {
packetData = std::make_unique<unsigned char[]>(dataLength);
- }
-
ssize_t receivedLength = recv(m_Socket[0].fd, packetData.get(), dataLength, 0);
if (receivedLength < 0)
{
@@ -133,11 +147,11 @@ Packet SocketProfilingConnection::ReadPacket(uint32_t timeout)
if (dataLength != static_cast<uint32_t>(receivedLength))
{
// What do we do here if we can't read in a full packet?
- throw RuntimeException("Invalid MIPE packet");
+ throw armnn::RuntimeException("Invalid MIPE packet");
}
-
- return Packet(metadataIdentifier, dataLength, packetData);
}
+
+ return Packet(metadataIdentifier, dataLength, packetData);
}
} // namespace profiling