From a9e98e546c4cf40251435b3d0e84b9ac980a9623 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Mon, 1 Jan 2024 15:07:00 -0800 Subject: fixes #1572 nng creates too many threads This further limits some of the thread counts, but principally it offers a new runtime facility, nng_init_set_parameter(), which can be used to set certain runtime parameters on the number of threads, provided it is called before the rest of application start up. This facility is quite intentionally "undocumented", at least for now, as we want to limit our commitment to it. Still this should be helpful for applications that need to reduce the number of threads that are created. --- src/core/init.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) (limited to 'src/core/init.c') diff --git a/src/core/init.c b/src/core/init.c index f2195bcb..8f2e1056 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -1,5 +1,5 @@ // -// Copyright 2023 Staysail Systems, Inc. +// Copyright 2024 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a @@ -54,10 +54,107 @@ nni_init(void) return (nni_plat_init(nni_init_helper)); } +// accessing the list of parameters +typedef struct nni_init_param { + nni_list_node node; + nng_init_parameter param; + uint64_t value; +#ifdef NNG_TEST_LIB + uint64_t effective; +#endif +} nni_init_param; + +static nni_list nni_init_params = + NNI_LIST_INITIALIZER(nni_init_params, nni_init_param, node); + +void +nni_init_set_param(nng_init_parameter p, uint64_t value) +{ + if (nni_inited) { + // this is paranoia -- if some library code started already + // then we cannot safely change parameters, and modifying the + // list is not thread safe. + return; + } + nni_init_param *item; + NNI_LIST_FOREACH (&nni_init_params, item) { + if (item->param == p) { + item->value = value; + return; + } + } + if ((item = NNI_ALLOC_STRUCT(item)) != NULL) { + item->param = p; + item->value = value; + nni_list_append(&nni_init_params, item); + } +} + +uint64_t +nni_init_get_param(nng_init_parameter p, uint64_t default_value) +{ + nni_init_param *item; + NNI_LIST_FOREACH (&nni_init_params, item) { + if (item->param == p) { + return (item->value); + } + } + return (default_value); +} + +void +nni_init_set_effective(nng_init_parameter p, uint64_t value) +{ +#ifdef NNG_TEST_LIB + nni_init_param *item; + NNI_LIST_FOREACH (&nni_init_params, item) { + if (item->param == p) { + item->effective = value; + return; + } + } + if ((item = NNI_ALLOC_STRUCT(item)) != NULL) { + item->param = p; + item->effective = value; + nni_list_append(&nni_init_params, item); + } +#else + NNI_ARG_UNUSED(p); + NNI_ARG_UNUSED(value); +#endif +} + +#ifdef NNG_TEST_LIB +uint64_t +nni_init_get_effective(nng_init_parameter p) +{ + nni_init_param *item; + NNI_LIST_FOREACH (&nni_init_params, item) { + if (item->param == p) { + return (item->effective); + } + } + return ((uint64_t)-1); +} +#endif + + +static void +nni_init_params_fini(void) +{ + nni_init_param *item; + while ((item = nni_list_first(&nni_init_params)) != NULL) { + nni_list_remove(&nni_init_params, item); + NNI_FREE_STRUCT(item); + } +} + void nni_fini(void) { if (!nni_inited) { + // make sure we discard parameters even if we didn't startup + nni_init_params_fini(); return; } nni_sp_tran_sys_fini(); @@ -67,6 +164,7 @@ nni_fini(void) nni_taskq_sys_fini(); nni_reap_sys_fini(); // must be before timer and aio (expire) nni_id_map_sys_fini(); + nni_init_params_fini(); nni_plat_fini(); nni_inited = false; -- cgit v1.2.3-70-g09d2