subsys: stats - Statistics support
Implements the definition, manipulation, and delivery of statistics. Signed-off-by: Christopher Collins <ccollins@apache.org>
This commit is contained in:
parent
3986ef2770
commit
5ed30f0360
386
include/stats.h
Normal file
386
include/stats.h
Normal file
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
* Copyright Runtime.io 2018. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Statistics.
|
||||
*
|
||||
* Statistics are per-module event counters for troubleshooting, maintenance,
|
||||
* and usage monitoring. Statistics are organized into named "groups", with
|
||||
* each group consisting of a set of "entries". An entry corresponds to an
|
||||
* individual counter. Each entry can optionally be named if the STATS_NAMES
|
||||
* setting is enabled. Statistics can be retrieved with the mcumgr management
|
||||
* subsystem.
|
||||
*
|
||||
* There are two, largely duplicated, statistics sections here, in order to
|
||||
* provide the optional ability to name statistics.
|
||||
*
|
||||
* STATS_SECT_START/END actually declare the statistics structure definition,
|
||||
* STATS_SECT_DECL() creates the structure declaration so you can declare
|
||||
* these statistics as a global structure, and STATS_NAME_START/END are how
|
||||
* you name the statistics themselves.
|
||||
*
|
||||
* Statistics entries can be declared as any of several integer types.
|
||||
* However, all statistics in a given structure must be of the same size, and
|
||||
* they are all unsigned.
|
||||
*
|
||||
* - STATS_SECT_ENTRY(): default statistic entry, 32-bits.
|
||||
*
|
||||
* - STATS_SECT_ENTRY16(): 16-bits. Smaller statistics if you need to fit into
|
||||
* specific RAM or code size numbers.
|
||||
*
|
||||
* - STATS_SECT_ENTRY32(): 32-bits.
|
||||
*
|
||||
* - STATS_SECT_ENTRY64(): 64-bits. Useful for storing chunks of data.
|
||||
*
|
||||
* Following the static entry declaration is the statistic names declaration.
|
||||
* This is compiled out when the CONFIGURE_STATS_NAME setting is undefined.
|
||||
*
|
||||
* When CONFIG_STATS_NAMES is defined, the statistics names are stored and
|
||||
* returned to the management APIs. When the setting is undefined, temporary
|
||||
* names are generated as needed with the following format:
|
||||
*
|
||||
* s<stat-idx>
|
||||
*
|
||||
* E.g., "s0", "s1", etc.
|
||||
*/
|
||||
|
||||
#ifndef H_STATS_
|
||||
#define H_STATS_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct stats_name_map {
|
||||
u16_t snm_off;
|
||||
const char *snm_name;
|
||||
} __packed;
|
||||
|
||||
struct stats_hdr {
|
||||
const char *s_name;
|
||||
u8_t s_size;
|
||||
u8_t s_cnt;
|
||||
u16_t s_pad1;
|
||||
#ifdef CONFIG_STATS_NAMES
|
||||
const struct stats_name_map *s_map;
|
||||
int s_map_cnt;
|
||||
#endif
|
||||
struct stats_hdr *s_next;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Declares a stat group struct.
|
||||
*
|
||||
* @param group__ The name to assign to the structure tag.
|
||||
*/
|
||||
#define STATS_SECT_DECL(group__) \
|
||||
struct stats_ ## group__
|
||||
|
||||
/**
|
||||
* @brief Ends a stats group struct definition.
|
||||
*/
|
||||
#define STATS_SECT_END }
|
||||
|
||||
/* The following macros depend on whether CONFIG_STATS is defined. If it is
|
||||
* not defined, then invocations of these macros get compiled out.
|
||||
*/
|
||||
#ifdef CONFIG_STATS
|
||||
|
||||
/**
|
||||
* @brief Begins a stats group struct definition.
|
||||
*
|
||||
* @param group__ The stats group struct name.
|
||||
*/
|
||||
#define STATS_SECT_START(group__) \
|
||||
STATS_SECT_DECL(group__) { \
|
||||
struct stats_hdr s_hdr;
|
||||
|
||||
/**
|
||||
* @brief Declares a 32-bit stat entry inside a group struct.
|
||||
*
|
||||
* @param var__ The name ot assign to the entry.
|
||||
*/
|
||||
#define STATS_SECT_ENTRY(var__) u32_t var__;
|
||||
|
||||
/**
|
||||
* @brief Declares a 16-bit stat entry inside a group struct.
|
||||
*
|
||||
* @param var__ The name ot assign to the entry.
|
||||
*/
|
||||
#define STATS_SECT_ENTRY16(var__) u16_t var__;
|
||||
|
||||
/**
|
||||
* @brief Declares a 32-bit stat entry inside a group struct.
|
||||
*
|
||||
* @param var__ The name ot assign to the entry.
|
||||
*/
|
||||
#define STATS_SECT_ENTRY32(var__) u32_t var__;
|
||||
|
||||
/**
|
||||
* @brief Declares a 64-bit stat entry inside a group struct.
|
||||
*
|
||||
* @param var__ The name ot assign to the entry.
|
||||
*/
|
||||
#define STATS_SECT_ENTRY64(var__) u64_t var__;
|
||||
|
||||
/**
|
||||
* @brief Increases a statistic entry by the specified amount.
|
||||
*
|
||||
* Increases a statistic entry by the specified amount. Compiled out if
|
||||
* CONFIG_STATS is not defined.
|
||||
*
|
||||
* @param group__ The group containing the entry to increase.
|
||||
* @param var__ The statistic entry to increase.
|
||||
* @param n__ The amount to increase the statistic entry by.
|
||||
*/
|
||||
#define STATS_INCN(group__, var__, n__) \
|
||||
((group__).var__ += (n__))
|
||||
|
||||
/**
|
||||
* @brief Increments a statistic entry.
|
||||
*
|
||||
* Increments a statistic entry by one. Compiled out if CONFIG_STATS is not
|
||||
* defined.
|
||||
*
|
||||
* @param group__ The group containing the entry to increase.
|
||||
* @param var__ The statistic entry to increase.
|
||||
*/
|
||||
#define STATS_INC(group__, var__) \
|
||||
STATS_INCN(group__, var__, 1)
|
||||
|
||||
/**
|
||||
* @brief Sets a statistic entry to zero.
|
||||
*
|
||||
* Sets a statistic entry to zero. Compiled out if CONFIG_STATS is not
|
||||
* defined.
|
||||
*
|
||||
* @param group__ The group containing the entry to clear.
|
||||
* @param var__ The statistic entry to clear.
|
||||
*/
|
||||
#define STATS_CLEAR(group__, var__) \
|
||||
((group__).var__ = 0)
|
||||
|
||||
#define STATS_SIZE_16 (sizeof(u16_t))
|
||||
#define STATS_SIZE_32 (sizeof(u32_t))
|
||||
#define STATS_SIZE_64 (sizeof(u64_t))
|
||||
|
||||
#define STATS_SIZE_INIT_PARMS(group__, size__) \
|
||||
(size__), \
|
||||
((sizeof(group__)) - sizeof(struct stats_hdr)) / (size__)
|
||||
|
||||
/**
|
||||
* @brief Initializes and registers a statistics group.
|
||||
*
|
||||
* @param group__ The statistics group to initialize and
|
||||
* register.
|
||||
* @param size__ The size of each entry in the statistics group,
|
||||
* in bytes. Must be one of: 2 (16-bits), 4
|
||||
* (32-bits) or 8 (64-bits).
|
||||
* @param name__ The name of the statistics group to register.
|
||||
* This name must be unique among all
|
||||
* statistics groups.
|
||||
*
|
||||
* @return 0 on success; negative error code on failure.
|
||||
*/
|
||||
#define STATS_INIT_AND_REG(group__, size__, name__) \
|
||||
stats_init_and_reg( \
|
||||
&(group__).s_hdr, \
|
||||
(size__), \
|
||||
(sizeof(group__) - sizeof(struct stats_hdr)) / (size__), \
|
||||
STATS_NAME_INIT_PARMS(group__), \
|
||||
(name__))
|
||||
|
||||
/**
|
||||
* @brief Initializes a statistics group.
|
||||
*
|
||||
* @param hdr The header of the statistics structure,
|
||||
* contains things like statistic section
|
||||
* name, size of statistics entries, number of
|
||||
* statistics, etc.
|
||||
* @param size The size of each individual statistics
|
||||
* element, in bytes. Must be one of: 2
|
||||
* (16-bits), 4 (32-bits) or 8 (64-bits).
|
||||
* @param cnt The number of elements in the stats group.
|
||||
* @param map The mapping of stat offset to name.
|
||||
* @param map_cnt The number of items in the statistics map
|
||||
*
|
||||
* @param group__ The group containing the entry to clear.
|
||||
* @param var__ The statistic entry to clear.
|
||||
*/
|
||||
void stats_init(struct stats_hdr *shdr, uint8_t size, uint8_t cnt,
|
||||
const struct stats_name_map *map, uint8_t map_cnt);
|
||||
|
||||
/**
|
||||
* @brief Registers a statistics group to be managed.
|
||||
*
|
||||
* @param name The name of the statistics group to register.
|
||||
* This name must be unique among all
|
||||
* statistics groups. If the name is a
|
||||
* duplicate, this function will return
|
||||
* -EALREADY.
|
||||
* @param shdr The statistics group to register.
|
||||
*
|
||||
* @return 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int stats_register(const char *name, struct stats_hdr *shdr);
|
||||
|
||||
/**
|
||||
* @brief Initializes and registers a statistics group.
|
||||
*
|
||||
* Initializes and registers a statistics group. Note: it is recommended to
|
||||
* use the STATS_INIT_AND_REG macro instead of this function.
|
||||
*
|
||||
* @param hdr The header of the statistics group to
|
||||
* initialize and register.
|
||||
* @param size The size of each individual statistics
|
||||
* element, in bytes. Must be one of: 2
|
||||
* (16-bits), 4 (32-bits) or 8 (64-bits).
|
||||
* @param cnt The number of elements in the stats group.
|
||||
* @param map The mapping of stat offset to name.
|
||||
* @param map_cnt The number of items in the statistics map
|
||||
* @param name The name of the statistics group to register.
|
||||
* This name must be unique among all
|
||||
* statistics groups. If the name is a
|
||||
* duplicate, this function will return
|
||||
* -EALREADY.
|
||||
*
|
||||
* @return 0 on success; negative error code on failure.
|
||||
*
|
||||
* @see STATS_INIT_AND_REG
|
||||
*/
|
||||
int stats_init_and_reg(struct stats_hdr *hdr, uint8_t size, uint8_t cnt,
|
||||
const struct stats_name_map *map, uint8_t map_cnt,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Zeroes the specified statistics group.
|
||||
*
|
||||
* @param shdr The statistics group to clear.
|
||||
*/
|
||||
void stats_reset(struct stats_hdr *shdr);
|
||||
|
||||
/** @typedef stats_walk_fn
|
||||
* @brief Function that gets applied to every stat entry during a walk.
|
||||
*
|
||||
* @param hdr The group containing the stat entry being
|
||||
* walked.
|
||||
* @param arg Optional argument.
|
||||
* @param name The name of the statistic entry to process
|
||||
* @param off The offset of the entry, from `hdr`.
|
||||
*
|
||||
* @return 0 if the walk should proceed;
|
||||
* nonzero to abort the walk.
|
||||
*/
|
||||
typedef int stats_walk_fn(struct stats_hdr *hdr, void *arg,
|
||||
const char *name, uint16_t off);
|
||||
|
||||
/**
|
||||
* @brief Applies a function to every stat entry in a group.
|
||||
*
|
||||
* @param hdr The stats group to operate on.
|
||||
* @param walk_cb The function to apply to each stat entry.
|
||||
* @param arg Optional argument to pass to the callback.
|
||||
*
|
||||
* @return 0 if the walk completed;
|
||||
* nonzero if the walk was aborted.
|
||||
*/
|
||||
int stats_walk(struct stats_hdr *hdr, stats_walk_fn *walk_cb, void *arg);
|
||||
|
||||
/** @typedef stats_group_walk_fn
|
||||
* @brief Function that gets applied to every registered stats group.
|
||||
*
|
||||
* @param hdr The stats group being walked.
|
||||
* @param arg Optional argument.
|
||||
*
|
||||
* @return 0 if the walk should proceed;
|
||||
* nonzero to abort the walk.
|
||||
*/
|
||||
typedef int stats_group_walk_fn(struct stats_hdr *hdr, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Applies a function every registered statistics group.
|
||||
*
|
||||
* @param walk_cb The function to apply to each stat group.
|
||||
* @param arg Optional argument to pass to the callback.
|
||||
*
|
||||
* @return 0 if the walk completed;
|
||||
* nonzero if the walk was aborted.
|
||||
*/
|
||||
int stats_group_walk(stats_group_walk_fn *walk_cb, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the next registered statistics group.
|
||||
*
|
||||
* @param cur The group whose sucessor is being retrieved, or
|
||||
* NULL to retrieve the first group.
|
||||
*
|
||||
* @return Pointer to the retrieved group on success;
|
||||
* NULL if no more groups remain.
|
||||
*/
|
||||
struct stats_hdr *stats_group_get_next(const struct stats_hdr *cur);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the statistics group with the specified name.
|
||||
*
|
||||
* @param name The name of the statistics group to look up.
|
||||
*
|
||||
* @return Pointer to the retrieved group on success;
|
||||
* NULL if there is no matching registered group.
|
||||
*/
|
||||
struct stats_hdr *stats_group_find(const char *name);
|
||||
|
||||
#else /* CONFIG_STATS */
|
||||
|
||||
#define STATS_SECT_START(group__) \
|
||||
STATS_SECT_DECL(group__) {
|
||||
|
||||
#define STATS_SECT_ENTRY(var__)
|
||||
#define STATS_SECT_ENTRY16(var__)
|
||||
#define STATS_SECT_ENTRY32(var__)
|
||||
#define STATS_SECT_ENTRY64(var__)
|
||||
#define STATS_RESET(var__)
|
||||
#define STATS_SIZE_INIT_PARMS(group__, size__)
|
||||
#define STATS_INCN(group__, var__, n__)
|
||||
#define STATS_INC(group__, var__)
|
||||
#define STATS_CLEAR(group__, var__)
|
||||
#define STATS_INIT_AND_REG(group__, size__, name__) (0)
|
||||
|
||||
#endif /* !CONFIG_STATS */
|
||||
|
||||
#ifdef CONFIG_STATS_NAMES
|
||||
|
||||
#define STATS_NAME_MAP_NAME(sectname__) stats_map_ ## sectname__
|
||||
|
||||
#define STATS_NAME_START(sectname__) \
|
||||
const struct stats_name_map STATS_NAME_MAP_NAME(sectname__)[] = {
|
||||
|
||||
#define STATS_NAME(sectname__, entry__) \
|
||||
{ offsetof(STATS_SECT_DECL(sectname__), entry__), #entry__ },
|
||||
|
||||
#define STATS_NAME_END(sectname__) }
|
||||
|
||||
#define STATS_NAME_INIT_PARMS(name__) \
|
||||
&(STATS_NAME_MAP_NAME(name__)[0]), \
|
||||
(sizeof(STATS_NAME_MAP_NAME(name__)) / sizeof(struct stats_name_map))
|
||||
|
||||
#else /* CONFIG_STATS_NAMES */
|
||||
|
||||
#define STATS_NAME_START(name__)
|
||||
#define STATS_NAME(name__, entry__)
|
||||
#define STATS_NAME_END(name__)
|
||||
#define STATS_NAME_INIT_PARMS(name__) NULL, 0
|
||||
|
||||
#endif /* CONFIG_STATS_NAMES */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_STATS_ */
|
|
@ -1,2 +1,3 @@
|
|||
zephyr_sources_if_kconfig(printk.c)
|
||||
zephyr_sources_if_kconfig(reboot.c)
|
||||
zephyr_sources_if_kconfig(stats.c)
|
||||
|
|
19
misc/Kconfig
19
misc/Kconfig
|
@ -288,6 +288,25 @@ config CPU_CLOCK_FREQ_MHZ
|
|||
This option specifies the CPU Clock Frequency in MHz in order to
|
||||
convert Intel RDTSC timestamp to microseconds.
|
||||
|
||||
config STATS
|
||||
bool
|
||||
prompt "Statistics support"
|
||||
default n
|
||||
help
|
||||
Enable per-module event counters for troubleshooting, maintenance,
|
||||
and usage monitoring. Statistics can be retrieved with the mcumgr
|
||||
management subsystem.
|
||||
|
||||
config STATS_NAMES
|
||||
bool
|
||||
prompt "Statistic names"
|
||||
depends on STATS
|
||||
default n
|
||||
help
|
||||
Include a full name string for each statistic in the build. If this
|
||||
setting is disabled, statistics are assigned generic names of the
|
||||
form "s0", "s1", etc. Enabling this setting simplifies debugging,
|
||||
but results in a larger code size.
|
||||
endmenu
|
||||
|
||||
menu "Boot Options"
|
||||
|
|
285
misc/stats.c
Normal file
285
misc/stats.c
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Copyright Runtime.io 2018. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <stats.h>
|
||||
|
||||
#define STATS_GEN_NAME_MAX_LEN (sizeof("s255"))
|
||||
|
||||
/* The global list of registered statistic groups. */
|
||||
static struct stats_hdr *stats_list;
|
||||
|
||||
static const char *
|
||||
stats_get_name(const struct stats_hdr *hdr, int idx)
|
||||
{
|
||||
#ifdef CONFIG_STATS_NAMES
|
||||
const struct stats_name_map *cur;
|
||||
u16_t off;
|
||||
int i;
|
||||
|
||||
/* The stats name map contains two elements, an offset into the
|
||||
* statistics entry structure, and the name corresponding to that
|
||||
* offset. This annotation allows for naming only certain statistics,
|
||||
* and doesn't enforce ordering restrictions on the stats name map.
|
||||
*/
|
||||
off = sizeof(*hdr) + idx * hdr->s_size;
|
||||
for (i = 0; i < hdr->s_map_cnt; i++) {
|
||||
cur = hdr->s_map + i;
|
||||
if (cur->snm_off == off) {
|
||||
return cur->snm_name;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u16_t
|
||||
stats_get_off(const struct stats_hdr *hdr, int idx)
|
||||
{
|
||||
return sizeof(*hdr) + idx * hdr->s_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a generic name for an unnamed stat. The name has the form:
|
||||
* s<idx>
|
||||
*
|
||||
* This function assumes the supplied destination buffer is large enough to
|
||||
* accommodate the name.
|
||||
*/
|
||||
static void
|
||||
stats_gen_name(int idx, char *dst)
|
||||
{
|
||||
char c;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
/* Encode the stat name backwards (e.g., "321s" for index 123). */
|
||||
len = 0;
|
||||
do {
|
||||
dst[len++] = '0' + idx % 10;
|
||||
idx /= 10;
|
||||
} while (idx > 0);
|
||||
dst[len++] = 's';
|
||||
|
||||
/* Reverse the string to its proper order. */
|
||||
for (i = 0; i < len / 2; i++) {
|
||||
c = dst[i];
|
||||
dst[i] = dst[len - i - 1];
|
||||
dst[len - i - 1] = c;
|
||||
}
|
||||
dst[len] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk a specific statistic entry, and call walk_func with arg for
|
||||
* each field within that entry.
|
||||
*
|
||||
* Walk func takes the following parameters:
|
||||
*
|
||||
* - The header of the statistics section (stats_hdr)
|
||||
* - The user supplied argument
|
||||
* - The name of the statistic (if STATS_NAME_ENABLE = 0, this is
|
||||
* ("s%d", n), where n is the number of the statistic in the structure.
|
||||
* - A pointer to the current entry.
|
||||
*
|
||||
* @return 0 on success, the return code of the walk_func on abort.
|
||||
*
|
||||
*/
|
||||
int
|
||||
stats_walk(struct stats_hdr *hdr, stats_walk_fn *walk_func, void *arg)
|
||||
{
|
||||
const char *name;
|
||||
char name_buf[STATS_GEN_NAME_MAX_LEN];
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hdr->s_cnt; i++) {
|
||||
name = stats_get_name(hdr, i);
|
||||
if (name == NULL) {
|
||||
/* No assigned name; generate a temporary s<#> name. */
|
||||
stats_gen_name(i, name_buf);
|
||||
name = name_buf;
|
||||
}
|
||||
|
||||
rc = walk_func(hdr, arg, name, stats_get_off(hdr, i));
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a statistics structure, pointed to by hdr.
|
||||
*
|
||||
* @param hdr The header of the statistics structure, contains things
|
||||
* like statistic section name, size of statistics entries,
|
||||
* number of statistics, etc.
|
||||
* @param size The size of the individual statistics elements, either
|
||||
* 2 (16-bits), 4 (32-bits) or 8 (64-bits).
|
||||
* @param cnt The number of elements in the statistics structure
|
||||
* @param map The mapping of statistics name to statistic entry
|
||||
* @param map_cnt The number of items in the statistics map
|
||||
*/
|
||||
void
|
||||
stats_init(struct stats_hdr *hdr, u8_t size, u8_t cnt,
|
||||
const struct stats_name_map *map, u8_t map_cnt)
|
||||
{
|
||||
hdr->s_size = size;
|
||||
hdr->s_cnt = cnt;
|
||||
#ifdef CONFIG_STATS_NAMES
|
||||
hdr->s_map = map;
|
||||
hdr->s_map_cnt = map_cnt;
|
||||
#endif
|
||||
|
||||
stats_reset(hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk the group of registered statistics and call walk_func() for
|
||||
* each element in the list. This function _DOES NOT_ lock the statistics
|
||||
* list, and assumes that the list is not being changed by another task.
|
||||
* (assumption: all statistics are registered prior to OS start.)
|
||||
*
|
||||
* @param walk_func The walk function to call, with a statistics header
|
||||
* and arg.
|
||||
* @param arg The argument to call the walk function with.
|
||||
*
|
||||
* @return 0 on success, non-zero error code on failure
|
||||
*/
|
||||
int
|
||||
stats_group_walk(stats_group_walk_fn *walk_func, void *arg)
|
||||
{
|
||||
struct stats_hdr *hdr;
|
||||
int rc;
|
||||
|
||||
for (hdr = stats_list; hdr != NULL; hdr = hdr->s_next) {
|
||||
rc = walk_func(hdr, arg);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct stats_hdr *
|
||||
stats_group_get_next(const struct stats_hdr *cur)
|
||||
{
|
||||
if (cur == NULL) {
|
||||
return stats_list;
|
||||
}
|
||||
|
||||
/* Cast away const. */
|
||||
return cur->s_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a statistics structure by name, this is not thread-safe.
|
||||
* (assumption: all statistics are registered prior ot OS start.)
|
||||
*
|
||||
* @param name The statistic structure name to find
|
||||
*
|
||||
* @return statistic structure if found, NULL if not found.
|
||||
*/
|
||||
struct stats_hdr *
|
||||
stats_group_find(const char *name)
|
||||
{
|
||||
struct stats_hdr *hdr;
|
||||
|
||||
for (hdr = stats_list; hdr != NULL; hdr = hdr->s_next) {
|
||||
if (strcmp(hdr->s_name, name) == 0) {
|
||||
return hdr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the statistics pointed to by shdr, with the name of "name."
|
||||
*
|
||||
* @param name The name of the statistic to register. This name is guaranteed
|
||||
* unique in the statistics map. If already exists, this function
|
||||
* will return an error.
|
||||
* @param shdr The statistics header to register into the statistic map under
|
||||
* name.
|
||||
*
|
||||
* @return 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int
|
||||
stats_register(const char *name, struct stats_hdr *hdr)
|
||||
{
|
||||
struct stats_hdr *prev;
|
||||
struct stats_hdr *cur;
|
||||
|
||||
/* Don't allow duplicate entries. */
|
||||
prev = NULL;
|
||||
for (cur = stats_list; cur != NULL; cur = cur->s_next) {
|
||||
if (strcmp(cur->s_name, name) == 0) {
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
if (prev == NULL) {
|
||||
stats_list = hdr;
|
||||
} else {
|
||||
prev->s_next = hdr;
|
||||
}
|
||||
hdr->s_name = name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and registers the specified statistics section.
|
||||
*
|
||||
* @param shdr The statistics header to register
|
||||
* @param size The entry size of the statistics to register either 2 (16-bit),
|
||||
* 4 (32-bit) or 8 (64-bit).
|
||||
* @param cnt The number of statistics entries in the statistics structure.
|
||||
* @param map The map of statistics entry to statistics name, only used when
|
||||
* STATS_NAMES is enabled.
|
||||
* @param map_cnt The number of elements in the statistics name map.
|
||||
* @param name The name of the statistics element to register with the system.
|
||||
*
|
||||
* @return 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int
|
||||
stats_init_and_reg(struct stats_hdr *shdr, u8_t size, u8_t cnt,
|
||||
const struct stats_name_map *map, u8_t map_cnt,
|
||||
const char *name)
|
||||
{
|
||||
int rc;
|
||||
|
||||
stats_init(shdr, size, cnt, map, map_cnt);
|
||||
|
||||
rc = stats_register(name, shdr);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets and zeroes the specified statistics section.
|
||||
*
|
||||
* @param shdr The statistics header to zero
|
||||
*/
|
||||
void
|
||||
stats_reset(struct stats_hdr *hdr)
|
||||
{
|
||||
memset(hdr + 1, 0, hdr->s_size * hdr->s_cnt);
|
||||
}
|
Loading…
Reference in a new issue