diff options
Diffstat (limited to 'src/core/counter.c')
-rw-r--r-- | src/core/counter.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/core/counter.c b/src/core/counter.c new file mode 100644 index 00000000..dace15f3 --- /dev/null +++ b/src/core/counter.c @@ -0,0 +1,108 @@ +/*! \file counter.c + * utility routines for keeping some statistics. */ +/* + * (C) 2009 by Harald Welte <laforge@gnumonks.org> + * + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <string.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/talloc.h> +#include <osmocom/core/counter.h> + +static LLIST_HEAD(counters); + +/*! Global talloc context for all osmo_counter allocations. */ +void *tall_ctr_ctx; + +/*! Allocate a new counter with given name. Allocates from tall_ctr_ctx + * \param[in] name Human-readable string name for the counter + * \returns Allocated counter on success; NULL on error */ +struct osmo_counter *osmo_counter_alloc(const char *name) +{ + struct osmo_counter *ctr = talloc_zero(tall_ctr_ctx, struct osmo_counter); + + if (!ctr) + return NULL; + + ctr->name = name; + llist_add_tail(&ctr->list, &counters); + + return ctr; +} + +/*! Release/Destroy a given counter + * \param[in] ctr Counter to be destroyed */ +void osmo_counter_free(struct osmo_counter *ctr) +{ + llist_del(&ctr->list); + talloc_free(ctr); +} + +/*! Iterate over all counters; call \a handle_cunter call-back for each. + * \param[in] handle_counter Call-back to be called for each counter; aborts if rc < 0 + * \param[in] data Opaque data passed through to \a handle_counter function + * \returns 0 if all \a handle_counter calls successfull; negative on error */ +int osmo_counters_for_each(int (*handle_counter)(struct osmo_counter *, void *), + void *data) +{ + struct osmo_counter *ctr; + int rc = 0; + + llist_for_each_entry(ctr, &counters, list) { + rc = handle_counter(ctr, data); + if (rc < 0) + return rc; + } + + return rc; +} + +/*! Counts the registered counter + * \returns amount of counters */ +int osmo_counters_count(void) +{ + return llist_count(&counters); +} + +/*! Find a counter by its name. + * \param[in] name Name used to look-up/search counter + * \returns Counter on success; NULL if not found */ +struct osmo_counter *osmo_counter_get_by_name(const char *name) +{ + struct osmo_counter *ctr; + + llist_for_each_entry(ctr, &counters, list) { + if (!strcmp(ctr->name, name)) + return ctr; + } + return NULL; +} + +/*! Compute difference between current and previous counter value. + * \param[in] ctr Counter of which the difference is to be computed + * \returns Delta value between current counter and previous counter. Please + * note that the actual counter values are unsigned long, while the + * difference is computed as signed integer! */ +int osmo_counter_difference(struct osmo_counter *ctr) +{ + int delta = ctr->value - ctr->previous; + ctr->previous = ctr->value; + + return delta; +} |