diff options
| author | Garrett D'Amore <garrett@damore.org> | 2021-12-05 22:11:24 -0500 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2021-12-05 23:04:45 -0500 |
| commit | c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04 (patch) | |
| tree | 3a135bbee8750cc1b1869cfca6a2e6f24bf8e59c | |
| parent | eee06d1e8365ea1b1aa9363a3c6445745b002324 (diff) | |
| download | nng-c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04.tar.gz nng-c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04.tar.bz2 nng-c9bbe8eb574fe10ff16cc71a23fcc9b31fb8ed04.zip | |
Use static initialization for lists and mutexes.
This eliminates some run-time initialization, moving it to compile time.
Additional follow up work will expand on this to simplify initialization
and reduce the need for certain locks.
| -rw-r--r-- | src/core/dialer.c | 4 | ||||
| -rw-r--r-- | src/core/idhash.h | 26 | ||||
| -rw-r--r-- | src/core/init.c | 47 | ||||
| -rw-r--r-- | src/core/init.h | 19 | ||||
| -rw-r--r-- | src/core/list.h | 10 | ||||
| -rw-r--r-- | src/core/listener.c | 4 | ||||
| -rw-r--r-- | src/core/socket.c | 20 | ||||
| -rw-r--r-- | src/core/stats.c | 29 | ||||
| -rw-r--r-- | src/platform/posix/posix_impl.h | 6 | ||||
| -rw-r--r-- | src/platform/posix/posix_thread.c | 2 | ||||
| -rw-r--r-- | src/platform/windows/win_impl.h | 6 | ||||
| -rw-r--r-- | src/platform/windows/win_thread.c | 2 | ||||
| -rw-r--r-- | src/sp/transport.c | 9 | ||||
| -rw-r--r-- | src/supplemental/http/http_client.c | 30 | ||||
| -rw-r--r-- | src/supplemental/http/http_server.c | 31 | ||||
| -rw-r--r-- | src/supplemental/tls/tls_common.c | 1 |
16 files changed, 65 insertions, 181 deletions
diff --git a/src/core/dialer.c b/src/core/dialer.c index 3a749085..e3f435db 100644 --- a/src/core/dialer.c +++ b/src/core/dialer.c @@ -21,20 +21,18 @@ static void dialer_connect_cb(void *); static void dialer_timer_cb(void *); static nni_id_map dialers; -static nni_mtx dialers_lk; +static nni_mtx dialers_lk = NNI_MTX_INITIALIZER; void nni_dialer_sys_init(void) { nni_id_map_init(&dialers, 1, 0x7fffffff, false); - nni_mtx_init(&dialers_lk); } void nni_dialer_sys_fini(void) { nni_reap_drain(); - nni_mtx_fini(&dialers_lk); nni_id_map_fini(&dialers); } diff --git a/src/core/idhash.h b/src/core/idhash.h index 0c9043ce..b2259853 100644 --- a/src/core/idhash.h +++ b/src/core/idhash.h @@ -1,5 +1,5 @@ // -// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a @@ -23,28 +23,28 @@ // use table sizes that are powers of two. Note that hash items // must be non-NULL. The table is protected by an internal lock. -typedef struct nni_id_map nni_id_map; -typedef struct nni_id_entry nni_id_entry; +typedef struct nni_id_map nni_id_map; +typedef struct nni_id_entry nni_id_entry; // NB: These details are entirely private to the hash implementation. // They are provided here to facilitate inlining in structures. struct nni_id_map { - size_t id_cap; - size_t id_count; - size_t id_load; - size_t id_min_load; // considers placeholders - size_t id_max_load; + uint32_t id_cap; + uint32_t id_count; + uint32_t id_load; + uint32_t id_min_load; // considers placeholders + uint32_t id_max_load; uint32_t id_min_val; uint32_t id_max_val; uint32_t id_dyn_val; nni_id_entry *id_entries; }; -extern void nni_id_map_init(nni_id_map *, uint32_t, uint32_t, bool); -extern void nni_id_map_fini(nni_id_map *); +extern void nni_id_map_init(nni_id_map *, uint32_t, uint32_t, bool); +extern void nni_id_map_fini(nni_id_map *); extern void *nni_id_get(nni_id_map *, uint32_t); -extern int nni_id_set(nni_id_map *, uint32_t, void *); -extern int nni_id_alloc(nni_id_map *, uint32_t *, void *); -extern int nni_id_remove(nni_id_map *, uint32_t); +extern int nni_id_set(nni_id_map *, uint32_t, void *); +extern int nni_id_alloc(nni_id_map *, uint32_t *, void *); +extern int nni_id_remove(nni_id_map *, uint32_t); #endif // CORE_IDHASH_H diff --git a/src/core/init.c b/src/core/init.c index c923fdf0..f9dee9e2 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -14,21 +14,16 @@ #include <stdio.h> #include <stdlib.h> -static nni_mtx nni_init_mtx; -static nni_list nni_init_list; -static bool nni_inited = false; - -extern int nni_tls_sys_init(void); +extern int nni_tls_sys_init(void); extern void nni_tls_sys_fini(void); +static bool nni_inited = false; + static int nni_init_helper(void) { int rv; - nni_mtx_init(&nni_init_mtx); - NNI_LIST_INIT(&nni_init_list, nni_initializer, i_node); - nni_inited = true; #ifdef NNG_TEST_LIB static bool cleanup = false; if (!cleanup) { @@ -54,6 +49,8 @@ nni_init_helper(void) nni_pipe_sys_init(); nni_sp_tran_sys_init(); + nni_inited = true; + return (0); } @@ -69,19 +66,6 @@ nni_fini(void) if (!nni_inited) { return; } - if (!nni_list_empty(&nni_init_list)) { - nni_initializer *init; - - nni_mtx_lock(&nni_init_mtx); - while ((init = nni_list_first(&nni_init_list)) != NULL) { - if (init->i_fini != NULL) { - init->i_fini(); - } - init->i_once = 0; - nni_list_remove(&nni_init_list, init); - } - nni_mtx_unlock(&nni_init_mtx); - } nni_sp_tran_sys_fini(); nni_tls_sys_fini(); nni_pipe_sys_fini(); @@ -95,27 +79,6 @@ nni_fini(void) nni_reap_sys_fini(); // must be before timer and aio (expire) nni_stat_sys_fini(); - nni_mtx_fini(&nni_init_mtx); nni_plat_fini(); nni_inited = false; } - -int -nni_initialize(nni_initializer *init) -{ - int rv; - if (init->i_once) { - return (0); - } - nni_mtx_lock(&nni_init_mtx); - if (init->i_once) { - nni_mtx_unlock(&nni_init_mtx); - return (0); - } - if ((rv = init->i_init()) == 0) { - init->i_once = 1; - nni_list_append(&nni_init_list, init); - } - nni_mtx_unlock(&nni_init_mtx); - return (rv); -} diff --git a/src/core/init.h b/src/core/init.h index d21bb4c5..7875ba4c 100644 --- a/src/core/init.h +++ b/src/core/init.h @@ -23,23 +23,4 @@ int nni_init(void); // that all resources used by the library are released back to the system. void nni_fini(void); -typedef struct nni_initializer { - int (*i_init)(void); // i_init is called exactly once - void (*i_fini)(void); // i_fini is called on shutdown - int i_once; // private -- initialize to zero - nni_list_node i_node; // private -- initialize to zero -} nni_initializer; - -// nni_initialize will call the initialization routine exactly once. This is -// done efficiently, so that if the caller has initialized already, then -// subsequent calls are "cheap" (no synchronization cost). The initialization -// function must not itself cause any further calls to nni_initialize; the -// function should limit itself to initialization of locks and static data -// structures. When shutting down, the finalizer will be called. The -// order in which finalizers are called is unspecified. -// -// An initializer may fail (due to resource exhaustion), in which case the -// return value of nni_initialize will be non-zero. -int nni_initialize(nni_initializer *); - #endif // CORE_INIT_H diff --git a/src/core/list.h b/src/core/list.h index 204057a2..d3c703bb 100644 --- a/src/core/list.h +++ b/src/core/list.h @@ -29,6 +29,16 @@ extern void nni_list_init_offset(nni_list *list, size_t offset); #define NNI_LIST_INIT(list, type, field) \ nni_list_init_offset(list, offsetof(type, field)) +// NNI_LIST_INITIALIZER is used to initialize structures at declaration time. +// The list argument is the structure being initialized and the type and +// offset determine where the node lives within each item. +#define NNI_LIST_INITIALIZER(list, type, field) \ + { \ + .ll_head.ln_next = &(list).ll_head, \ + .ll_head.ln_prev = &(list).ll_head, \ + .ll_offset = offsetof(type, field) \ + } + #define NNI_LIST_NODE_INIT(node) \ do { \ (node)->ln_prev = (node)->ln_next = 0; \ diff --git a/src/core/listener.c b/src/core/listener.c index 74e5e22b..4d4a4e24 100644 --- a/src/core/listener.c +++ b/src/core/listener.c @@ -22,20 +22,18 @@ static void listener_accept_cb(void *); static void listener_timer_cb(void *); static nni_id_map listeners; -static nni_mtx listeners_lk; +static nni_mtx listeners_lk = NNI_MTX_INITIALIZER; void nni_listener_sys_init(void) { nni_id_map_init(&listeners, 1, 0x7fffffff, false); - nni_mtx_init(&listeners_lk); } void nni_listener_sys_fini(void) { nni_reap_drain(); - nni_mtx_fini(&listeners_lk); nni_id_map_fini(&listeners); } diff --git a/src/core/socket.c b/src/core/socket.c index 6c43e43d..d9ac12b6 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -16,12 +16,6 @@ // Socket implementation. -static nni_list sock_list; -static nni_id_map sock_ids; -static nni_mtx sock_lk; -static nni_id_map ctx_ids; -static bool inited; - struct nni_ctx { nni_list_node c_node; nni_sock *c_sock; @@ -107,6 +101,11 @@ struct nni_socket { #endif }; +static nni_list sock_list = NNI_LIST_INITIALIZER(sock_list, nni_sock, s_node); +static nni_mtx sock_lk = NNI_MTX_INITIALIZER; +static nni_id_map sock_ids; +static nni_id_map ctx_ids; + static void nni_ctx_destroy(nni_ctx *); #define SOCK(s) ((nni_sock *) (s)) @@ -611,12 +610,8 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto) void nni_sock_sys_init(void) { - NNI_LIST_INIT(&sock_list, nni_sock, s_node); - nni_mtx_init(&sock_lk); - nni_id_map_init(&sock_ids, 1, 0x7fffffff, false); nni_id_map_init(&ctx_ids, 1, 0x7fffffff, false); - inited = true; } void @@ -624,8 +619,6 @@ nni_sock_sys_fini(void) { nni_id_map_fini(&sock_ids); nni_id_map_fini(&ctx_ids); - nni_mtx_fini(&sock_lk); - inited = false; } int @@ -822,9 +815,6 @@ nni_sock_closeall(void) { nni_sock *s; - if (!inited) { - return; - } for (;;) { nni_mtx_lock(&sock_lk); if ((s = nni_list_first(&sock_list)) == NULL) { diff --git a/src/core/stats.c b/src/core/stats.c index e4765078..f7e52fb0 100644 --- a/src/core/stats.c +++ b/src/core/stats.c @@ -19,21 +19,21 @@ struct nng_stat { const nni_stat_info *s_info; const nni_stat_item *s_item; // Used during snapshot collection nni_list s_children; - nni_stat * s_parent; + nni_stat *s_parent; nni_list_node s_node; nni_time s_timestamp; union { int sv_id; bool sv_bool; uint64_t sv_value; - char * sv_string; + char *sv_string; } s_val; }; #ifdef NNG_ENABLE_STATS static nni_stat_item stats_root; -static nni_mtx stats_lock; -static nni_mtx stats_val_lock; +static nni_mtx stats_lock = NNI_MTX_INITIALIZER; +static nni_mtx stats_val_lock = NNI_MTX_INITIALIZER; #endif void @@ -171,7 +171,7 @@ nni_stat_set_string(nni_stat_item *item, const char *s) { #ifdef NNG_ENABLE_STATS const nni_stat_info *info = item->si_info; - char * old = item->si_u.sv_string; + char *old = item->si_u.sv_string; nni_mtx_lock(&stats_val_lock); if ((s != NULL) && (old != NULL) && (strcmp(s, old) == 0)) { @@ -235,7 +235,7 @@ nng_stats_free(nni_stat *st) static int stat_make_tree(nni_stat_item *item, nni_stat **sp) { - nni_stat * stat; + nni_stat *stat; nni_stat_item *child; if ((stat = NNI_ALLOC_STRUCT(stat)) == NULL) { @@ -266,8 +266,8 @@ stat_update(nni_stat *stat) { const nni_stat_item *item = stat->s_item; const nni_stat_info *info = item->si_info; - char * old; - char * str; + char *old; + char *str; switch (info->si_type) { case NNG_STAT_SCOPE: @@ -397,7 +397,6 @@ nng_stat_bool(nni_stat *stat) return (stat->s_val.sv_bool); } - const char * nng_stat_string(nng_stat *stat) { @@ -498,8 +497,6 @@ nni_stat_sys_init(void) .si_desc = "all statistics", .si_type = NNG_STAT_SCOPE, }; - nni_mtx_init(&stats_lock); - nni_mtx_init(&stats_val_lock); nni_stat_init(&stats_root, &root); #endif return (0); @@ -508,10 +505,6 @@ nni_stat_sys_init(void) void nni_stat_sys_fini(void) { -#ifdef NNG_ENABLE_STATS - nni_mtx_fini(&stats_lock); - nni_mtx_fini(&stats_val_lock); -#endif } #ifdef NNG_ENABLE_STATS @@ -538,10 +531,10 @@ nng_stats_dump(nng_stat *stat) #ifdef NNG_ENABLE_STATS static char buf[128]; // to minimize recursion, not thread safe int len; - char * scope; - char * indent = " "; + char *scope; + char *indent = " "; unsigned long long val; - nni_stat * child; + nni_stat *child; switch (nng_stat_type(stat)) { case NNG_STAT_SCOPE: diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h index 234d1501..97924a45 100644 --- a/src/platform/posix/posix_impl.h +++ b/src/platform/posix/posix_impl.h @@ -58,10 +58,16 @@ struct nni_plat_mtx { pthread_mutex_t mtx; }; +#define NNI_MTX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } + struct nni_rwlock { pthread_rwlock_t rwl; }; +#define NNI_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER } + +// No static form of CV initialization because of the need to use +// attributes to set the clock type. struct nni_plat_cv { pthread_cond_t cv; nni_plat_mtx *mtx; diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c index c47bcec6..b7cd5e1e 100644 --- a/src/platform/posix/posix_thread.c +++ b/src/platform/posix/posix_thread.c @@ -34,7 +34,7 @@ #endif static pthread_mutex_t nni_plat_init_lock = PTHREAD_MUTEX_INITIALIZER; -static int nni_plat_inited = 0; +static volatile int nni_plat_inited = 0; static int nni_plat_forked = 0; pthread_condattr_t nni_cvattr; diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h index 608a065e..b3c08edf 100644 --- a/src/platform/windows/win_impl.h +++ b/src/platform/windows/win_impl.h @@ -37,15 +37,17 @@ struct nni_plat_thr { struct nni_plat_mtx { SRWLOCK srl; - DWORD owner; - int init; }; +#define NNI_MTX_INITIALIZER { SRWLOCK_INIT } + struct nni_rwlock { SRWLOCK rwl; BOOLEAN exclusive; }; +#define NNI_RWLOCK_INITIALIZER { SRWLOCK_INIT } + struct nni_plat_cv { CONDITION_VARIABLE cv; PSRWLOCK srl; diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c index 31e783a3..b131c067 100644 --- a/src/platform/windows/win_thread.c +++ b/src/platform/windows/win_thread.c @@ -55,13 +55,11 @@ void nni_plat_mtx_init(nni_plat_mtx *mtx) { InitializeSRWLock(&mtx->srl); - mtx->init = 1; } void nni_plat_mtx_fini(nni_plat_mtx *mtx) { - mtx->init = 0; } void diff --git a/src/sp/transport.c b/src/sp/transport.c index ed27ebeb..9f4c6522 100644 --- a/src/sp/transport.c +++ b/src/sp/transport.c @@ -14,8 +14,9 @@ #include <stdio.h> #include <string.h> -static nni_list sp_tran_list; -static nni_rwlock sp_tran_lk; +static nni_list sp_tran_list = + NNI_LIST_INITIALIZER(sp_tran_list, nni_sp_tran, tran_link); +static nni_rwlock sp_tran_lk = NNI_RWLOCK_INITIALIZER; void nni_sp_tran_register(nni_sp_tran *tran) @@ -73,9 +74,6 @@ extern void nni_sp_zt_register(void); void nni_sp_tran_sys_init(void) { - NNI_LIST_INIT(&sp_tran_list, nni_sp_tran, tran_link); - nni_rwlock_init(&sp_tran_lk); - #ifdef NNG_TRANSPORT_INPROC nni_sp_inproc_register(); #endif @@ -110,5 +108,4 @@ nni_sp_tran_sys_fini(void) nni_list_remove(&sp_tran_list, t); t->tran_fini(); } - nni_rwlock_fini(&sp_tran_lk); } diff --git a/src/supplemental/http/http_client.c b/src/supplemental/http/http_client.c index 3737cb7b..b156794c 100644 --- a/src/supplemental/http/http_client.c +++ b/src/supplemental/http/http_client.c @@ -1,5 +1,5 @@ // -// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // Copyright 2019 Devolutions <info@devolutions.net> // @@ -19,7 +19,7 @@ #include "http_api.h" -static nni_mtx http_txn_lk; +static nni_mtx http_txn_lk = NNI_MTX_INITIALIZER; struct nng_http_client { nni_list aios; @@ -198,15 +198,6 @@ nni_http_client_connect(nni_http_client *c, nni_aio *aio) nni_mtx_unlock(&c->mtx); } -static int http_client_sys_init(void); -static void http_client_sys_fini(void); - -static nni_initializer http_client_initializer = { - .i_init = http_client_sys_init, - .i_fini = http_client_sys_fini, - .i_once = 0, -}; - typedef enum http_txn_state { HTTP_CONNECTING, HTTP_SENDING, @@ -385,8 +376,6 @@ nni_http_transact_conn( http_txn *txn; int rv; - nni_initialize(&http_client_initializer); - if (nni_aio_begin(aio) != 0) { return; } @@ -430,8 +419,6 @@ nni_http_transact(nni_http_client *client, nni_http_req *req, http_txn *txn; int rv; - nni_initialize(&http_client_initializer); - if (nni_aio_begin(aio) != 0) { return; } @@ -470,16 +457,3 @@ nni_http_transact(nni_http_client *client, nni_http_req *req, nni_http_client_connect(client, txn->aio); nni_mtx_unlock(&http_txn_lk); } - -static int -http_client_sys_init(void) -{ - nni_mtx_init(&http_txn_lk); - return (0); -} - -static void -http_client_sys_fini(void) -{ - nni_mtx_fini(&http_txn_lk); -} diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c index 7f6f9abe..b7e7ac80 100644 --- a/src/supplemental/http/http_server.c +++ b/src/supplemental/http/http_server.c @@ -22,15 +22,6 @@ #include "http_api.h" -static int http_server_sys_init(void); -static void http_server_sys_fini(void); - -static nni_initializer http_server_initializer = { - .i_init = http_server_sys_init, - .i_fini = http_server_sys_fini, - .i_once = 0, -}; - struct nng_http_handler { nni_list_node node; char * uri; @@ -279,8 +270,9 @@ nni_http_handler_set_method(nni_http_handler *h, const char *method) return (0); } -static nni_list http_servers; -static nni_mtx http_servers_lk; +static nni_list http_servers = + NNI_LIST_INITIALIZER(http_servers, nni_http_server, node); +static nni_mtx http_servers_lk = NNI_MTX_INITIALIZER; static void http_sc_reap(void *arg) @@ -1001,8 +993,6 @@ nni_http_server_init(nni_http_server **serverp, const nni_url *url) int rv; nni_http_server *s; - nni_initialize(&http_server_initializer); - nni_mtx_lock(&http_servers_lk); NNI_LIST_FOREACH (&http_servers, s) { if ((!s->closed) && (atoi(url->u_port) == s->port) && @@ -1924,18 +1914,3 @@ nni_http_server_fini(nni_http_server *s) } nni_mtx_unlock(&http_servers_lk); } - -static int -http_server_sys_init(void) -{ - NNI_LIST_INIT(&http_servers, nni_http_server, node); - nni_mtx_init(&http_servers_lk); - return (0); -} - -static void -http_server_sys_fini(void) -{ - nni_reap_drain(); - nni_mtx_fini(&http_servers_lk); -} diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c index 3e497b0c..357c8411 100644 --- a/src/supplemental/tls/tls_common.c +++ b/src/supplemental/tls/tls_common.c @@ -1495,7 +1495,6 @@ nni_tls_sys_init(void) void nni_tls_sys_fini(void) { - nni_reap_drain(); NNG_TLS_ENGINE_FINI(); } |
