1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

rewrite of histogram class

git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@260 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
Steffen Vogel 2014-12-09 19:46:25 +00:00
parent c8d412df73
commit 8bd93e40fd
9 changed files with 145 additions and 85 deletions

View file

@ -1,5 +1,5 @@
TARGETS = server send random receive test
SRCS = server.c send.c receive.c random.c node.c path.c utils.c socket.c msg.c cfg.c if.c tc.c
SRCS = server.c send.c receive.c random.c node.c path.c utils.c socket.c msg.c cfg.c if.c tc.c hist.c
# Default target: build everything
all: $(TARGETS)
@ -7,11 +7,11 @@ all: $(TARGETS)
COMMON = socket.o if.o utils.o msg.o node.o cfg.o tc.o hooks.o
# Dependencies for individual binaries
server: $(COMMON) path.o
server: $(COMMON) path.o hist.o
send: $(COMMON)
receive: $(COMMON)
random: utils.o msg.o
test: $(COMMON)
test: $(COMMON) hist.o
VPATH = src

View file

@ -20,10 +20,6 @@
/** Socket priority */
#define SOCKET_PRIO 7
/* Some parameters for histogram statistics */
#define HIST_HEIGHT 50
#define HIST_SEQ 17
/* Protocol numbers */
#define IPPROTO_S2SS 137
#define ETH_P_S2SS 0xBABE

36
server/include/hist.h Normal file
View file

@ -0,0 +1,36 @@
/** Histogram functions.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
*/
#ifndef _HIST_H_
#define _HIST_H_
#define HIST_HEIGHT 50
#define HIST_SEQ 17
/** Histogram structure */
struct hist {
double start;
double end;
double resolution;
int length;
unsigned *data;
};
void hist_init(struct hist *h, double start, double end, double resolution);
void hist_free(struct hist *h);
void hist_reset(struct hist *h);
void hist_put(struct hist *h, double value);
/** Print ASCII style plot of histogram */
void hist_plot(struct hist *h);
/** Dump histogram data in Matlab format */
void hist_dump(struct hist *h);
#endif /* _HIST_H_ */

View file

@ -12,6 +12,7 @@
#include <libconfig.h>
#include "config.h"
#include "hist.h"
#include "node.h"
#include "msg.h"
#include "hooks.h"
@ -35,6 +36,9 @@ struct path
/** A pointer to the last received message */
struct msg *last;
/** Counter for received messages according to their sequence no displacement */
struct hist histogram;
/** Last known message number */
unsigned int sequence;
@ -49,8 +53,6 @@ struct path
unsigned int skipped;
/** Counter for dropped messages due to reordering */
unsigned int dropped;
/** Counter for received messages according to their sequence no displacement */
unsigned int histogram[HIST_SEQ];
/** The thread id for this path */
pthread_t recv_tid;

View file

@ -81,12 +81,6 @@ double timespec_delta(struct timespec *start, struct timespec *end);
/** Get period as timespec from rate */
struct timespec timespec_rate(double rate);
/** Print ASCII style plot of histogram */
void hist_plot(unsigned *hist, int length);
/** Dump histogram data in Matlab format */
void hist_dump(unsigned *hist, int length);
/** A system(2) emulator with popen/pclose(2) and proper output handling */
int system2(const char* cmd, ...);

85
server/src/hist.c Normal file
View file

@ -0,0 +1,85 @@
/** Histogram functions.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include "utils.h"
#include "hist.h"
void hist_init(struct hist *h, double start, double end, double resolution)
{
h->start = start;
h->end = end;
h->resolution = resolution;
h->length = (end - start) / resolution;
h->data = malloc(h->length * sizeof(unsigned));
hist_reset(h);
}
void hist_free(struct hist *h)
{
free(h->data);
}
void hist_put(struct hist *h, double value)
{
int index = round((value - h->start) / h->resolution);
if (index >= 0 && index < h->length)
h->data[index]++;
}
void hist_reset(struct hist *h)
{
memset(h->data, 0, h->length * sizeof(unsigned));
}
void hist_plot(struct hist *h)
{
unsigned min = UINT_MAX;
unsigned max = 0;
/* Get max, first & last */
for (int i = 0; i < h->length; i++) {
if (h->data[i] > max)
max = h->data[i];
if (h->data[i] < min)
min = h->data[i];
}
char buf[HIST_HEIGHT];
memset(buf, '#', HIST_HEIGHT);
/* Print plot */
info("%5s | %5s | %s", "Value", "Occur", "Histogram Plot:");
for (int i = 0; i < h->length; i++) {
double val = h->start + i * h->resolution;
int bar = HIST_HEIGHT * ((double) h->data[i] / max);
if (h->data[i] == min) info("%5.2e | " GRN("%5u") " | %.*s", val, h->data[i], bar, buf);
else if (h->data[i] == max) info("%5.2e | " RED("%5u") " | %.*s", val, h->data[i], bar, buf);
else info("%5.2e | " "%5u" " | %.*s", val, h->data[i], bar, buf);
}
}
void hist_dump(struct hist *h)
{
char tok[8];
char buf[h->length * sizeof(tok)];
memset(buf, 0, sizeof(buf));
/* Print in Matlab vector format */
for (int i = 0; i < h->length; i++) {
snprintf(tok, sizeof(tok), "%u ", h->data[i]);
strncat(buf, tok, sizeof(buf) - strlen(buf));
}
info("hist = [ %s]", buf);
}

