diff --git a/lib/isc/include/isc/stats.h b/lib/isc/include/isc/stats.h index 8f41bb95aa867b4c6a0af4b2c188c6d7a748ba8a..2c6f811785e297290e2f204db7873252e8d89fbb 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 255216d138c649d996b5d1afe92c395b2c9ec86f..1df53498a95d1d499701b29e593052d7f4212d2e 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 96097ff1bcb5ab520ad25584cc4dfa08fe6da94b..182a0217050f119df33c3faa72999695f1b0fa3f 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 4765cae2995e2b461c8a1b32771f0389c226cf2c..f456a971b0a2b112b329dc45071e98aea31c544a 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 b3769aece5b5c0c7e1498be4174e1cb6ad729f3c..745c3d73104dc754a82104a79f3a5440bae3da40 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 d47deaa6d5318cc3784ba1c870b58a805a4c4b40..d221b0d5b2e16763681ee572bb3b8bac664bd496 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