1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-11-15 17:47:09 +00:00

Merge pull request #182 from mxmlnkn/issue-155

Issue #155: Fix for initial spike on program
This commit is contained in:
Brenden Matthews 2015-12-11 12:54:32 -08:00
commit c2b921170d
4 changed files with 107 additions and 38 deletions

View File

@ -2878,6 +2878,7 @@ void set_current_config() {
void initialisation(int argc, char **argv) {
struct sigaction act, oact;
clear_net_stats();
set_default_configurations();
set_current_config();
@ -3063,7 +3064,6 @@ int main(int argc, char **argv)
argc_copy = argc;
argv_copy = argv;
g_signal_pending = 0;
clear_net_stats();
#ifdef BUILD_CURL
struct curl_global_initializer {

View File

@ -367,10 +367,24 @@ void print_gateway_ip(struct text_object *obj, char *p, int p_max_size)
snprintf(p, p_max_size, "%s", gw_info.ip);
}
/**
* Parses information from /proc/net/dev and stores them in ???
*
* For the output format of /proc/net/dev @see http://linux.die.net/man/5/proc
*
* @return always returns 0. May change in the future, e.g. returning non zero
* if some error happened
**/
int update_net_stats(void)
{
FILE *net_dev_fp;
static int rep = 0;
/* variably to notify the parts averaging the download speed, that this
* is the first call ever to this function. This variable can't be used
* to decide if this is the first time an interface was parsed as there
* are many interfaces, which can be activated and deactivated at arbitrary
* times */
static char first = 1;
// FIXME: arbitrary size chosen to keep code simple.
@ -394,12 +408,15 @@ int update_net_stats(void)
return 0;
}
/* open file and ignore first two lines */
/* open file /proc/net/dev. If not something went wrong, clear all
* network statistics */
if (!(net_dev_fp = open_file("/proc/net/dev", &rep))) {
clear_net_stats();
return 0;
}
/* ignore first two header lines in file /proc/net/dev. If somethings
* goes wrong, e.g. end of file reached, quit.
* (Why isn't clear_net_stats called for this case ??? */
if (!fgets(buf, 255, net_dev_fp) || /* garbage */
!fgets(buf, 255, net_dev_fp)) { /* garbage (field names) */
fclose(net_dev_fp);
@ -413,48 +430,68 @@ int update_net_stats(void)
char temp_addr[18];
long long r, t, last_recv, last_trans;
/* quit only after all non-header lines from /proc/net/dev parsed */
if (fgets(buf, 255, net_dev_fp) == NULL) {
break;
}
p = buf;
while (isspace((int) *p)) {
/* change char * p to first non-space character, which is the beginning
* of the interface name */
while (*p != '\0' && isspace((int) *p)) {
p++;
}
s = p;
while (*p && *p != ':') {
/* increment p until the end of the interface name has been reached */
while (*p != '\0' && *p != ':') {
p++;
}
if (*p == '\0') {
continue;
}
/* replace ':' with '\0' in output of /proc/net/dev */
*p = '\0';
p++;
/* get pointer to interface statistics with the interface name in s */
ns = get_net_stat(s, NULL, NULL);
ns->up = 1;
memset(&(ns->addr.sa_data), 0, 14);
memset(ns->addrs, 0, 17 * MAX_NET_INTERFACES + 1); /* Up to 17 chars per ip, max MAX_NET_INTERFACES interfaces. Nasty memory usage... */
last_recv = ns->recv;
last_trans = ns->trans;
/* bytes packets errs drop fifo frame compressed multicast|bytes ... */
sscanf(p, "%lld %*d %*d %*d %*d %*d %*d %*d %lld",
&r, &t);
/* if recv or trans is less than last time, an overflow happened */
/* if the interface is parsed the first time, then set recv and trans
* to currently received, meaning the change in network traffic is 0 */
if (ns->last_read_recv == -1) {
ns->recv = r;
first = 1;
}
if (ns->last_read_trans == -1) {
ns->trans = t;
first = 1;
}
/* move current traffic statistic to last thereby obsoleting the
* current statistic */
last_recv = ns->recv;
last_trans = ns->trans;
/* If recv or trans is less than last time, an overflow happened.
* In that case set the last traffic to the current one, don't set
* it to 0, else a spike in the download and upload speed will occur! */
if (r < ns->last_read_recv) {
last_recv = 0;
last_recv = r;
} else {
ns->recv += (r - ns->last_read_recv);
}
ns->last_read_recv = r;
if (t < ns->last_read_trans) {
last_trans = 0;
last_trans = t;
} else {
ns->trans += (t - ns->last_read_trans);
}
@ -490,19 +527,19 @@ int update_net_stats(void)
close((long) i);
free(conf.ifc_buf);
/*** end ip addr patch ***/
if (!first) {
/* calculate speeds */
/* calculate instantenous speeds */
ns->net_rec [0] = (ns->recv - last_recv ) / delta;
ns->net_trans[0] = (ns->trans - last_trans) / delta;
}
curtmp1 = 0;
curtmp2 = 0;
// get an average
/* get an average over the last speed samples */
int samples = net_avg_samples.get(*state);
/* is OpenMP actually useful here? How large is samples? > 1000 ? */
#ifdef HAVE_OPENMP
#pragma omp parallel for reduction(+:curtmp1, curtmp2) schedule(dynamic,10)
#endif /* HAVE_OPENMP */

View File

@ -58,9 +58,19 @@ conky::lua_traits<if_up_strictness_>::Map conky::lua_traits<if_up_strictness_>::
static conky::simple_config_setting<if_up_strictness_> if_up_strictness("if_up_strictness",
IFUP_UP, true);
/**
* global array of structs containing network statistics for each interface
**/
struct net_stat netstats[MAX_NET_INTERFACES];
/**
* Returns pointer to specified interface in netstats array.
* If not found then add the specified interface to the array.
* The added interface will have all its members initialized to 0,
* because clear_net_stats() is called from main() in conky.cc!
*
* @param[in] dev device / interface name. Silently ignores char * == NULL
**/
struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_at_crash2)
{
unsigned int i;
@ -80,6 +90,10 @@ struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_
for (i = 0; i < MAX_NET_INTERFACES; i++) {
if (netstats[i].dev == 0) {
netstats[i].dev = strndup(dev, text_buffer_size.get(*state));
/* initialize last_read_recv and last_read_trans to -1 denoting
* that they were never read before */
netstats[i].last_read_recv = -1;
netstats[i].last_read_trans = -1;
return &netstats[i];
}
}
@ -415,6 +429,11 @@ double wireless_link_barval(struct text_object *obj)
}
#endif /* BUILD_WLAN */
/**
* Clears the global array of net_stat structs which contains networks
* statistics for every interface.
**/
void clear_net_stats(void)
{
#ifdef BUILD_IPV6

View File

@ -43,11 +43,21 @@ struct v6addr {
#endif /* BUILD_IPV6 */
struct net_stat {
/* interface name, e.g. wlan0, eth0, ... */
char *dev;
/* set to 1, if interface is up */
int up;
/* network traffic read on last call in order to calculate how much
* was received or transmitted since the last call. contains -1 if
* it was never read before. in bytes */
long long last_read_recv, last_read_trans;
/* total received and transmitted data statistics in bytes */
long long recv, trans;
/* averaged network speed in bytes / second */
double recv_speed, trans_speed;
/* struct with at least the member sa_data which is a const * containing
* the socket address.
* @see http://pubs.opengroup.org/onlinepubs/7908799/xns/syssocket.h.html */
struct sockaddr addr;
#ifdef BUILD_IPV6
struct v6addr *v6addrs;
@ -57,6 +67,9 @@ struct net_stat {
#if defined(__linux__)
char addrs[17 * MAX_NET_INTERFACES + 1];
#endif /* __linux__ */
/* network speeds between two conky calls in bytes per second.
* An average over these samples is calculated in recv_speed and
* trans_speed */
double net_rec[15], net_trans[15];
// wireless extensions
char essid[32];