1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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);
}
|