From 899d95791f7934b7bc8ede2175efb8673977e7a9 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 13 Aug 2021 11:29:16 -0400 Subject: [PATCH] TT#101150 add stats_counters_min_max() Change-Id: I9c3104718696a8e1fc69faee132f960209e80c15 --- include/aux.h | 24 ++++++++++++++++++++++++ include/statistics.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/aux.h b/include/aux.h index 2fb932348..95a055a84 100644 --- a/include/aux.h +++ b/include/aux.h @@ -532,6 +532,30 @@ INLINE void atomic64_local_copy_zero(atomic64 *dst, atomic64 *src) { #define atomic64_local_copy_zero_struct(d, s, member) \ atomic64_local_copy_zero(&((d)->member), &((s)->member)) +#define atomic64_min(min, val_expression) \ + do { \ + uint64_t __cur = val_expression; \ + do { \ + uint64_t __old = atomic64_get(min); \ + if (__old && __old <= __cur) \ + break; \ + if (atomic64_set_if(min, __cur, __old)) \ + break; \ + } while (1); \ + } while (0) + +#define atomic64_max(max, val_expression) \ + do { \ + uint64_t __cur = val_expression; \ + do { \ + uint64_t __old = atomic64_get(max); \ + if (__old && __old >= __cur) \ + break; \ + if (atomic64_set_if(max, __cur, __old)) \ + break; \ + } while (1); \ + } while (0) + diff --git a/include/statistics.h b/include/statistics.h index d1fda0da4..05fbee029 100644 --- a/include/statistics.h +++ b/include/statistics.h @@ -39,6 +39,12 @@ struct global_stats_ax { struct global_stats_counter ax; // running accumulator struct global_stats_counter intv; // last per-interval values }; +struct global_stats_min_max { + struct global_stats_counter min; + struct global_stats_counter max; + struct global_stats_counter avg; // sum while accumulation is running + atomic64 count; +}; struct request_time { @@ -153,6 +159,35 @@ INLINE void stats_counters_ax_calc_avg(struct global_stats_ax *stats, long long #undef F } +INLINE void stats_counters_min1(atomic64 *min, atomic64 *inp) { + atomic64_min(min, atomic64_get(inp)); +} +INLINE void stats_counters_max1(atomic64 *max, atomic64 *inp) { + atomic64_max(max, atomic64_get(inp)); +} +INLINE void stats_counters_min_max(struct global_stats_min_max *mm, struct global_stats_counter *inp) { +#define F(x) \ + stats_counters_min1(&mm->min.x, &inp->x); \ + stats_counters_max1(&mm->max.x, &inp->x); \ + atomic64_add(&mm->avg.x, atomic64_get(&inp->x)); +#include "counter_stats_fields.inc" +#undef F + atomic64_inc(&mm->count); +} +INLINE void stats_counters_min_max_reset(struct global_stats_min_max *mm, struct global_stats_min_max *loc) { + uint64_t count = atomic64_get_set(&mm->count, 0); + +#define F(x) \ + atomic64_set(&loc->min.x, atomic64_get_set(&mm->min.x, 0)); \ + atomic64_set(&loc->max.x, atomic64_get_set(&mm->max.x, 0)); \ + if (count) \ + atomic64_set(&loc->avg.x, atomic64_get_set(&mm->avg.x, 0) / count); \ + else \ + atomic64_set(&loc->avg.x, 0); +#include "counter_stats_fields.inc" +#undef F +} + void statistics_init(void); void statistics_free(void);