View file

@ -93,9 +93,7 @@ static void * path_run(void *arg)
if (dist > UINT16_MAX / 2)
dist -= UINT16_MAX;
int idx = HIST_SEQ / 2 + dist;
if (idx < HIST_SEQ && idx >= 0)
p->histogram[idx]++;
hist_put(&p->histogram, dist);
/* Handle simulation restart */
if (m->sequence == 0 && abs(dist) > 16) {
@ -112,8 +110,7 @@ static void * path_run(void *arg)
p->skipped = 0;
p->dropped = 0;
/* Reset sequence no tracking */
memset(p->histogram, 0, sizeof(p->histogram));
hist_reset(&p->histogram);
}
else if (dist <= 0 && p->received > 1) {
p->dropped++;
@ -146,6 +143,8 @@ int path_start(struct path *p)
{ INDENT
info("Starting path: %12s " GRN("=>") " %-12s", p->in->name, p->out->name);
hist_init(&p->histogram, -HIST_SEQ, +HIST_SEQ, 1);
/* At fixed rate mode, we start another thread for sending */
if (p->rate)
pthread_create(&p->sent_tid, NULL, &path_send, (void *) p);
@ -165,11 +164,10 @@ int path_stop(struct path *p)
pthread_join(p->sent_tid, NULL);
}
if (p->received) {
path_stats(p);
hist_plot(p->histogram, HIST_SEQ);
hist_dump(p->histogram, HIST_SEQ);
}
path_stats(p);
hist_plot(&p->histogram);
hist_dump(&p->histogram);
hist_free(&p->histogram);
return 0;
}

View file

@ -19,6 +19,7 @@
#include "msg.h"
#include "node.h"
#include "utils.h"
#include "hist.h"
static struct settings set;
static struct node *node;
@ -28,11 +29,6 @@ int running = 1;
#define CLOCK_ID CLOCK_MONOTONIC_RAW
#define RTT_MIN 20
#define RTT_MAX 100
#define RTT_RESOLUTION 2
#define RTT_HIST (int) ((RTT_MAX - RTT_MIN) / RTT_RESOLUTION)
void quit(int sig, siginfo_t *si, void *ptr)
{
running = 0;
@ -82,11 +78,9 @@ int main(int argc, char *argv[])
double rtt_max = LLONG_MIN;
double rtt_min = LLONG_MAX;
double avg = 0;
int bar;
unsigned hist[RTT_HIST];
memset(hist, 0, RTT_HIST * sizeof(unsigned));
struct hist histogram;
hist_init(&histogram, 0, 2e-4, 1e-5);
#if 1 /* Print header */
fprintf(stdout, "%17s", "timestamp");
@ -106,11 +100,8 @@ int main(int argc, char *argv[])
if (rtt < rtt_min) rtt_min = rtt;
avg += rtt;
/* Update histogram */
bar = (rtt * 1000 / RTT_RESOLUTION) - (RTT_MIN / RTT_RESOLUTION);
if (bar < RTT_HIST)
hist[bar]++;
hist_put(&histogram, rtt);
#if 1
struct timespec ts;
@ -125,8 +116,9 @@ int main(int argc, char *argv[])
free(ts2);
hist_plot(hist, RTT_HIST);
hist_dump(hist, RTT_HIST);
hist_plot(&histogram);
hist_dump(&histogram);
hist_free(&histogram);
}
node_stop(node);

View file

@ -103,49 +103,6 @@ struct timespec timespec_rate(double rate)
return ts;
}
void hist_plot(unsigned *hist, int length)
{
char buf[HIST_HEIGHT + 32];
int bar;
int max = 0;
/* Get max, first & last */
for (int i = 0; i < length; i++) {
if (hist[i] > hist[max])
max = i;
}
/* Print header */
info("%2s | %5s | %s", "Id", "Value", "Histogram Plot:");
/* Print plot */
memset(buf, '#', sizeof(buf));
for (int i = 0; i < length; i++) {
bar = HIST_HEIGHT * (float) hist[i] / hist[max];
if (hist[i] == 0)
info("%2u | " GRN("%5u") " | " , i, hist[i]);
else if (hist[i] == hist[max])
info("%2u | " RED("%5u") " | " BLD("%.*s"), i, hist[i], bar, buf);
else
info("%2u | " "%5u" " | " "%.*s", i, hist[i], bar, buf);
}
}
void hist_dump(unsigned *hist, int length)
{
char tok[16];
char buf[length * sizeof(tok)];
memset(buf, 0, sizeof(buf));
/* Print in Matlab vector format */
for (int i = 0; i < length; i++) {
snprintf(tok, sizeof(tok), "%u ", hist[i]);
strncat(buf, tok, sizeof(buf)-strlen(buf));
}
info("Matlab: hist = [ %s]", buf);
}
/** @todo: Proper way: create additional pipe for stderr in child process */
int system2(const char *cmd, ...)
{