diff --git a/include/haproxy/counters-t.h b/include/haproxy/counters-t.h index 0dba60e43..301490d29 100644 --- a/include/haproxy/counters-t.h +++ b/include/haproxy/counters-t.h @@ -200,6 +200,7 @@ struct extra_counters { char **datap; /* points to pointer to heap containing counters allocated in a linear fashion */ size_t size; /* size of allocated data */ size_t tgrp_step; /* distance in words between two datap for consecutive tgroups, 0 for single */ + uint nbtgrp; /* number of thread groups accessing these counters */ enum counters_type type; /* type of object containing the counters */ }; diff --git a/include/haproxy/counters.h b/include/haproxy/counters.h index 1f97d9dfc..5fbe94d6f 100644 --- a/include/haproxy/counters.h +++ b/include/haproxy/counters.h @@ -128,27 +128,44 @@ void counters_be_shared_drop(struct be_counters_shared *counters); _ctr->size += (csize); \ } while (0) -#define EXTRA_COUNTERS_ALLOC(counters, alloc_failed_label) \ - do { \ - typeof(counters) _ctr = (counters); \ - *_ctr->datap = malloc((_ctr)->size); \ - if (!*_ctr->datap) \ - goto alloc_failed_label; \ +#define EXTRA_COUNTERS_ALLOC(counters, alloc_failed_label, nbtg) \ + do { \ + typeof(counters) _ctr = (counters); \ + char **datap = _ctr->datap; \ + uint tgrp; \ + _ctr->nbtgrp = _ctr->tgrp_step ? (nbtg) : 1; \ + for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \ + *datap = malloc((_ctr)->size); \ + if (!*_ctr->datap) \ + goto alloc_failed_label; \ + datap += _ctr->tgrp_step; \ + } \ } while (0) #define EXTRA_COUNTERS_INIT(counters, mod, init_counters, init_counters_size) \ do { \ - typeof(counters) _ctr = (counters); \ - memcpy(*_ctr->datap + mod->counters_off[_ctr->type], \ - (init_counters), (init_counters_size)); \ + typeof(counters) _ctr = (counters); \ + char **datap = _ctr->datap; \ + uint tgrp; \ + for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \ + memcpy(*datap + mod->counters_off[_ctr->type], \ + (init_counters), (init_counters_size)); \ + datap += _ctr->tgrp_step; \ + } \ } while (0) -#define EXTRA_COUNTERS_FREE(counters) \ - do { \ - if (counters) { \ - ha_free((counters)->datap);\ - free(counters); \ - } \ +#define EXTRA_COUNTERS_FREE(counters) \ + do { \ + typeof(counters) _ctr = (counters); \ + if (_ctr) { \ + char **datap = _ctr->datap; \ + uint tgrp; \ + for (tgrp = 0; tgrp < _ctr->nbtgrp; tgrp++) { \ + ha_free(datap); \ + datap += _ctr->tgrp_step; \ + } \ + free(_ctr); \ + } \ } while (0) #endif /* _HAPROXY_COUNTERS_H */ diff --git a/src/resolvers.c b/src/resolvers.c index abbe54aca..c717b013a 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -2915,7 +2915,7 @@ int resolv_allocate_counters(struct list *stat_modules) mod->counters_size); } - EXTRA_COUNTERS_ALLOC(ns->extra_counters, alloc_failed); + EXTRA_COUNTERS_ALLOC(ns->extra_counters, alloc_failed, 1); list_for_each_entry(mod, stat_modules, list) { memcpy(*ns->extra_counters->datap + mod->counters_off[ns->extra_counters->type], diff --git a/src/stats.c b/src/stats.c index 08e8c6fdf..b4f29696e 100644 --- a/src/stats.c +++ b/src/stats.c @@ -1108,7 +1108,7 @@ int stats_allocate_proxy_counters_internal(struct extra_counters **counters, EXTRA_COUNTERS_ADD(mod, *counters, mod->counters, mod->counters_size); } - EXTRA_COUNTERS_ALLOC(*counters, alloc_failed); + EXTRA_COUNTERS_ALLOC(*counters, alloc_failed, global.nbtgroups); list_for_each_entry(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) { if (!(stats_px_get_cap(mod->domain_flags) & px_cap))