summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkev.h76
-rw-r--r--pkmem.h4
-rw-r--r--test/pkev.c19
-rw-r--r--test/pkev.cpp37
-rw-r--r--test/pkmem.cpp16
5 files changed, 111 insertions, 41 deletions
diff --git a/pkev.h b/pkev.h
index a3a8d34..b3a9008 100644
--- a/pkev.h
+++ b/pkev.h
@@ -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;
}
diff --git a/pkmem.h b/pkmem.h
index c7c731a..7807e3c 100644
--- a/pkmem.h
+++ b/pkmem.h
@@ -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);
}