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.
This commit is contained in:
Diego Fronza
2019-11-05 17:48:47 -03:00
committed by Ondřej Surý
parent eb5611a770
commit a544e2e300
6 changed files with 91 additions and 7 deletions

View File

@@ -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 */

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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 */

View File

@@ -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));
}

View File

@@ -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