]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add a function isc_stats_resize
authorMatthijs Mekking <matthijs@isc.org>
Thu, 19 Aug 2021 11:38:51 +0000 (13:38 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Tue, 24 Aug 2021 07:07:15 +0000 (09:07 +0200)
Add a new function to resize the number of counters in a statistics
counter structure. This will be needed when we keep track of DNSSEC
sign statistics and new keys are introduced due to a rollover.

lib/isc/include/isc/stats.h
lib/isc/stats.c
lib/isc/tests/stats_test.c

index c2ab4e6c039b20b2cd4cc450df7b0b7b28ea45b6..f57aa1a96fa15396077b3d8e7053888a03bf6090 100644 (file)
@@ -238,6 +238,17 @@ isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter);
  *     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 */
index ab599b18afb9e401d99711e25333db32cfdc87a9..6297946cb29d203b9cfa709053497d547d79232b 100644 (file)
@@ -162,3 +162,35 @@ isc_stats_get_counter(isc_stats_t *stats, isc_statscounter_t counter) {
 
        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;
+}
index a212613143d6f205a81da33729bc08e2703b8b20..7b7476d3ad15a46648d6bc64211539deaa7e957c 100644 (file)
@@ -96,6 +96,23 @@ isc_stats_basic_test(void **state) {
                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);
 }