* on creation.
*/
+void
+isc_stats_resize(isc_stats_t **stats, int ncounters);
+/*%<
+ * Resize a statistics counter structure of general type. The new set of
+ * counters are indexed by an ID between 0 and ncounters -1.
+ *
+ * Requires:
+ *\li 'stats' is a valid isc_stats_t.
+ *\li 'ncounters' is a non-zero positive number.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_STATS_H */
return (atomic_load_acquire(&stats->counters[counter]));
}
+
+void
+isc_stats_resize(isc_stats_t **statsp, int ncounters) {
+ isc_stats_t *stats;
+ size_t counters_alloc_size;
+ isc__atomic_statcounter_t *newcounters;
+
+ REQUIRE(statsp != NULL && *statsp != NULL);
+ REQUIRE(ISC_STATS_VALID(*statsp));
+ REQUIRE(ncounters > 0);
+
+ stats = *statsp;
+ if (stats->ncounters >= ncounters) {
+ /* We already have enough counters. */
+ return;
+ }
+
+ /* Grow number of counters. */
+ counters_alloc_size = sizeof(isc__atomic_statcounter_t) * ncounters;
+ newcounters = isc_mem_get(stats->mctx, counters_alloc_size);
+ for (int i = 0; i < ncounters; i++) {
+ atomic_init(&newcounters[i], 0);
+ }
+ for (int i = 0; i < stats->ncounters; i++) {
+ uint32_t counter = atomic_load_acquire(&stats->counters[i]);
+ atomic_store_release(&newcounters[i], counter);
+ }
+ isc_mem_put(stats->mctx, stats->counters,
+ sizeof(isc__atomic_statcounter_t) * stats->ncounters);
+ stats->counters = newcounters;
+ stats->ncounters = ncounters;
+}
assert_int_equal(isc_stats_get_counter(stats, i), i + 1);
}
+ /* Test resize. */
+ isc_stats_resize(&stats, 3);
+ assert_int_equal(isc_stats_ncounters(stats), 4);
+ isc_stats_resize(&stats, 4);
+ assert_int_equal(isc_stats_ncounters(stats), 4);
+ isc_stats_resize(&stats, 5);
+ assert_int_equal(isc_stats_ncounters(stats), 5);
+
+ /* Existing counters are retained */
+ for (int i = 0; i < isc_stats_ncounters(stats); i++) {
+ uint32_t expect = i + 1;
+ if (i == 4) {
+ expect = 0;
+ }
+ assert_int_equal(isc_stats_get_counter(stats, i), expect);
+ }
+
isc_stats_detach(&stats);
}