aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/stats.c38
-rw-r--r--src/core/stats.h19
2 files changed, 44 insertions, 13 deletions
diff --git a/src/core/stats.c b/src/core/stats.c
index 3b9448e6..5fa9ca41 100644
--- a/src/core/stats.c
+++ b/src/core/stats.c
@@ -111,19 +111,28 @@ nni_stat_unregister(nni_stat_item *item)
}
void
-nni_stat_init(nni_stat_item *item, const nni_stat_info *info)
+nni_stat_init_lock(
+ nni_stat_item *item, const nni_stat_info *info, nni_mtx *mtx)
{
#ifdef NNG_ENABLE_STATS
memset(item, 0, sizeof(*item));
NNI_LIST_INIT(&item->si_children, nni_stat_item, si_node);
item->si_info = info;
+ item->si_mtx = mtx;
#else
NNI_ARG_UNUSED(item);
NNI_ARG_UNUSED(info);
+ NNI_ARG_UNUSED(mtx);
#endif
}
void
+nni_stat_init(nni_stat_item *item, const nni_stat_info *info)
+{
+ nni_stat_init_lock(item, info, NULL);
+}
+
+void
nni_stat_inc(nni_stat_item *item, uint64_t inc)
{
#ifdef NNG_ENABLE_STATS
@@ -274,13 +283,26 @@ stat_make_tree(nni_stat_item *item, nni_stat **sp)
}
static void
-stat_update(nni_stat *stat)
+stat_update(nni_stat *stat, nni_mtx **mtxp)
{
const nni_stat_item *item = stat->s_item;
const nni_stat_info *info = item->si_info;
char *old;
char *str;
+ if (info->si_lock) {
+ NNI_ASSERT(item->si_mtx != NULL);
+ if (*mtxp != item->si_mtx) {
+ if (*mtxp) {
+ nni_mtx_unlock(*mtxp);
+ }
+ nni_mtx_lock(item->si_mtx);
+ *mtxp = item->si_mtx;
+ }
+ } else if (*mtxp) {
+ nni_mtx_unlock(*mtxp);
+ *mtxp = NULL;
+ }
switch (info->si_type) {
case NNG_STAT_SCOPE:
case NNG_STAT_ID:
@@ -325,12 +347,12 @@ stat_update(nni_stat *stat)
}
static void
-stat_update_tree(nni_stat *stat)
+stat_update_tree(nni_stat *stat, nni_mtx **mtxp)
{
nni_stat *child;
- stat_update(stat);
+ stat_update(stat, mtxp);
NNI_LIST_FOREACH (&stat->s_children, child) {
- stat_update_tree(child);
+ stat_update_tree(child, mtxp);
}
}
@@ -339,6 +361,7 @@ nni_stat_snapshot(nni_stat **statp, nni_stat_item *item)
{
int rv;
nni_stat *stat;
+ nni_mtx *mtx = NULL;
if (item == NULL) {
item = &stats_root;
@@ -348,7 +371,10 @@ nni_stat_snapshot(nni_stat **statp, nni_stat_item *item)
nni_mtx_unlock(&stats_lock);
return (rv);
}
- stat_update_tree(stat);
+ stat_update_tree(stat, &mtx);
+ if (mtx != NULL) {
+ nni_mtx_unlock(mtx);
+ }
nni_mtx_unlock(&stats_lock);
*statp = stat;
return (0);
diff --git a/src/core/stats.h b/src/core/stats.h
index 5a2e2831..ddd8a886 100644
--- a/src/core/stats.h
+++ b/src/core/stats.h
@@ -42,6 +42,7 @@ struct nni_stat_item {
nni_list_node si_node; // list node, framework use only
nni_list si_children; // children, framework use only
const nni_stat_info *si_info; // statistic description
+ nni_mtx *si_mtx; // protects, if flag in info
union {
uint64_t sv_number;
nni_atomic_u64 sv_atomic;
@@ -53,13 +54,13 @@ struct nni_stat_item {
};
struct nni_stat_info {
- const char *si_name; // name of statistic
- const char *si_desc; // description of statistic (English)
- nni_stat_type si_type; // statistic type, e.g. NNG_STAT_LEVEL
- nni_stat_unit si_unit; // statistic unit, e.g. NNG_UNIT_MILLIS
- nni_stat_update si_update; // update function (can be NULL)
- bool si_atomic : 1; // stat is atomic
- bool si_alloc : 1; // stat string is allocated
+ const char *si_name; // name of statistic
+ const char *si_desc; // description of statistic (English)
+ nni_stat_type si_type; // statistic type, e.g. NNG_STAT_LEVEL
+ nni_stat_unit si_unit; // statistic unit, e.g. NNG_UNIT_MILLIS
+ bool si_atomic : 1; // stat is atomic
+ bool si_alloc : 1; // stat string is allocated
+ bool si_lock : 1; // stat protected by lock (si_mtx)
};
#ifdef NNG_ENABLE_STATS
@@ -75,6 +76,9 @@ struct nni_stat_info {
#define NNI_STAT_ATOMIC(var, name, desc, type, unit) \
NNI_STAT_FIELDS(var, .si_name = name, .si_desc = desc, \
.si_type = type, .si_unit = unit, .si_atomic = true)
+#define NNI_STAT_LOCK(var, name, desc, type, unit) \
+ NNI_STAT_FIELDS(var, .si_name = name, .si_desc = desc, \
+ .si_type = type, .si_unit = unit, .si_lock = true)
// nni_stat_add adds a statistic, but the operation is unlocked, and the
// add is to an unregistered stats tree.
@@ -92,6 +96,7 @@ void nni_stat_set_id(nni_stat_item *, int);
void nni_stat_set_bool(nni_stat_item *, bool);
void nni_stat_set_string(nni_stat_item *, const char *);
void nni_stat_init(nni_stat_item *, const nni_stat_info *);
+void nni_stat_init_lock(nni_stat_item *, const nni_stat_info *, nni_mtx *);
void nni_stat_inc(nni_stat_item *, uint64_t);
void nni_stat_dec(nni_stat_item *, uint64_t);