diff options
| -rw-r--r-- | pkev.h | 76 | ||||
| -rw-r--r-- | pkmem.h | 4 | ||||
| -rw-r--r-- | test/pkev.c | 19 | ||||
| -rw-r--r-- | test/pkev.cpp | 37 | ||||
| -rw-r--r-- | test/pkmem.cpp | 16 |
5 files changed, 111 insertions, 41 deletions
@@ -1,6 +1,8 @@ #ifndef PK_EV_H #define PK_EV_H +#include "./pkmem.h" /* deleteme */ + #include <stdint.h> typedef uint64_t pk_ev_mgr_id_T; @@ -10,7 +12,7 @@ typedef uint64_t pk_ev_cb_id_T; // TODO re-think threading // note: pk_ev_init() is NOT thread-safe -void pk_ev_init(); +void pk_ev_init(struct pk_membucket *bkt); // note: pk_ev_teardown() is NOT thread-safe void pk_ev_teardown(); @@ -55,6 +57,14 @@ void pk_ev_unregister_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_id_T cb # define PK_EV_GROW_RATIO 1.5 #endif +#ifndef PK_EV_MEM_ALLOC +# define PK_EV_MEM_ALLOC(sz, alignment, bkt) pk_new(sz, alignment, bkt) +#endif + +#ifndef PK_EV_MEM_FREE +# define PK_EV_MEM_FREE(ptr, sz, bkt) pk_delete(ptr, sz, bkt) +#endif + struct pk_ev_cb { pk_ev_cb_fn *cb; void *user_cb_data; @@ -81,16 +91,19 @@ struct pk_ev_mstr { atomic_uint_fast64_t rn_mgrs; struct pk_ev_mgr **mgrs; mtx_t *mtxs; + struct pk_membucket *bkt; }; struct pk_ev_mstr pk_ev_mstr; void -pk_ev_init() +pk_ev_init(struct pk_membucket* bkt) { int i; - pk_ev_mstr.mgrs = (struct pk_ev_mgr **)malloc(sizeof(void *) * PK_EV_INIT_MGR_COUNT); - pk_ev_mstr.mtxs = (mtx_t*)malloc(sizeof(mtx_t) * PK_EV_INIT_MGR_COUNT); + pk_ev_mstr.bkt = bkt; + pk_ev_mstr.mgrs = (struct pk_ev_mgr **)PK_EV_MEM_ALLOC(sizeof(void *) * + PK_EV_INIT_MGR_COUNT, alignof(void *), bkt); + pk_ev_mstr.mtxs = (mtx_t*)PK_EV_MEM_ALLOC(sizeof(mtx_t) * PK_EV_INIT_MGR_COUNT, alignof(mtx_t), bkt); memset(pk_ev_mstr.mgrs, 0, sizeof(void *) * PK_EV_INIT_MGR_COUNT); memset(pk_ev_mstr.mtxs, 0, sizeof(mtx_t) * PK_EV_INIT_MGR_COUNT); for (i = 0; i < PK_EV_INIT_MGR_COUNT; ++i) { @@ -100,37 +113,44 @@ pk_ev_init() atomic_store(&pk_ev_mstr.rn_mgrs, PK_EV_INIT_MGR_COUNT); } +size_t +pk_ev_inner_calc_sz(uint64_t ev_count, uint64_t cb_count, size_t *sz_ev_list, size_t *sz_ev_cb_list) +{ + // base sizes + size_t l_sz_ev_list = sizeof(struct pk_ev) * ev_count; + size_t l_sz_ev_cb_list = sizeof(struct pk_ev_cb) * cb_count; + if (sz_ev_list != nullptr) *sz_ev_list = l_sz_ev_list; + if (sz_ev_cb_list != nullptr) *sz_ev_cb_list = l_sz_ev_cb_list; + + size_t ret = sizeof(struct pk_ev_mgr); + ret += l_sz_ev_list; + ret += l_sz_ev_cb_list * ev_count; + return ret; +} + void pk_ev_teardown() { long unsigned int i; - for (i = 0; i < pk_ev_mstr.rn_mgrs; ++i) { - if ((atomic_load(&pk_ev_mstr.rn_mgrs) & (1lu << i)) == 0) continue; + for (i = 0; i < atomic_load(&pk_ev_mstr.rn_mgrs); ++i) { + if ((atomic_load(&pk_ev_mstr.flg_mgrs) & (1lu << i)) == 0) continue; mtx_lock(&pk_ev_mstr.mtxs[i]); - free(pk_ev_mstr.mgrs[i]); + size_t sz = pk_ev_inner_calc_sz( + atomic_load(&pk_ev_mstr.mgrs[i]->rn_ev), + atomic_load(&pk_ev_mstr.mgrs[i]->rn_cb), + NULL, NULL + ); + PK_EV_MEM_FREE(pk_ev_mstr.mgrs[i], sz, pk_ev_mstr.bkt); pk_ev_mstr.mgrs[i] = NULL; mtx_unlock(&pk_ev_mstr.mtxs[i]); mtx_destroy(&pk_ev_mstr.mtxs[i]); } - free(pk_ev_mstr.mgrs); - free(pk_ev_mstr.mtxs); + PK_EV_MEM_FREE(pk_ev_mstr.mgrs, sizeof(void *) * atomic_load(&pk_ev_mstr.rn_mgrs), pk_ev_mstr.bkt); + PK_EV_MEM_FREE(pk_ev_mstr.mtxs, sizeof(mtx_t) * atomic_load(&pk_ev_mstr.rn_mgrs), pk_ev_mstr.bkt); pk_ev_mstr.mgrs = NULL; pk_ev_mstr.mtxs = NULL; } -size_t -pk_ev_inner_calc_sz(uint64_t ev_count, uint64_t cb_count, size_t *sz_ev_list, size_t *sz_ev_cb_list) -{ - // base sizes - if (sz_ev_list != nullptr) *sz_ev_list = sizeof(struct pk_ev) * ev_count; - if (sz_ev_cb_list != nullptr) *sz_ev_cb_list = sizeof(struct pk_ev_cb) * cb_count; - - size_t ret = sizeof(struct pk_ev_mgr); - if (sz_ev_list != nullptr) ret += *sz_ev_list; - if (sz_ev_cb_list != nullptr) ret += *sz_ev_cb_list * ev_count; - return ret; -} - static struct pk_ev_mgr* pk_ev_inner_ev_mgr_create(uint64_t ev_count, uint64_t cb_count) { @@ -143,7 +163,7 @@ pk_ev_inner_ev_mgr_create(uint64_t ev_count, uint64_t cb_count) size_t sz = pk_ev_inner_calc_sz(ev_count, cb_count, &sz_ev_list, &sz_ev_cb_list); size_t sz_offset; - struct pk_ev_mgr *mgr = (struct pk_ev_mgr*)malloc(sz); + struct pk_ev_mgr *mgr = (struct pk_ev_mgr*)PK_EV_MEM_ALLOC(sz, alignof(struct pk_ev_mgr), pk_ev_mstr.bkt); if (mgr == NULL) goto early_exit; mgr->ev = (struct pk_ev*)(((char *)mgr) + sizeof(struct pk_ev_mgr)); @@ -219,8 +239,10 @@ recreate: void pk_ev_destroy_mgr(pk_ev_mgr_id_T evmgr) { + assert(evmgr < pk_ev_mstr.rn_mgrs); mtx_lock(&pk_ev_mstr.mtxs[evmgr]); - free(pk_ev_mstr.mgrs[evmgr]); + size_t old_sz = pk_ev_inner_calc_sz(pk_ev_mstr.mgrs[evmgr]->rn_ev, pk_ev_mstr.mgrs[evmgr]->rn_cb, NULL, NULL); + PK_EV_MEM_FREE(pk_ev_mstr.mgrs[evmgr], old_sz, pk_ev_mstr.bkt); pk_ev_mstr.mgrs[evmgr] = NULL; mtx_unlock(&pk_ev_mstr.mtxs[evmgr]); } @@ -242,7 +264,8 @@ pk_ev_register_ev(pk_ev_mgr_id_T evmgr, void *user_ev_data) } mgr = pk_ev_inner_ev_mgr_create(new_size, pk_ev_mstr.mgrs[evmgr]->rn_cb); pk_ev_inner_ev_mgr_clone(pk_ev_mstr.mgrs[evmgr], mgr); - free(pk_ev_mstr.mgrs[evmgr]); + size_t old_sz = pk_ev_inner_calc_sz(pk_ev_mstr.mgrs[evmgr]->rn_ev, pk_ev_mstr.mgrs[evmgr]->rn_cb, NULL, NULL); + PK_EV_MEM_FREE(pk_ev_mstr.mgrs[evmgr], old_sz, pk_ev_mstr.bkt); pk_ev_mstr.mgrs[evmgr] = mgr; } id = pk_ev_mstr.mgrs[evmgr]->n_ev++; @@ -278,6 +301,7 @@ pk_ev_register_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_fn *cb, void * if (found == false) { mtx_lock(&pk_ev_mstr.mtxs[evmgr]); if (pk_ev_mstr.mgrs[evmgr]->ev[evid].right_ev_cbs == pk_ev_mstr.mgrs[evmgr]->rn_cb) { + size_t old_sz = pk_ev_inner_calc_sz(pk_ev_mstr.mgrs[evmgr]->rn_ev, pk_ev_mstr.mgrs[evmgr]->rn_cb, NULL, NULL); new_size = PK_MAX(2, PK_MIN(255, pk_ev_mstr.mgrs[evmgr]->rn_cb * PK_EV_GROW_RATIO)); if (new_size == pk_ev_mstr.mgrs[evmgr]->rn_cb) { PK_LOG_ERR("[pkev.h] need more room, but failed to grow cb count.\n"); @@ -286,7 +310,7 @@ pk_ev_register_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_fn *cb, void * } mgr = pk_ev_inner_ev_mgr_create(pk_ev_mstr.mgrs[evmgr]->rn_ev, new_size); pk_ev_inner_ev_mgr_clone(pk_ev_mstr.mgrs[evmgr], mgr); - free(pk_ev_mstr.mgrs[evmgr]); + PK_EV_MEM_FREE(pk_ev_mstr.mgrs[evmgr], old_sz, pk_ev_mstr.bkt); pk_ev_mstr.mgrs[evmgr] = mgr; mgr = nullptr; } @@ -50,7 +50,7 @@ pk_new(pk_membucket* bucket = NULL) template <typename T> inline T* -pk_new(long count, pk_membucket* bucket = NULL) +pk_new_arr(long count, pk_membucket* bucket = NULL) { char* ptr = NULL; if (bucket) { @@ -83,7 +83,7 @@ pk_delete(const T* ptr, pk_membucket* bucket = NULL) template <typename T> inline void -pk_delete(const T* ptr, long count, pk_membucket* bucket = NULL) +pk_delete_arr(const T* ptr, long count, pk_membucket* bucket = NULL) { if IS_DESTRUCTIBLE(T) { for (long i = 0; i < count; ++i) { diff --git a/test/pkev.c b/test/pkev.c index e38ae9d..7c285d5 100644 --- a/test/pkev.c +++ b/test/pkev.c @@ -1,4 +1,5 @@ +#define PK_IMPL_MEM #define PK_IMPL_EV #include "../pkev.h" @@ -8,6 +9,7 @@ #include <stdio.h> struct ev { + struct pk_membucket *bkt; pk_ev_mgr_id_T evmgr; pk_ev_id_T evid; pk_ev_cb_id_T evcbid; @@ -48,7 +50,9 @@ test_setup() { memset(&ev_one, 0, sizeof(struct ev)); memset(&ev_two, 0, sizeof(struct ev)); - pk_ev_init(); + ev_one.bkt = pk_mem_bucket_create("test_ev_c", PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); + ev_two.bkt = ev_one.bkt; + pk_ev_init(ev_one.bkt); const pk_ev_mgr_id_T evmgr = pk_ev_create_mgr(); if (evmgr >= 64) { PK_LOGV_ERR("%s: failed to create pk_ev_mgr\n", __FILE__); @@ -59,6 +63,13 @@ test_setup() return evmgr; } +void test_teardown() { + pk_ev_teardown(); + pk_mem_bucket_destroy(ev_one.bkt); + ev_one.bkt = NULL; + ev_two.bkt = NULL; +} + int main(int argc, char *argv[]) { (void)argc; @@ -76,8 +87,8 @@ int main(int argc, char *argv[]) pk_ev_emit(evmgr, ev_one.evid, NULL); pk_ev_emit(evmgr, ev_two.evid, NULL); PK_LOGV_INF("%s: ev_one: %i, ev_two: %i\n", __FILE__, ev_one.handled_count, ev_two.handled_count); - pk_ev_teardown(); if (ev_one.handled_count != 1 || ev_two.handled_count != 1) exit(1); + test_teardown(); } // register, emit, catch @@ -105,8 +116,8 @@ int main(int argc, char *argv[]) if (pk_ev_mstr.mgrs[ev_one.evmgr]->ev[ev_one.evid].right_ev_cbs != 1) exit (1); if (pk_ev_mstr.mgrs[ev_two.evmgr]->ev[ev_two.evid].left_ev_cbs != 0) exit (1); if (pk_ev_mstr.mgrs[ev_two.evmgr]->ev[ev_two.evid].right_ev_cbs != 1) exit (1); - pk_ev_teardown(); if (ev_one.handled_count != 1 || ev_two.handled_count != 1) exit(1); + test_teardown(); } // threaded register, emit, catch @@ -122,8 +133,8 @@ int main(int argc, char *argv[]) thrd_join(t1, &i); thrd_join(t2, &i); PK_LOGV_INF("%s: ev_one: %i, ev_two: %i\n", __FILE__, ev_one.handled_count, ev_two.handled_count); - pk_ev_teardown(); if (ev_one.handled_count != 1 || ev_two.handled_count != 1) exit(1); + test_teardown(); } return 0; diff --git a/test/pkev.cpp b/test/pkev.cpp index f8b370b..0d39336 100644 --- a/test/pkev.cpp +++ b/test/pkev.cpp @@ -1,4 +1,5 @@ +#define PK_IMPL_MEM #define PK_IMPL_EV #include "../pkmacros.h" @@ -26,6 +27,7 @@ exit(int code) } struct ev { + pk_membucket *bkt; pk_ev_mgr_id_T evmgr; pk_ev_id_T evid; atomic_int count; @@ -46,7 +48,9 @@ test_setup() ev_two.evid = {}; ev_two.count = {}; ev_two.handled = {}; - pk_ev_init(); + ev_one.bkt = pk_mem_bucket_create("pkev_test_cpp", PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); + ev_two.bkt = ev_one.bkt; + pk_ev_init(ev_one.bkt); const pk_ev_mgr_id_T evmgr = pk_ev_create_mgr(); if (evmgr >= 64) { PK_LOGV_ERR("%s: failed to create pk_ev_mgr\n", __FILE__); @@ -57,6 +61,13 @@ test_setup() return evmgr; } +void test_teardown() { + pk_ev_teardown(); + pk_mem_bucket_destroy(ev_one.bkt); + ev_one.bkt = NULL; + ev_two.bkt = NULL; +} + typedef struct cb_data { int i; struct ev *ev; @@ -274,6 +285,30 @@ int main(int argc, char *argv[]) } while(false); + + // create multiple + do { + + uint64_t mask = 0b1; + const pk_ev_mgr_id_T evmgr = test_setup(); + (void)evmgr; + + for (i = 1; i < PK_EV_INIT_MGR_COUNT; ++i) { + auto ev_mgr_id = pk_ev_create_mgr(); + (void)ev_mgr_id; + mask |= (1ull << i); + } + + assert(pk_ev_mstr.flg_mgrs == mask); + + for (i = PK_EV_INIT_MGR_COUNT-1; i > 0; --i) { + pk_ev_destroy_mgr(pk_ev_mgr_id_T{i}); + } + + pk_ev_teardown(); + } + while (false); + return 0; uncaught_err: PK_LOGV_ERR("%s: failed to catch err.\n", __FILE__); diff --git a/test/pkmem.cpp b/test/pkmem.cpp index c19b71d..4ef1947 100644 --- a/test/pkmem.cpp +++ b/test/pkmem.cpp @@ -173,7 +173,7 @@ int main(int argc, char *argv[]) pk_membucket *bkt = pk_mem_bucket_create("test-some-dang-string", 1024, PK_MEMBUCKET_FLAG_NONE); pk_mem_bucket_set_client_mem_bucket(bkt); - char *some_dang_string = pk_new<char>(64); + char *some_dang_string = pk_new_arr<char>(64); fprintf(stdout, "some_dang_string: %s: %p\n", some_dang_string, (void *)some_dang_string); @@ -193,7 +193,7 @@ int main(int argc, char *argv[]) // 576 == 1024 - EXPECTED_PK_MEMBLOCK_SIZE - (sizeof(pk_memblock) * bkt->block_capacity) - 64 pk_mem_assert(576 == bkt->blocks[15].size); - pk_delete<char>(some_dang_string, 64); + pk_delete_arr<char>(some_dang_string, 64); pk_mem_bucket_destroy(bkt); } @@ -613,8 +613,8 @@ int main(int argc, char *argv[]) size_t diff; pk_membucket *bkt = pk_mem_bucket_create(test_free_between, PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); - char *str1 = pk_new<char>(16, bkt); - char *str2 = pk_new<char>(16, bkt); + char *str1 = pk_new_arr<char>(16, bkt); + char *str2 = pk_new_arr<char>(16, bkt); pk_handle *handle1 = pk_new<pk_handle>(bkt); pk_handle *handle2 = pk_new<pk_handle>(bkt); @@ -655,10 +655,10 @@ int main(int argc, char *argv[]) { pk_membucket *bkt = pk_mem_bucket_create(test_free_between, PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); - float *flts1 = pk_new<float>(48000, bkt); - pk_delete<float>(flts1, 48000, bkt); - float *flts2 = pk_new<float>(48000, bkt); - pk_delete<float>(flts2, 48000, bkt); + float *flts1 = pk_new_arr<float>(48000, bkt); + pk_delete_arr<float>(flts1, 48000, bkt); + float *flts2 = pk_new_arr<float>(48000, bkt); + pk_delete_arr<float>(flts2, 48000, bkt); pk_mem_bucket_destroy(bkt); } |
