From a544e2e3006cf426b4125a892ae828137d692e6b Mon Sep 17 00:00:00 2001 From: Diego Fronza Date: Tue, 5 Nov 2019 17:48:47 -0300 Subject: [PATCH] Add functions for collecting high-water counters Add {isc,ns}_stats_{update_if_greater,get_counter}() functions that are used to set and collect high-water type of statistics. --- lib/isc/include/isc/stats.h | 25 +++++++++++++++++++++ lib/isc/stats.c | 45 +++++++++++++++++++++++++++++++------ lib/isc/win32/libisc.def.in | 2 ++ lib/ns/include/ns/stats.h | 7 ++++++ lib/ns/stats.c | 17 ++++++++++++++ lib/ns/win32/libns.def | 2 ++ 6 files changed, 91 insertions(+), 7 deletions(-) diff --git a/lib/isc/include/isc/stats.h b/lib/isc/include/isc/stats.h index 8f41bb95aa..2c6f811785 100644 --- a/lib/isc/include/isc/stats.h +++ b/lib/isc/include/isc/stats.h @@ -132,6 +132,31 @@ isc_stats_set(isc_stats_t *stats, uint64_t val, *\li 'stats' is a valid isc_stats_t. */ +void isc_stats_update_if_greater(isc_stats_t *stats, + isc_statscounter_t counter, + isc_statscounter_t value); +/*%< +* Atomically assigns 'value' to 'counter' if value > counter. +* +* Requires: +*\li 'stats' is a valid isc_stats_t. +* +*\li counter is less than the maximum available ID for the stats specified +* on creation. +*/ + +isc_statscounter_t +isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter); +/*%< + * Returns value currently stored in counter. + * + * Requires: + *\li 'stats' is a valid isc_stats_t. + * + *\li counter is less than the maximum available ID for the stats specified + * on creation. + */ + ISC_LANG_ENDDECLS #endif /* ISC_STATS_H */ diff --git a/lib/isc/stats.c b/lib/isc/stats.c index 255216d138..1df53498a9 100644 --- a/lib/isc/stats.c +++ b/lib/isc/stats.c @@ -29,17 +29,17 @@ #define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC) #if defined(_WIN32) && !defined(_WIN64) - typedef atomic_int_fast32_t isc__atomic_statcounter_t; +typedef atomic_int_fast32_t isc_stat_t; #else - typedef atomic_int_fast64_t isc__atomic_statcounter_t; +typedef atomic_int_fast64_t isc_stat_t; #endif struct isc_stats { - unsigned int magic; - isc_mem_t *mctx; - isc_refcount_t references; - int ncounters; - isc__atomic_statcounter_t *counters; + unsigned int magic; + isc_mem_t *mctx; + isc_refcount_t references; + int ncounters; + isc_stat_t *counters; }; static isc_result_t @@ -149,3 +149,34 @@ isc_stats_set(isc_stats_t *stats, uint64_t val, atomic_store_explicit(&stats->counters[counter], val, memory_order_relaxed); } + +void isc_stats_update_if_greater(isc_stats_t *stats, + isc_statscounter_t counter, + isc_statscounter_t value) +{ + REQUIRE(ISC_STATS_VALID(stats)); + REQUIRE(counter < stats->ncounters); + + isc_statscounter_t curr_value; + + do { + curr_value = atomic_load_explicit(&stats->counters[counter], + memory_order_relaxed); + if (curr_value >= value) { + break; + } + + } while (!atomic_compare_exchange_strong(&stats->counters[counter], + &curr_value, + value)); +} + +isc_statscounter_t +isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter) +{ + REQUIRE(ISC_STATS_VALID(stats)); + REQUIRE(counter < stats->ncounters); + + return (atomic_load_explicit(&stats->counters[counter], + memory_order_relaxed)); +} diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 96097ff1bc..182a021705 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -532,9 +532,11 @@ isc_stats_create isc_stats_decrement isc_stats_detach isc_stats_dump +isc_stats_get_counter isc_stats_increment isc_stats_ncounters isc_stats_set +isc_stats_update_if_greater isc_stdio_close isc_stdio_flush isc_stdio_open diff --git a/lib/ns/include/ns/stats.h b/lib/ns/include/ns/stats.h index 4765cae299..f456a971b0 100644 --- a/lib/ns/include/ns/stats.h +++ b/lib/ns/include/ns/stats.h @@ -123,4 +123,11 @@ ns_stats_decrement(ns_stats_t *stats, isc_statscounter_t counter); isc_stats_t * ns_stats_get(ns_stats_t *stats); +void ns_stats_update_if_greater(ns_stats_t *stats, + isc_statscounter_t counter, + isc_statscounter_t value); + +isc_statscounter_t +ns_stats_get_counter(ns_stats_t *stats, isc_statscounter_t counter); + #endif /* NS_STATS_H */ diff --git a/lib/ns/stats.c b/lib/ns/stats.c index b3769aece5..745c3d7310 100644 --- a/lib/ns/stats.c +++ b/lib/ns/stats.c @@ -109,3 +109,20 @@ ns_stats_get(ns_stats_t *stats) { return (stats->counters); } + +void ns_stats_update_if_greater(ns_stats_t *stats, + isc_statscounter_t counter, + isc_statscounter_t value) +{ + REQUIRE(NS_STATS_VALID(stats)); + + isc_stats_update_if_greater(stats->counters, counter, value); +} + +isc_statscounter_t +ns_stats_get_counter(ns_stats_t *stats, isc_statscounter_t counter) +{ + REQUIRE(NS_STATS_VALID(stats)); + + return (isc_stats_get_counter(stats->counters, counter)); +} diff --git a/lib/ns/win32/libns.def b/lib/ns/win32/libns.def index d47deaa6d5..d221b0d5b2 100644 --- a/lib/ns/win32/libns.def +++ b/lib/ns/win32/libns.def @@ -102,6 +102,8 @@ ns_stats_create ns_stats_decrement ns_stats_detach ns_stats_get +ns_stats_get_counter ns_stats_increment +ns_stats_update_if_greater ns_update_start ns_xfr_start -- GitLab