@@ -232,6 +232,40 @@ add_sample(struct stopwatch *sw, unsigned long long new_sample)
calc_average(&sw->long_term, new_sample);
}
+static bool
+performance_get_stats_protected(const char *name,
+ struct performance_stats *stats)
+{
+ struct performance *perf;
+
+ perf = shash_find_data(&performances, name);
+ if (!perf) {
+ return false;
+ }
+
+ stats->count = perf->samples;
+ stats->unit = perf->units;
+ stats->max = perf->max;
+ stats->min = perf->min;
+ stats->pctl_95 = perf->pctl.percentile;
+ stats->ewma_50 = perf->short_term.average;
+ stats->ewma_1 = perf->long_term.average;
+
+ return true;
+}
+
+bool
+performance_get_stats(const char *name, struct performance_stats *stats)
+{
+ bool found = false;
+
+ ovs_mutex_lock(&performances_lock);
+ found = performance_get_stats_protected(name, stats);
+ ovs_mutex_unlock(&performances_lock);
+
+ return found;
+}
+
static void
stopwatch_print(struct stopwatch *sw, const char *name,
struct ds *s)
@@ -24,6 +24,16 @@ enum stopwatch_units {
SW_NS,
};
+struct stopwatch_stats {
+ unsigned long long count; /* Total number of samples. */
+ enum stopwatch_units unit; /* Unit of following values. */
+ unsigned long long max; /* Maximum value. */
+ unsigned long long min; /* Minimum value. */
+ double pctl_95; /* 95th percentile. */
+ double ewma_50; /* Exponentially weighted moving average (alpha 0.50). */
+ double ewma_1; /* Exponentially weighted moving average (alpha 0.01). */
+};
+
/* Create a new stopwatch.
* The "units" are not used for any calculations but are printed when
* statistics are requested.
@@ -38,4 +48,7 @@ void stopwatch_start(const char *name, unsigned long long ts);
*/
void stopwatch_stop(const char *name, unsigned long long ts);
+/* Retrieve statistics calculated from collected samples */
+bool stopwatch_get_stats(const char *name, struct stopwatch_stats *stats);
+
#endif /* stopwatch.h */