diff --git a/include/villas/hooks.h b/include/villas/hooks.h index f87f228d1..f88635a21 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -112,7 +112,7 @@ enum hook_type { /** All path related actions */ HOOK_PATH = HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART, /** Hooks which are used to collect statistics. */ - HOOK_STATS = HOOK_INTERNAL | HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC, + HOOK_STATS = HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC, /** @} */ }; diff --git a/include/villas/path.h b/include/villas/path.h index 7bf71a003..c9e5104aa 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -67,7 +67,7 @@ struct path char *_name; /**< Singleton: A string which is used to print this path to screen. */ - struct stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ + struct stats_delta *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ }; diff --git a/include/villas/stats.h b/include/villas/stats.h index f5c4178c5..dc69beb41 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -34,7 +34,9 @@ enum stats_id { }; struct stats_delta { - double vals[STATS_COUNT]; + double values[STATS_COUNT]; + + struct sample *last; }; struct stats { @@ -47,14 +49,12 @@ int stats_init(struct stats *s); void stats_destroy(struct stats *s); -void stats_update(struct stats *s, enum stats_id id, double val); +void stats_update(struct stats_delta *s, enum stats_id id, double val); + +void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt); int stats_commit(struct stats *s, struct stats_delta *d); -void stats_collect(struct stats *s, struct sample *smps[], size_t cnt); - -void stats_decollect(struct stats *s, struct sample *smps[], size_t cnt); - #ifdef WITH_JANSSON json_t * stats_json(struct stats *s); #endif diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index 5ce5cf705..81673a3c3 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -76,8 +76,9 @@ int hook_drop(struct hook *h, int when, struct hook_info *j) if (h->prev) { dist = h->last->sequence - (int32_t) h->prev->sequence; if (dist <= 0) { - stats_update(j->path->stats, STATS_DROPPED, dist); warn("Dropped sample: dist = %d, i = %d", dist, i); + if (j->path) + stats_update(j->path->stats, STATS_DROPPED, dist); } else { struct sample *tmp; diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index e0139efff..f9fb97b7f 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -22,8 +22,9 @@ int hook_stats(struct hook *h, int when, struct hook_info *j) switch (when) { case HOOK_READ: assert(j->smps); + assert(j->path); - stats_collect(s, j->smps, j->cnt); + stats_collect(j->path->stats, j->smps, j->cnt); break; case HOOK_PATH_STOP: diff --git a/lib/stats.c b/lib/stats.c index e62dda812..6441edf85 100644 --- a/lib/stats.c +++ b/lib/stats.c @@ -48,54 +48,42 @@ void stats_destroy(struct stats *s) } } -void stats_update(struct stats *s, enum stats_id id, double val) +void stats_update(struct stats_delta *d, enum stats_id id, double val) { - if (!s) - return; - - hist_put(&s->histograms[id], val); + if (d && id >= 0 && id < STATS_COUNT) + d->values[id] = val; } -#if 0 -int stats_delta(struct stats_delta *d, struct sample *s, struct sample *p) -{ - d->histogram.owd = time_delta(&smps[i]->ts.origin, &smps[i]->ts.received); - d->histogram.gap = time_delta(&s->last->ts.origin, &smps[i]->ts.origin); - d->histogram.gap_seq = s->sequence - (int32_t) p->sequence; - d->histogram.gap_recv = time_delta(&s->last->ts.received, &smps[i]->ts.received); - - d->counter.dropped = d->histogram.gap_seq <= 0 ? 1 : 0; - d->counter.invalid = 0; - - return 0; -} -#endif - int stats_commit(struct stats *s, struct stats_delta *d) { for (int i = 0; i < STATS_COUNT; i++) { - hist_put(&s->histograms[i], d->vals[i]); + hist_put(&s->histograms[i], d->values[i]); } return 0; } -void stats_collect(struct stats *s, struct sample *smps[], size_t cnt) +void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt) { - for (int i = 0; i < cnt; i++) { - if (s->last) { -// struct stats_delta d; -// stats_get_delta(&d, smps[i], s->last); -// stats_commit(s, &d); + struct sample *previous = s->last; + + if (previous) { + sample_put(previous); + + for (int i = 0; i < cnt; i++) { + stats_update(s, STATS_GAP_RECEIVED, time_delta(&previous->ts.received, &smps[i]->ts.received)); + stats_update(s, STATS_GAP_SAMPLE, time_delta(&previous->ts.origin, &smps[i]->ts.origin)); + stats_update(s, STATS_OWD, time_delta(&smps[i]->ts.origin, &smps[i]->ts.received)); + stats_update(s, STATS_GAP_SEQUENCE, smps[i]->sequence - (int32_t) previous->sequence); + + /* Make sure there is always a reference to the previous sample */ + + previous = smps[i]; } - - if (i == 0 && s->last) - sample_put(s->last); - if (i == cnt - 1) - sample_get(smps[i]); - - s->last = smps[i]; } + + sample_get(previous); + s->last = previous; } #ifdef WITH_JANSSON