diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-07-13 18:17:02 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-07-13 18:17:02 -0700 |
| commit | 14caa074a83fa2e659b3e490bf9bd31ff0b6b4b1 (patch) | |
| tree | a393024cc23b7540fa08009b221e3e40a195603d | |
| parent | 722cd0deed891bfcb3f1e9866655cc5a41b2111e (diff) | |
| download | nng-14caa074a83fa2e659b3e490bf9bd31ff0b6b4b1.tar.gz nng-14caa074a83fa2e659b3e490bf9bd31ff0b6b4b1.tar.bz2 nng-14caa074a83fa2e659b3e490bf9bd31ff0b6b4b1.zip | |
Make idhash non-inlined (so we can add a mutex.)
| -rw-r--r-- | src/core/idhash.c | 44 | ||||
| -rw-r--r-- | src/core/idhash.h | 20 | ||||
| -rw-r--r-- | src/core/pipe.c | 1 | ||||
| -rw-r--r-- | src/protocol/reqrep/rep.c | 29 | ||||
| -rw-r--r-- | src/protocol/survey/respond.c | 29 | ||||
| -rw-r--r-- | tests/idhash.c | 229 |
6 files changed, 187 insertions, 165 deletions
diff --git a/src/core/idhash.c b/src/core/idhash.c index 9f3b4b03..b3974983 100644 --- a/src/core/idhash.c +++ b/src/core/idhash.c @@ -1,5 +1,6 @@ // -// Copyright 2016 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -17,9 +18,26 @@ struct nni_idhash_entry { void * ihe_val; }; +struct nni_idhash { + size_t ih_cap; + size_t ih_count; + size_t ih_load; + size_t ih_minload; // considers placeholders + size_t ih_maxload; + uint32_t ih_walkers; + uint32_t ih_minval; + uint32_t ih_maxval; + uint32_t ih_dynval; + nni_idhash_entry *ih_entries; +}; + int -nni_idhash_init(nni_idhash *h) +nni_idhash_init(nni_idhash **hp) { + nni_idhash *h; + if ((h = NNI_ALLOC_STRUCT(h)) == NULL) { + return (NNG_ENOMEM); + } h->ih_entries = NULL; h->ih_count = 0; h->ih_load = 0; @@ -30,18 +48,22 @@ nni_idhash_init(nni_idhash *h) h->ih_minval = 0; h->ih_maxval = 0xffffffff; h->ih_dynval = 0; + *hp = h; return (0); } void nni_idhash_fini(nni_idhash *h) { - NNI_ASSERT(h->ih_walkers == 0); - if (h->ih_entries != NULL) { - nni_free(h->ih_entries, h->ih_cap * sizeof(nni_idhash_entry)); - h->ih_entries = NULL; - h->ih_cap = h->ih_count = 0; - h->ih_load = h->ih_minload = h->ih_maxload = 0; + if (h != NULL) { + NNI_ASSERT(h->ih_walkers == 0); + if (h->ih_entries != NULL) { + NNI_FREE_STRUCTS(h->ih_entries, h->ih_cap); + h->ih_entries = NULL; + h->ih_cap = h->ih_count = 0; + h->ih_load = h->ih_minload = h->ih_maxload = 0; + } + NNI_FREE_STRUCT(h); } } @@ -50,7 +72,7 @@ nni_idhash_reclaim(nni_idhash *h) { // Reclaim the buffer if we want, but preserve the limits. if ((h->ih_count == 0) && (h->ih_cap != 0) && (h->ih_walkers == 0)) { - nni_free(h->ih_entries, h->ih_cap * sizeof(nni_idhash_entry)); + NNI_FREE_STRUCTS(h->ih_entries, h->ih_cap); h->ih_cap = 0; h->ih_entries = NULL; h->ih_minload = 0; @@ -124,7 +146,7 @@ nni_hash_resize(nni_idhash *h) } oldents = h->ih_entries; - newents = nni_alloc(sizeof(nni_idhash_entry) * newsize); + newents = NNI_ALLOC_STRUCTS(newents, newsize); if (newents == NULL) { return (NNG_ENOMEM); } @@ -157,7 +179,7 @@ nni_hash_resize(nni_idhash *h) } } if (oldsize != 0) { - nni_free(oldents, sizeof(nni_idhash_entry) * oldsize); + NNI_FREE_STRUCTS(oldents, oldsize); } return (0); } diff --git a/src/core/idhash.h b/src/core/idhash.h index bb3b1581..018420bc 100644 --- a/src/core/idhash.h +++ b/src/core/idhash.h @@ -1,5 +1,6 @@ // -// Copyright 2016 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -25,21 +26,6 @@ typedef struct nni_idhash nni_idhash; typedef struct nni_idhash_entry nni_idhash_entry; -// The details of the nni_idhash are "private". But they let us inline -// this into structures. -struct nni_idhash { - size_t ih_cap; - size_t ih_count; - size_t ih_load; - size_t ih_minload; // considers placeholders - size_t ih_maxload; - uint32_t ih_walkers; - uint32_t ih_minval; - uint32_t ih_maxval; - uint32_t ih_dynval; - nni_idhash_entry *ih_entries; -}; - // nni_idhash_walkfn is called when walking a hash table. If the // return value is non-zero, then nni_idhash_walk will terminate further // process and return that return value. The function takes the generic @@ -48,7 +34,7 @@ struct nni_idhash { // Note that the walkfn must not attempt to change the hash table. // The user must provide any locking needed. typedef int (*nni_idhash_walkfn)(void *, uint32_t, void *); -extern int nni_idhash_init(nni_idhash *); +extern int nni_idhash_init(nni_idhash **); extern void nni_idhash_fini(nni_idhash *); extern void nni_idhash_reclaim(nni_idhash *); extern void nni_idhash_set_limits(nni_idhash *, uint32_t, uint32_t, uint32_t); diff --git a/src/core/pipe.c b/src/core/pipe.c index 702e8eb1..91b78192 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -1,5 +1,6 @@ // // Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this diff --git a/src/protocol/reqrep/rep.c b/src/protocol/reqrep/rep.c index cfc83a5b..d37ca691 100644 --- a/src/protocol/reqrep/rep.c +++ b/src/protocol/reqrep/rep.c @@ -1,5 +1,6 @@ // // Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -28,16 +29,16 @@ static void nni_rep_pipe_fini(void *); // An nni_rep_sock is our per-socket protocol private structure. struct nni_rep_sock { - nni_sock * sock; - nni_msgq * uwq; - nni_msgq * urq; - int raw; - int ttl; - nni_idhash pipes; - char * btrace; - size_t btrace_len; - nni_aio aio_getq; - nni_mtx mtx; + nni_sock * sock; + nni_msgq * uwq; + nni_msgq * urq; + int raw; + int ttl; + nni_idhash *pipes; + char * btrace; + size_t btrace_len; + nni_aio aio_getq; + nni_mtx mtx; }; // An nni_rep_pipe is our per-pipe protocol private structure. @@ -59,7 +60,7 @@ nni_rep_sock_fini(void *arg) nni_rep_sock *rep = arg; nni_aio_fini(&rep->aio_getq); - nni_idhash_fini(&rep->pipes); + nni_idhash_fini(rep->pipes); if (rep->btrace != NULL) { nni_free(rep->btrace, rep->btrace_len); } @@ -183,7 +184,7 @@ nni_rep_pipe_start(void *arg) rp->id = nni_pipe_id(rp->pipe); nni_mtx_lock(&rep->mtx); - rv = nni_idhash_insert(&rep->pipes, rp->id, rp); + rv = nni_idhash_insert(rep->pipes, rp->id, rp); nni_mtx_unlock(&rep->mtx); if (rv != 0) { return (rv); @@ -214,7 +215,7 @@ nni_rep_pipe_stop(void *arg) if (id != 0) { nni_mtx_lock(&rep->mtx); - nni_idhash_remove(&rep->pipes, id); + nni_idhash_remove(rep->pipes, id); nni_mtx_unlock(&rep->mtx); } } @@ -260,7 +261,7 @@ nni_rep_sock_getq_cb(void *arg) // (nonblocking) if we can. If we can't for any reason, then we // free the message. nni_mtx_lock(&rep->mtx); - rv = nni_idhash_find(&rep->pipes, id, (void **) &rp); + rv = nni_idhash_find(rep->pipes, id, (void **) &rp); nni_mtx_unlock(&rep->mtx); if (rv == 0) { rv = nni_msgq_tryput(rp->sendq, msg); diff --git a/src/protocol/survey/respond.c b/src/protocol/survey/respond.c index 6a784738..17018155 100644 --- a/src/protocol/survey/respond.c +++ b/src/protocol/survey/respond.c @@ -1,5 +1,6 @@ // // Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -28,16 +29,16 @@ static void nni_resp_pipe_fini(void *); // An nni_resp_sock is our per-socket protocol private structure. struct nni_resp_sock { - nni_sock * nsock; - nni_msgq * urq; - nni_msgq * uwq; - int raw; - int ttl; - nni_idhash pipes; - char * btrace; - size_t btrace_len; - nni_aio aio_getq; - nni_mtx mtx; + nni_sock * nsock; + nni_msgq * urq; + nni_msgq * uwq; + int raw; + int ttl; + nni_idhash *pipes; + char * btrace; + size_t btrace_len; + nni_aio aio_getq; + nni_mtx mtx; }; // An nni_resp_pipe is our per-pipe protocol private structure. @@ -59,7 +60,7 @@ nni_resp_sock_fini(void *arg) if (psock != NULL) { nni_aio_fini(&psock->aio_getq); - nni_idhash_fini(&psock->pipes); + nni_idhash_fini(psock->pipes); if (psock->btrace != NULL) { nni_free(psock->btrace, psock->btrace_len); } @@ -180,7 +181,7 @@ nni_resp_pipe_start(void *arg) ppipe->id = nni_pipe_id(ppipe->npipe); nni_mtx_lock(&psock->mtx); - rv = nni_idhash_insert(&psock->pipes, ppipe->id, ppipe); + rv = nni_idhash_insert(psock->pipes, ppipe->id, ppipe); nni_mtx_unlock(&psock->mtx); if (rv != 0) { return (rv); @@ -206,7 +207,7 @@ nni_resp_pipe_stop(void *arg) nni_mtx_lock(&psock->mtx); if (ppipe->id != 0) { - nni_idhash_remove(&psock->pipes, ppipe->id); + nni_idhash_remove(psock->pipes, ppipe->id); ppipe->id = 0; } nni_mtx_unlock(&psock->mtx); @@ -246,7 +247,7 @@ nni_resp_sock_getq_cb(void *arg) nni_msg_trim_header(msg, 4); nni_mtx_lock(&psock->mtx); - rv = nni_idhash_find(&psock->pipes, id, (void **) &ppipe); + rv = nni_idhash_find(psock->pipes, id, (void **) &ppipe); if (rv != 0) { nni_msg_free(msg); diff --git a/tests/idhash.c b/tests/idhash.c index a51db654..a30b0d0a 100644 --- a/tests/idhash.c +++ b/tests/idhash.c @@ -1,5 +1,6 @@ // -// Copyright 2016 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -7,139 +8,149 @@ // found online at https://opensource.org/licenses/MIT. // -#include "convey.h" #include "core/idhash.c" +#include "convey.h" Main({ - Test("General ID Hash", { - int rv; + Test("General ID Hash", + { + int rv; - Convey("Given an id hash", { - nni_idhash h; + Convey("Given an id hash", { + nni_idhash *h = NULL; - So(nni_idhash_init(&h) == 0); - So(nni_idhash_count(&h) == 0); + So(nni_idhash_init(&h) == 0); + So(h != NULL); + So(nni_idhash_count(h) == 0); - Reset({ - nni_idhash_fini(&h); - }) + Reset({ nni_idhash_fini(h); }); - Convey("We can insert an element", { - char *five = "five"; - char *four = "four"; - rv = nni_idhash_insert(&h, 5, five); - So(nni_idhash_count(&h) == 1); - So(rv == 0); + Convey("We can insert an element", { + char *five = "five"; + char *four = "four"; + rv = nni_idhash_insert(h, 5, five); + So(nni_idhash_count(h) == 1); + So(rv == 0); - Convey("And we can find it", { - void *ptr; - rv = nni_idhash_find(&h, 5, &ptr); - So(rv == 0); - So(ptr == five); - }) - Convey("We can delete it", { - void *ptr; - rv = nni_idhash_remove(&h, 5); - So(rv == 0); - rv = nni_idhash_find(&h, 5, &ptr); - So(rv == NNG_ENOENT); - }) - Convey("We can change the value", { - void *ptr; - So(nni_idhash_insert(&h, 5, four) == 0); - So(nni_idhash_count(&h) == 1); - So(nni_idhash_find(&h, 5, &ptr) == 0); - So(ptr == four); - }) - Convey("We can insert a hash collision", { - void *ptr; - So(nni_idhash_insert(&h, 13, four) == 0); - So(nni_idhash_count(&h) == 2); - So(nni_idhash_find(&h, 5, &ptr) == 0); - So(ptr == five); - So(nni_idhash_find(&h, 13, &ptr) == 0); - So(ptr == four); - Convey("And delete the intermediate", { - So(nni_idhash_remove(&h, 5) == 0); - ptr = NULL; - So(nni_idhash_find(&h, 13, &ptr) == 0); - So(ptr == four); - }) - }) + Convey("And we can find it", { + void *ptr; + rv = nni_idhash_find(h, 5, &ptr); + So(rv == 0); + So(ptr == five); + }); + Convey("We can delete it", { + void *ptr; + rv = nni_idhash_remove(h, 5); + So(rv == 0); + rv = nni_idhash_find(h, 5, &ptr); + So(rv == NNG_ENOENT); + }); + Convey("We can change the value", { + void *ptr; + So(nni_idhash_insert(h, 5, four) == + 0); + So(nni_idhash_count(h) == 1); + So(nni_idhash_find(h, 5, &ptr) == + 0); + So(ptr == four); + }); + Convey("We can insert a hash collision", { + void *ptr; + So(nni_idhash_insert( + h, 13, four) == 0); + So(nni_idhash_count(h) == 2); + So(nni_idhash_find(h, 5, &ptr) == + 0); + So(ptr == five); + So(nni_idhash_find(h, 13, &ptr) == + 0); + So(ptr == four); + Convey("And delete intermediate", { + So(nni_idhash_remove( + h, 5) == 0); + ptr = NULL; + So(nni_idhash_find( + h, 13, &ptr) == 0); + So(ptr == four); + }); + }); - }) - Convey("We cannot find bogus values", { - void *ptr = NULL; - rv = nni_idhash_find(&h, 42, &ptr); - So(rv == NNG_ENOENT); - So(ptr == NULL); - }) - }) - }) + }); + Convey("We cannot find bogus values", { + void *ptr; + ptr = NULL; + rv = nni_idhash_find(h, 42, &ptr); + So(rv == NNG_ENOENT); + So(ptr == NULL); + }); + }); + }) - Test("Resize ID Hash", { - int expect[1024]; - int i; + Test("Resize ID Hash", { + int expect[1024]; + int i; - for (i = 0; i < 1024; i++) { - expect[i] = i; - } - Convey("Given an id hash", { - nni_idhash h; + for (i = 0; i < 1024; i++) { + expect[i] = i; + } + Convey("Given an id hash", { + nni_idhash *h; - So(nni_idhash_init(&h) == 0); - So(nni_idhash_count(&h) == 0); + So(nni_idhash_init(&h) == 0); + So(nni_idhash_count(h) == 0); - Reset({ - nni_idhash_fini(&h); - }) + Reset({ nni_idhash_fini(h); }); - Convey("We can insert 1024 items", { - for (i = 0; i < 1024; i++) { - nni_idhash_insert(&h, i, &expect[i]); - } - So(nni_idhash_count(&h) == 1024); + Convey("We can insert 1024 items", { + for (i = 0; i < 1024; i++) { + nni_idhash_insert( + h, i, &expect[i]); + } + So(nni_idhash_count(h) == 1024); - Convey("We can remove them", { - for (i = 0; i < 1024; i++) { - nni_idhash_remove(&h, i); - } - So(nni_idhash_count(&h) == 0); - }) - }) - }) - }) + Convey("We can remove them", { + for (i = 0; i < 1024; i++) { + nni_idhash_remove(h, i); + } + So(nni_idhash_count(h) == 0); + }); + }); + }); + }); Test("Dynamic ID generation", { Convey("Given a small ID hash", { - nni_idhash h; - int expect[5]; - uint32_t id; - int i; + nni_idhash *h; + int expect[5]; + uint32_t id; + int i; So(nni_idhash_init(&h) == 0); - Reset({ - nni_idhash_fini(&h); - }) - nni_idhash_set_limits(&h, 10, 13, 10); + Reset({ nni_idhash_fini(h); }); + nni_idhash_set_limits(h, 10, 13, 10); So(1); Convey("We can fill the table", { for (i = 0; i < 4; i++) { - So(nni_idhash_alloc(&h, &id, &expect[i]) == 0); + So(nni_idhash_alloc( + h, &id, &expect[i]) == 0); So(id == (i + 10)); } Convey("Adding another fails", { - So(nni_idhash_alloc(&h, &id, &expect[5]) == NNG_ENOMEM); - }) + So(nni_idhash_alloc(h, &id, + &expect[5]) == NNG_ENOMEM); + }); Convey("Deleting one lets us reinsert", { - nni_idhash_remove(&h, 11); - So(nni_idhash_alloc(&h, &id, &expect[5]) == 0); + nni_idhash_remove(h, 11); + So(nni_idhash_alloc( + h, &id, &expect[5]) == 0); So(id == 11); - }) - }) + }); + }); Convey("We cannot insert bogus values", { - So(nni_idhash_insert(&h, 1, &expect[0]) == NNG_EINVAL); - So(nni_idhash_insert(&h, 100, &expect[0]) == NNG_EINVAL); - }) - }) - }) -}) + So(nni_idhash_insert(h, 1, &expect[0]) == + NNG_EINVAL); + So(nni_idhash_insert(h, 100, &expect[0]) == + NNG_EINVAL); + }); + }); + }); +}); |
