stats.c revision 1.4 1 1.4 christos /* $NetBSD: stats.c,v 1.4 2019/11/27 05:48:43 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public
7 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this
8 1.1 christos * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 1.1 christos *
10 1.1 christos * See the COPYRIGHT file distributed with this work for additional
11 1.1 christos * information regarding copyright ownership.
12 1.1 christos */
13 1.1 christos
14 1.1 christos /*! \file */
15 1.1 christos
16 1.1 christos #include <config.h>
17 1.1 christos
18 1.1 christos #include <isc/magic.h>
19 1.1 christos #include <isc/mem.h>
20 1.1 christos #include <isc/stats.h>
21 1.1 christos #include <isc/util.h>
22 1.1 christos
23 1.1 christos #include <ns/stats.h>
24 1.1 christos
25 1.1 christos #define NS_STATS_MAGIC ISC_MAGIC('N', 's', 't', 't')
26 1.1 christos #define NS_STATS_VALID(x) ISC_MAGIC_VALID(x, NS_STATS_MAGIC)
27 1.1 christos
28 1.1 christos struct ns_stats {
29 1.1 christos /*% Unlocked */
30 1.1 christos unsigned int magic;
31 1.1 christos isc_mem_t *mctx;
32 1.1 christos isc_mutex_t lock;
33 1.1 christos isc_stats_t *counters;
34 1.1 christos
35 1.1 christos /*% Locked by lock */
36 1.1 christos unsigned int references;
37 1.1 christos };
38 1.1 christos
39 1.1 christos void
40 1.1 christos ns_stats_attach(ns_stats_t *stats, ns_stats_t **statsp) {
41 1.1 christos REQUIRE(NS_STATS_VALID(stats));
42 1.1 christos REQUIRE(statsp != NULL && *statsp == NULL);
43 1.1 christos
44 1.1 christos LOCK(&stats->lock);
45 1.1 christos stats->references++;
46 1.1 christos UNLOCK(&stats->lock);
47 1.1 christos
48 1.1 christos *statsp = stats;
49 1.1 christos }
50 1.1 christos
51 1.1 christos void
52 1.1 christos ns_stats_detach(ns_stats_t **statsp) {
53 1.1 christos ns_stats_t *stats;
54 1.1 christos
55 1.1 christos REQUIRE(statsp != NULL && NS_STATS_VALID(*statsp));
56 1.1 christos
57 1.1 christos stats = *statsp;
58 1.1 christos *statsp = NULL;
59 1.1 christos
60 1.1 christos LOCK(&stats->lock);
61 1.1 christos stats->references--;
62 1.1 christos UNLOCK(&stats->lock);
63 1.1 christos
64 1.1 christos if (stats->references == 0) {
65 1.1 christos isc_stats_detach(&stats->counters);
66 1.3 christos isc_mutex_destroy(&stats->lock);
67 1.1 christos isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
68 1.1 christos }
69 1.1 christos }
70 1.1 christos
71 1.1 christos isc_result_t
72 1.1 christos ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp) {
73 1.1 christos ns_stats_t *stats;
74 1.1 christos isc_result_t result;
75 1.1 christos
76 1.1 christos REQUIRE(statsp != NULL && *statsp == NULL);
77 1.1 christos
78 1.1 christos stats = isc_mem_get(mctx, sizeof(*stats));
79 1.1 christos if (stats == NULL)
80 1.1 christos return (ISC_R_NOMEMORY);
81 1.1 christos
82 1.1 christos stats->counters = NULL;
83 1.1 christos stats->references = 1;
84 1.1 christos
85 1.3 christos isc_mutex_init(&stats->lock);
86 1.1 christos
87 1.1 christos result = isc_stats_create(mctx, &stats->counters, ncounters);
88 1.1 christos if (result != ISC_R_SUCCESS)
89 1.1 christos goto clean_mutex;
90 1.1 christos
91 1.1 christos stats->magic = NS_STATS_MAGIC;
92 1.1 christos stats->mctx = NULL;
93 1.1 christos isc_mem_attach(mctx, &stats->mctx);
94 1.1 christos *statsp = stats;
95 1.1 christos
96 1.1 christos return (ISC_R_SUCCESS);
97 1.1 christos
98 1.1 christos clean_mutex:
99 1.3 christos isc_mutex_destroy(&stats->lock);
100 1.1 christos isc_mem_put(mctx, stats, sizeof(*stats));
101 1.1 christos
102 1.1 christos return (result);
103 1.1 christos }
104 1.1 christos
105 1.1 christos /*%
106 1.1 christos * Increment/Decrement methods
107 1.1 christos */
108 1.1 christos void
109 1.1 christos ns_stats_increment(ns_stats_t *stats, isc_statscounter_t counter) {
110 1.1 christos REQUIRE(NS_STATS_VALID(stats));
111 1.1 christos
112 1.1 christos isc_stats_increment(stats->counters, counter);
113 1.1 christos }
114 1.1 christos
115 1.1 christos void
116 1.1 christos ns_stats_decrement(ns_stats_t *stats, isc_statscounter_t counter) {
117 1.1 christos REQUIRE(NS_STATS_VALID(stats));
118 1.1 christos
119 1.1 christos isc_stats_decrement(stats->counters, counter);
120 1.1 christos }
121 1.1 christos
122 1.1 christos isc_stats_t *
123 1.1 christos ns_stats_get(ns_stats_t *stats) {
124 1.1 christos REQUIRE(NS_STATS_VALID(stats));
125 1.1 christos
126 1.1 christos return (stats->counters);
127 1.1 christos }
128 1.4 christos
129 1.4 christos void ns_stats_update_if_greater(ns_stats_t *stats,
130 1.4 christos isc_statscounter_t counter,
131 1.4 christos isc_statscounter_t value)
132 1.4 christos {
133 1.4 christos REQUIRE(NS_STATS_VALID(stats));
134 1.4 christos
135 1.4 christos isc_stats_update_if_greater(stats->counters, counter, value);
136 1.4 christos }
137 1.4 christos
138 1.4 christos isc_statscounter_t
139 1.4 christos ns_stats_get_counter(ns_stats_t *stats, isc_statscounter_t counter)
140 1.4 christos {
141 1.4 christos REQUIRE(NS_STATS_VALID(stats));
142 1.4 christos
143 1.4 christos return (isc_stats_get_counter(stats->counters, counter));
144 1.4 christos }
145