diff options
Diffstat (limited to 'tools/gator/daemon/NetDriver.cpp')
-rw-r--r-- | tools/gator/daemon/NetDriver.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/tools/gator/daemon/NetDriver.cpp b/tools/gator/daemon/NetDriver.cpp new file mode 100644 index 000000000000..e75c0695779a --- /dev/null +++ b/tools/gator/daemon/NetDriver.cpp @@ -0,0 +1,129 @@ +/** + * Copyright (C) ARM Limited 2013-2014. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +// Define to get format macros from inttypes.h +#define __STDC_FORMAT_MACROS + +#include "NetDriver.h" + +#include <inttypes.h> + +#include "Logging.h" +#include "SessionData.h" + +class NetCounter : public DriverCounter { +public: + NetCounter(DriverCounter *next, char *const name, int64_t *const value); + ~NetCounter(); + + int64_t read(); + +private: + int64_t *const mValue; + int64_t mPrev; + + // Intentionally unimplemented + NetCounter(const NetCounter &); + NetCounter &operator=(const NetCounter &); +}; + +NetCounter::NetCounter(DriverCounter *next, char *const name, int64_t *const value) : DriverCounter(next, name), mValue(value), mPrev(0) { +} + +NetCounter::~NetCounter() { +} + +int64_t NetCounter::read() { + int64_t result = *mValue - mPrev; + mPrev = *mValue; + return result; +} + +NetDriver::NetDriver() : mBuf(), mReceiveBytes(0), mTransmitBytes(0) { +} + +NetDriver::~NetDriver() { +} + +void NetDriver::readEvents(mxml_node_t *const) { + // Only for use with perf + if (!gSessionData->perf.isSetup()) { + return; + } + + setCounters(new NetCounter(getCounters(), strdup("Linux_net_rx"), &mReceiveBytes)); + setCounters(new NetCounter(getCounters(), strdup("Linux_net_tx"), &mTransmitBytes)); +} + +bool NetDriver::doRead() { + if (!countersEnabled()) { + return true; + } + + if (!mBuf.read("/proc/net/dev")) { + return false; + } + + // Skip the header + char *key; + if (((key = strchr(mBuf.getBuf(), '\n')) == NULL) || + ((key = strchr(key + 1, '\n')) == NULL)) { + return false; + } + key = key + 1; + + mReceiveBytes = 0; + mTransmitBytes = 0; + + char *colon; + while ((colon = strchr(key, ':')) != NULL) { + char *end = strchr(colon + 1, '\n'); + if (end != NULL) { + *end = '\0'; + } + *colon = '\0'; + + int64_t receiveBytes; + int64_t transmitBytes; + const int count = sscanf(colon + 1, " %" SCNu64 " %*u %*u %*u %*u %*u %*u %*u %" SCNu64, &receiveBytes, &transmitBytes); + if (count != 2) { + return false; + } + mReceiveBytes += receiveBytes; + mTransmitBytes += transmitBytes; + + if (end == NULL) { + break; + } + key = end + 1; + } + + return true; +} + +void NetDriver::start() { + if (!doRead()) { + logg->logError(__FILE__, __LINE__, "Unable to read network stats"); + handleException(); + } + // Initialize previous values + for (DriverCounter *counter = getCounters(); counter != NULL; counter = counter->getNext()) { + if (!counter->isEnabled()) { + continue; + } + counter->read(); + } +} + +void NetDriver::read(Buffer *const buffer) { + if (!doRead()) { + logg->logError(__FILE__, __LINE__, "Unable to read network stats"); + handleException(); + } + super::read(buffer); +} |