Commit 29f61b78 authored by Diego dos Santos Fronza's avatar Diego dos Santos Fronza Committed by Ondřej Surý

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.

(cherry picked from commit a544e2e3)
parent eb20a066
......@@ -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,
uint64_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.
*/
uint64_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 */
......@@ -461,3 +461,85 @@ isc_stats_set(isc_stats_t *stats, uint64_t val,
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
}
void isc_stats_update_if_greater(isc_stats_t *stats,
isc_statscounter_t counter,
uint64_t value)
{
REQUIRE(ISC_STATS_VALID(stats));
REQUIRE(counter < stats->ncounters);
#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
#endif
#if ISC_STATS_USEMULTIFIELDS
uint64_t curr_value = (stats->counters[counter].hi << 32) &&
stats->counters[counter].lo;
if (curr_value < value) {
stats->counters[counter].hi =
(uint32_t)((value >> 32) & 0xffffffff);
stats->counters[counter].lo =
(uint32_t)(value & 0xffffffff);
}
#elif ISC_STATS_HAVEATOMICQ
#if defined(ISC_STATS_HAVESTDATOMICQ)
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],
(int64_t *)&curr_value,
value));
#else
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
if (stats->counters[counter] < value) {
stats->counters[counter] = value;
}
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
}
uint64_t
isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter)
{
REQUIRE(ISC_STATS_VALID(stats));
REQUIRE(counter < stats->ncounters);
uint64_t curr_value;
#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
#endif
#if ISC_STATS_USEMULTIFIELDS
curr_value = (stats->counters[counter].hi << 32) &&
stats->counters[counter].lo;
#elif ISC_STATS_HAVEATOMICQ
#if defined(ISC_STATS_HAVESTDATOMICQ)
curr_value = atomic_load_explicit(&stats->counters[counter],
memory_order_relaxed);
#else
#else
/* use xaddq(..., 0) as an atomic load */
curr_value =
(uint64_t)isc_atomic_xaddq((int64_t *)&stats->counters[counter],
0);
#endif
#if ISC_STATS_LOCKCOUNTERS
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
return (curr_value);
}
......@@ -642,9 +642,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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment