Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 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_ */
|