summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-08-27 17:19:24 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-08-28 14:03:31 -0400
commit3583af4e1c7979e8d309693d53fbe9184e067a50 (patch)
tree5056df53961561568ac4ff3a09a8b9ec4167c799
parent77b548f0241aaecf9f53d31b436a99c80519f00b (diff)
pk.h: update to 0.9.0, handle breaking changes
-rw-r--r--Makefile1
-rw-r--r--src/asset-manager.cpp5
-rw-r--r--src/camera.cpp33
-rw-r--r--src/ecs.cpp12
-rw-r--r--src/entities.cpp5
-rw-r--r--src/level.cpp5
-rw-r--r--src/pk.h348
-rw-r--r--src/scene.cpp5
-rw-r--r--src/thread-pool.cpp5
-rw-r--r--tests/pke-test-stubs.cpp15
-rw-r--r--tests/pke-test-stubs.h9
-rw-r--r--tests/pke-test.cpp3
12 files changed, 369 insertions, 77 deletions
diff --git a/Makefile b/Makefile
index ea46f58..10bf91c 100644
--- a/Makefile
+++ b/Makefile
@@ -245,6 +245,7 @@ $(DIR_OBJ)/libpke-example.$(LIB_EXT): $(DIR_OBJ)/example.$(OBJ_EXT)
ar rc $@ $(filter %.$(OBJ_EXT),$^)
ranlib $@
+$(DIR_OBJ)/libpke-test.$(LIB_EXT): $(DIR_OBJ)/pke-test-stubs.$(OBJ_EXT)
$(DIR_OBJ)/libpke-test.$(LIB_EXT): $(DIR_OBJ)/pke-test-dummy.$(OBJ_EXT)
$(DIR_OBJ)/libpke-test.$(LIB_EXT): $(DIR_OBJ)/pke-test-audio.$(OBJ_EXT)
$(DIR_OBJ)/libpke-test.$(LIB_EXT): $(DIR_OBJ)/pke-test-static-ui.$(OBJ_EXT)
diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp
index 749aa9e..519698e 100644
--- a/src/asset-manager.cpp
+++ b/src/asset-manager.cpp
@@ -11,13 +11,15 @@
#include <future>
struct Asset_Master {
+ pk_membucket *bkt;
pk_bkt_arr_t<Asset> bc{};
ThreadPoolHandle thread_pool = ThreadPoolHandle_MAX;
} asset_mstr;
void AM_Init() {
int i;
- new (&asset_mstr.bc) pk_bkt_arr_t<Asset>{ pk_bkt_arr_handle_MAX_constexpr };
+ asset_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr AM", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&asset_mstr.bc) pk_bkt_arr_t<Asset>{ pk_bkt_arr_handle_MAX_constexpr, asset_mstr.bkt, asset_mstr.bkt };
asset_mstr.thread_pool = PkeThreads_Init(2, 255);
for (i = 0; i < embedded_shader_index_count; ++i) {
AM_Register_Static(embedded_shaders[i].name, PKE_ASSET_TYPE_SHADER, embedded_shaders[i].data, embedded_shaders[i].size, nullptr);
@@ -271,4 +273,5 @@ void AM_Teardown() {
PkeThreads_Teardown(asset_mstr.thread_pool);
AM_GC();
pk_bkt_arr_teardown(&asset_mstr.bc);
+ pk_mem_bucket_destroy(asset_mstr.bkt);
}
diff --git a/src/camera.cpp b/src/camera.cpp
index ef00b6e..134e9f7 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -12,7 +12,10 @@ PkeCamera NullCamera {};
CompInstance NullCameraInstance{};
PkeCamera *ActiveCamera = &NullCamera;
-pk_bkt_arr_t<PkeCamera> bktc_cameras{};
+struct pke_camera_master {
+ pk_membucket *bkt;
+ pk_bkt_arr_t<PkeCamera> bktc_cameras{};
+} cam_mstr;
btSphereShape CameraShape{1.f};
@@ -45,10 +48,10 @@ PkeCamera &PkeCamera_Register_Inner(PkeCamera &cam, CompInstance &inst, const In
}
PkeCamera &PkeCamera_Register(pk_uuid uuid, const InstPos &instPos) {
- CameraHandle cameraHandle{pk_bkt_arr_new_handle(&bktc_cameras)};
+ CameraHandle cameraHandle{pk_bkt_arr_new_handle(&cam_mstr.bktc_cameras)};
CompInstance *inst;
- auto &cam = bktc_cameras[cameraHandle];
+ auto &cam = cam_mstr.bktc_cameras[cameraHandle];
new (&cam) PkeCamera{};
cam.uuid = uuid;
@@ -61,7 +64,7 @@ PkeCamera &PkeCamera_Register(pk_uuid uuid, const InstPos &instPos) {
PkeCamera *PkeCamera_Get(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- return &bktc_cameras[cameraHandle];
+ return &cam_mstr.bktc_cameras[cameraHandle];
}
PkeCamera *PkeCamera_Get(EntityHandle handle) {
@@ -72,16 +75,16 @@ PkeCamera *PkeCamera_Get(EntityHandle handle) {
(void)user_obj_data;
return arr_obj_data->handle == handle;
};
- pk_bkt_arr_handle cam_handle = pk_bkt_arr_find_first_handle(&bktc_cameras, &CamFindFn::invoke, &cam_find_cb, NULL);
+ pk_bkt_arr_handle cam_handle = pk_bkt_arr_find_first_handle(&cam_mstr.bktc_cameras, &CamFindFn::invoke, &cam_find_cb, NULL);
if (cam_handle == CameraHandle_MAX) {
return nullptr;
}
- return &bktc_cameras[cam_handle];
+ return &cam_mstr.bktc_cameras[cam_handle];
}
void PkeCamera_TargetInstance(CameraHandle cameraHandle, CompInstance *inst) {
assert(cameraHandle != CameraHandle_MAX);
- auto &cam = bktc_cameras[cameraHandle];
+ auto &cam = cam_mstr.bktc_cameras[cameraHandle];
CompInstance *selfInstance = ECS_GetInstance(cam.phys.instHandle);
if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) {
@@ -131,7 +134,7 @@ void PkeCamera_TargetInstance(CameraHandle cameraHandle, CompInstance *inst) {
void PkeCamera_UntargetInstance(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- auto &cam = bktc_cameras[cameraHandle];
+ auto &cam = cam_mstr.bktc_cameras[cameraHandle];
BtDynamicsWorld->removeConstraint(cam.phys.constraint);
pk_delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet);
cam.phys.constraint = CAFE_BABE(btTypedConstraint);
@@ -150,12 +153,12 @@ void PkeCamera_SetPrimary(CameraHandle cameraHandle) {
// Instead, should be a per-viewport or per-world check?
cam.isPrimary = (cam.camHandle == handle);
};
- pk_bkt_arr_iterate(&bktc_cameras, check_stale, &cameraHandle);
+ pk_bkt_arr_iterate(&cam_mstr.bktc_cameras, check_stale, &cameraHandle);
}
void PkeCamera_Destroy(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- auto *camPtr = &bktc_cameras[cameraHandle];
+ auto *camPtr = &cam_mstr.bktc_cameras[cameraHandle];
auto &cam = *camPtr;
if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) {
@@ -175,11 +178,12 @@ void PkeCamera_Destroy(CameraHandle cameraHandle) {
}
pk_bkt_arr &PkeCamera_GetPkBktArr() {
- return bktc_cameras;
+ return cam_mstr.bktc_cameras;
}
void PkeCamera_Init() {
- new (&bktc_cameras) pk_bkt_arr_t<PkeCamera>{ pk_bkt_arr_handle_MAX_constexpr };
+ cam_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr cam", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&cam_mstr.bktc_cameras) pk_bkt_arr_t<PkeCamera>{ pk_bkt_arr_handle_MAX_constexpr, cam_mstr.bkt, cam_mstr.bkt };
NullCamera.type = PKE_CAMERA_TYPE_ORTHOGONAL;
NullCamera.view = PKE_CAMERA_VIEW_TARGET;
NullCamera.stale = PKE_CAMERA_STALE_ALL;
@@ -197,7 +201,8 @@ void PkeCamera_Teardown() {
pk_delete<btRigidBody>(NullCameraInstance.bt.rigidBody, MemBkt_Bullet);
NullCameraInstance.bt.motionState = CAFE_BABE(btDefaultMotionState);
NullCameraInstance.bt.rigidBody = CAFE_BABE(btRigidBody);
- bktc_cameras.~pk_bkt_arr_t<PkeCamera>();
+ cam_mstr.bktc_cameras.~pk_bkt_arr_t<PkeCamera>();
+ pk_mem_bucket_destroy(cam_mstr.bkt);
}
void PkeCamera_Tick(double delta) {
@@ -231,6 +236,6 @@ void PkeCamera_Tick(double delta) {
}
cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT;
};
- pk_bkt_arr_iterate(&bktc_cameras, check_stale, NULL);
+ pk_bkt_arr_iterate(&cam_mstr.bktc_cameras, check_stale, NULL);
}
diff --git a/src/ecs.cpp b/src/ecs.cpp
index 0294c44..839c68e 100644
--- a/src/ecs.cpp
+++ b/src/ecs.cpp
@@ -61,11 +61,12 @@ void ECS_GetEntity_Inner(EntityHandle entHandle, Entity_Base*& ent) {
}
void ECS_Init() {
- new (&ecs.bc.generics) pk_bkt_arr_t<Entity_Base>{ pk_bkt_arr_handle_MAX_constexpr };
- new (&ecs.bc.entityPtrs) pk_bkt_arr_t<Entity_Base*>{ pk_bkt_arr_handle_MAX_constexpr };
- new (&ecs.bc.grBinds) pk_bkt_arr_t<CompGrBinds>{ pk_bkt_arr_handle_MAX_constexpr };
- new (&ecs.bc.instances) pk_bkt_arr_t<CompInstance>{ pk_bkt_arr_handle_MAX_constexpr };
- new (&ecs.bc.ev_mgrs) pk_bkt_arr_t<pke_component_event>{ pk_bkt_arr_handle_MAX_constexpr };
+ ecs.bkt = pk_mem_bucket_create("pk_bkt_arr ecs", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&ecs.bc.generics) pk_bkt_arr_t<Entity_Base>{ pk_bkt_arr_handle_MAX_constexpr, ecs.bkt, ecs.bkt };
+ new (&ecs.bc.entityPtrs) pk_bkt_arr_t<Entity_Base*>{ pk_bkt_arr_handle_MAX_constexpr, ecs.bkt, ecs.bkt };
+ new (&ecs.bc.grBinds) pk_bkt_arr_t<CompGrBinds>{ pk_bkt_arr_handle_MAX_constexpr, ecs.bkt, ecs.bkt };
+ new (&ecs.bc.instances) pk_bkt_arr_t<CompInstance>{ pk_bkt_arr_handle_MAX_constexpr, ecs.bkt, ecs.bkt };
+ new (&ecs.bc.ev_mgrs) pk_bkt_arr_t<pke_component_event>{ pk_bkt_arr_handle_MAX_constexpr, ecs.bkt, ecs.bkt };
pk_arr_reserve(&entitiesMarkedForRemoval, 16);
pk_arr_reserve(&EntitiesToBeRemoved, 16);
pk_arr_reserve(&entitiesYetToBeRemoved, 16);
@@ -639,4 +640,5 @@ void ECS_Teardown() {
ecs.bc.grBinds.~pk_bkt_arr_t<CompGrBinds>();
ecs.bc.entityPtrs.~pk_bkt_arr_t<Entity_Base*>();
ecs.bc.generics.~pk_bkt_arr_t<Entity_Base>();
+ pk_mem_bucket_destroy(ecs.bkt);
}
diff --git a/src/entities.cpp b/src/entities.cpp
index 82b10a8..8b37cbc 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -19,6 +19,7 @@
struct EntityTypeMaster {
+ pk_membucket *bkt;
pk_bkt_arr_t<EntityType> bc{};
} et_mstr;
@@ -30,7 +31,8 @@ struct EntToTeardown {
pk_arr_t<EntToTeardown> EntityTypesToTeardown{};
void EntityType_Init() {
- new (&et_mstr.bc) pk_bkt_arr_t<EntityType>{ pk_bkt_arr_handle_MAX_constexpr };
+ et_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr enttype", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&et_mstr.bc) pk_bkt_arr_t<EntityType>{ pk_bkt_arr_handle_MAX_constexpr, et_mstr.bkt, et_mstr.bkt };
pk_arr_reserve(&EntityTypesToTeardown, 16);
}
@@ -1424,4 +1426,5 @@ void EntityType_Teardown() {
pk_bkt_arr_iterate(&et_mstr.bc, et_iter_cb, NULL);
pk_bkt_arr_teardown(&et_mstr.bc);
pk_arr_reset(&EntityTypesToTeardown);
+ pk_mem_bucket_destroy(et_mstr.bkt);
}
diff --git a/src/level.cpp b/src/level.cpp
index 4293038..15517ac 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -5,15 +5,18 @@
#include "pk.h"
struct level_mstr {
+ pk_membucket *bkt;
pk_bkt_arr_t<pke_level> bc;
} level_mstr;
void pke_level_init() {
- new (&level_mstr.bc) pk_bkt_arr_t<pke_level>{ pk_bkt_arr_handle_MAX_constexpr };
+ level_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr level", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&level_mstr.bc) pk_bkt_arr_t<pke_level>{ pk_bkt_arr_handle_MAX_constexpr, level_mstr.bkt, level_mstr.bkt };
}
void pke_level_teardown() {
pk_bkt_arr_teardown(&level_mstr.bc);
+ pk_mem_bucket_destroy(level_mstr.bkt);
}
/*
diff --git a/src/pk.h b/src/pk.h
index 702cfa3..b293d77 100644
--- a/src/pk.h
+++ b/src/pk.h
@@ -1,7 +1,7 @@
#ifndef PK_SINGLE_HEADER_FILE_H
#define PK_SINGLE_HEADER_FILE_H
/*******************************************************************************
-* PK Single-Header-Library V0.7.0
+* PK Single-Header-Library V0.9.0
*
* Author: Jonathan Bradley
* Copyright: © 2024-2025 Jonathan Bradley
@@ -291,7 +291,7 @@
*
*******************************************************************************/
-#define PK_VERSION "0.7.0"
+#define PK_VERSION "0.9.0"
#ifdef PK_IMPL_ALL
# ifndef PK_IMPL_MEM_TYPES
@@ -912,6 +912,9 @@ pk_mem_bucket_create(const char* description, int64_t sz, enum PK_MEMBUCKET_FLAG
// [000-127] pk_membucket
// [128-191] 64 bytes of data LOL
// [192-511] 20 pk_memblocks (20 is worst-case, start 16, 4 per 64 bytes)
+ if ((sz % 64) > 0) {
+ sz += 64 - (sz % 64);
+ }
assert(sz >= 512 && "[pkmem.h] bucket too small to track allocation data");
struct pk_membucket* bkt = (struct pk_membucket*)aligned_alloc(64, sz);
if (bkt == NULL) return NULL;
@@ -1767,6 +1770,37 @@ pk_ev_unregister_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_id_T cbid)
}
#endif /* PK_IMPL_EV */
+#ifndef PK_PKITER_H
+#define PK_PKITER_H
+
+union pk_iter_id {
+ struct pk_iter_bkt_handle {
+ unsigned int b : 24;
+ unsigned int i : 8;
+ } bkt;
+ struct pk_iter_arr_idx {
+ unsigned int i : 32;
+ } arr;
+};
+
+struct pk_iter {
+ void *data;
+ union pk_iter_id id;
+};
+
+#if defined (__cplusplus)
+template <typename T>
+struct pk_iter_t : public pk_iter {
+ operator T*() {
+ return reinterpret_cast<T*>(this->data);
+ }
+ T* operator->() {
+ return reinterpret_cast<T*>(this->data);
+ }
+};
+#endif
+
+#endif /* PK_PKITER_H */
#ifndef PK_PKARR_H
#define PK_PKARR_H
@@ -1793,6 +1827,10 @@ void pk_arr_remove_at(struct pk_arr *arr, uint32_t index);
void pk_arr_clone(struct pk_arr *lhs, struct pk_arr *rhs);
void pk_arr_swap(struct pk_arr *lhs, struct pk_arr *rhs);
uint32_t pk_arr_find_first_index(struct pk_arr *arr, void *user_data, pk_arr_item_compare *fn);
+bool pk_arr_iter_begin(struct pk_arr *arr, struct pk_iter *it);
+bool pk_arr_iter_end(struct pk_arr *arr, struct pk_iter *it);
+bool pk_arr_iter_increment(struct pk_arr *arr, struct pk_iter *it);
+bool pk_arr_iter_decrement(struct pk_arr *arr, struct pk_iter *it);
#if defined(__cplusplus)
template<typename T>
@@ -2061,6 +2099,48 @@ pk_arr_find_first_index(struct pk_arr *arr, void *user_data, pk_arr_item_compare
return -1;
}
+bool
+pk_arr_iter_begin(struct pk_arr *arr, struct pk_iter *it) {
+ it->data = nullptr;
+ it->id.arr.i = 0;
+ if (arr->data != nullptr && arr->data != CAFE_BABE(void)) {
+ it->data = arr->data;
+ return true;
+ }
+ return false;
+}
+
+bool pk_arr_iter_end(struct pk_arr *arr, struct pk_iter *it) {
+ it->data = nullptr;
+ it->id.arr.i = 0;
+ if (arr->data != nullptr && arr->data != CAFE_BABE(void)) {
+ it->id.arr.i = arr->next - 1;
+ it->data = (void *)((char*)arr->data + (arr->stride * it->id.arr.i));
+ return true;
+ }
+ return false;
+}
+
+bool
+pk_arr_iter_increment(struct pk_arr *arr, struct pk_iter *it) {
+ if (it->id.arr.i + 1 >= arr->next) {
+ return false;
+ }
+ it->id.arr.i += 1;
+ it->data = (void *)((char*)arr->data + (arr->stride * it->id.arr.i));
+ return true;
+}
+
+bool
+pk_arr_iter_decrement(struct pk_arr *arr, struct pk_iter *it) {
+ if (it->id.arr.i == 0) {
+ return false;
+ }
+ it->id.arr.i -= 1;
+ it->data = (void *)((char*)arr->data + (arr->stride * it->id.arr.i));
+ return true;
+}
+
#endif /* PK_IMPL_ARR */
#ifndef PK_PK_STN_H
#define PK_PK_STN_H
@@ -2674,6 +2754,7 @@ enum PK_BKT_ARR_HANDLE_VALIDATION pk_bkt_arr_handle_validate(struct pk_bkt_arr *
void pk_bkt_arr_init(struct pk_bkt_arr *bkt_arr, unsigned long stride, unsigned long alignment, struct pk_bkt_arr_handle limits, struct pk_membucket *bkt_buckets, struct pk_membucket *bkt_data);
void pk_bkt_arr_clear(struct pk_bkt_arr *bkt_arr);
+void pk_bkt_arr_reserve(struct pk_bkt_arr *bkt_arr, size_t count);
struct pk_bkt_arr_handle pk_bkt_arr_find_first_handle(struct pk_bkt_arr *bkt_arr, pk_bkt_arr_compare_fn fn, void *user_data, const void *user_obj_data);
void pk_bkt_arr_iterate(struct pk_bkt_arr *bkt_arr, pk_bkt_arr_iterate_fn fn, void *user_data);
void pk_bkt_arr_teardown(struct pk_bkt_arr *bkt_arr);
@@ -2682,13 +2763,17 @@ void pk_bkt_arr_free_handle(struct pk_bkt_arr *bkt_arr, struct pk_bkt_arr_handle
int pk_bkt_arr_handle_compare(struct pk_bkt_arr_handle lhs, struct pk_bkt_arr_handle rhs);
struct pk_bkt_arr_handle pk_bkt_arr_handle_increment(struct pk_bkt_arr *arr, struct pk_bkt_arr_handle h);
struct pk_bkt_arr_handle pk_bkt_arr_handle_decrement(struct pk_bkt_arr *arr, struct pk_bkt_arr_handle h);
+bool pk_bkt_arr_iter_begin(struct pk_bkt_arr *arr, struct pk_iter *it);
+bool pk_bkt_arr_iter_end(struct pk_bkt_arr *arr, struct pk_iter *it);
+bool pk_bkt_arr_iter_increment(struct pk_bkt_arr *arr, struct pk_iter *it);
+bool pk_bkt_arr_iter_decrement(struct pk_bkt_arr *arr, struct pk_iter *it);
#if defined (__cplusplus)
#include <assert.h>
template<typename T>
struct pk_bkt_arr_t : public pk_bkt_arr {
pk_bkt_arr_t();
- pk_bkt_arr_t(struct pk_bkt_arr_handle limits, struct pk_membucket *bkt_buckets = nullptr, struct pk_membucket *bkt_data = nullptr);
+ pk_bkt_arr_t(struct pk_bkt_arr_handle limits, struct pk_membucket *bkt_buckets, struct pk_membucket *bkt_data);
~pk_bkt_arr_t();
T &operator[](struct pk_bkt_arr_handle);
using FN_Iter = pk_tmpln_1<void, T*, void*>;
@@ -2710,7 +2795,7 @@ T &pk_bkt_arr_t<T>::operator[](struct pk_bkt_arr_handle handle) {
assert(this->bucketed_data != nullptr);
assert(handle.b <= this->limits.b);
assert(handle.i <= this->limits.i);
- assert(handle.b != this->head_r.b || handle.i < this->head_r.i);
+ assert(handle.b != this->head_r.b || handle.i <= this->head_r.i);
T** two_star_programmer = reinterpret_cast<T**>(this->bucketed_data);
return two_star_programmer[handle.b][handle.i];
}
@@ -2728,9 +2813,10 @@ enum PK_BKT_ARR_HANDLE_VALIDATION pk_bkt_arr_handle_validate(struct pk_bkt_arr *
if (handle.b >= bkt_arr->reserved_buckets || handle.b >= bkt_arr->limits.b) {
ret |= PK_BKT_ARR_HANDLE_VALIDATION_BUCKET_INDEX_TOO_HIGH;
}
- if (handle.b == bkt_arr->reserved_buckets-1 && handle.i > bkt_arr->head_r.i) {
+ if (handle.i >= bkt_arr->limits.i) {
ret |= PK_BKT_ARR_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH;
- } else if (handle.b < bkt_arr->reserved_buckets-1 && handle.i > bkt_arr->limits.i) {
+ }
+ if (handle.b == bkt_arr->head_r.b && handle.i > bkt_arr->head_r.i) {
ret |= PK_BKT_ARR_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH;
}
return (enum PK_BKT_ARR_HANDLE_VALIDATION)ret;
@@ -2740,6 +2826,8 @@ void pk_bkt_arr_init(struct pk_bkt_arr *bkt_arr, unsigned long stride, unsigned
{
assert(limits.b <= PK_BKT_ARR_HANDLE_B_MAX);
assert(limits.i <= PK_BKT_ARR_HANDLE_I_MAX);
+ assert(bkt_buckets != nullptr);
+ assert(bkt_data != nullptr);
assert(bkt_arr != nullptr);
memset(bkt_arr, 0, sizeof(struct pk_bkt_arr));
bkt_arr->bkt_buckets = bkt_buckets;
@@ -2752,10 +2840,10 @@ void pk_bkt_arr_init(struct pk_bkt_arr *bkt_arr, unsigned long stride, unsigned
bkt_arr->reserved_buckets = 1;
bkt_arr->stride = stride;
bkt_arr->alignment = alignment;
- bkt_arr->idx_unused = (unsigned long long *)pk_new(sizeof(unsigned long long), alignof(unsigned long long), bkt_buckets);
+ bkt_arr->idx_unused = (unsigned long long *)pk_new_bkt(sizeof(unsigned long long), alignof(unsigned long long), bkt_buckets);
bkt_arr->idx_unused[0] = PK_BKT_ARR_ALL_UNUSED_VAL;
- bkt_arr->bucketed_data = (void **)pk_new(sizeof(void *), alignof(void *), bkt_buckets);
- bkt_arr->bucketed_data[0] = pk_new(stride * limits.i, alignment, bkt_data);
+ bkt_arr->bucketed_data = (void **)pk_new_bkt(sizeof(void *), alignof(void *), bkt_buckets);
+ bkt_arr->bucketed_data[0] = pk_new_bkt(stride * limits.i, alignment, bkt_data);
}
void pk_bkt_arr_clear(struct pk_bkt_arr *bkt_arr) {
@@ -2769,6 +2857,26 @@ void pk_bkt_arr_clear(struct pk_bkt_arr *bkt_arr) {
}
}
+void pk_bkt_arr_reserve(struct pk_bkt_arr *bkt_arr, size_t count) {
+ size_t bucket_count = count / bkt_arr->limits.i;
+ if (bkt_arr->reserved_buckets >= bucket_count) return;
+ unsigned long long *new_idx_unused = (unsigned long long *)pk_new_bkt(sizeof(unsigned long long) * bucket_count, alignof(uint64_t), bkt_arr->bkt_buckets);
+ void **new_bucketed_data = (void **)pk_new_bkt(sizeof(void *) * bucket_count, alignof(void *), bkt_arr->bkt_buckets);
+ if (bkt_arr->reserved_buckets > 0) {
+ memcpy(new_idx_unused, bkt_arr->idx_unused, sizeof(unsigned long long) * bkt_arr->reserved_buckets);
+ memcpy(new_bucketed_data, bkt_arr->bucketed_data, sizeof(void *) * bkt_arr->reserved_buckets);
+ pk_delete_bkt(bkt_arr->bucketed_data, sizeof(void *) * bkt_arr->reserved_buckets, bkt_arr->bkt_buckets);
+ pk_delete_bkt(bkt_arr->idx_unused, sizeof(unsigned long long) * bkt_arr->reserved_buckets, bkt_arr->bkt_buckets);
+ }
+ for (size_t i = bkt_arr->reserved_buckets; i < bucket_count; ++i) {
+ new_idx_unused[i] = PK_BKT_ARR_ALL_UNUSED_VAL;
+ new_bucketed_data[i] = pk_new_bkt(bkt_arr->stride * bkt_arr->limits.i, bkt_arr->alignment, bkt_arr->bkt_data);
+ }
+ bkt_arr->idx_unused = new_idx_unused;
+ bkt_arr->bucketed_data = new_bucketed_data;
+ bkt_arr->reserved_buckets = bucket_count;
+}
+
struct pk_bkt_arr_handle pk_bkt_arr_find_first_handle(struct pk_bkt_arr *bkt_arr, pk_bkt_arr_compare_fn fn, void *user_data, const void *user_obj_data) {
assert(bkt_arr != NULL);
assert(fn != NULL);
@@ -2799,7 +2907,7 @@ void pk_bkt_arr_iterate(struct pk_bkt_arr *bkt_arr, pk_bkt_arr_iterate_fn fn, vo
unsigned int b, i, ii;
for (b = 0; b < bkt_arr->reserved_buckets; ++b) {
char *arr = ((char**)(bkt_arr->bucketed_data))[b];
- ii = b == bkt_arr->reserved_buckets-1 ? bkt_arr->head_r.i : bkt_arr->limits.i;
+ ii = b == bkt_arr->head_r.b ? bkt_arr->head_r.i : bkt_arr->limits.i;
for (i = 0; i < ii; ++i) {
if (PK_HAS_FLAG(bkt_arr->idx_unused[b], 1ull << i)) {
continue;
@@ -2815,10 +2923,10 @@ void pk_bkt_arr_teardown(struct pk_bkt_arr *bkt_arr)
size_t sz = bkt_arr->limits.i * bkt_arr->stride;
if (bkt_arr->idx_unused == nullptr && bkt_arr->bucketed_data == nullptr) return;
for (b = bkt_arr->reserved_buckets - 1; b > -1; --b) {
- pk_delete(bkt_arr->bucketed_data[b], sz, bkt_arr->bkt_data);
+ pk_delete_bkt(bkt_arr->bucketed_data[b], sz, bkt_arr->bkt_data);
}
- pk_delete((void *)bkt_arr->idx_unused, sizeof(unsigned long long) * (bkt_arr->reserved_buckets), bkt_arr->bkt_buckets);
- pk_delete((void *)bkt_arr->bucketed_data, sizeof(void *) * (bkt_arr->reserved_buckets), bkt_arr->bkt_buckets);
+ pk_delete_bkt((void *)bkt_arr->idx_unused, sizeof(unsigned long long) * (bkt_arr->reserved_buckets), bkt_arr->bkt_buckets);
+ pk_delete_bkt((void *)bkt_arr->bucketed_data, sizeof(void *) * (bkt_arr->reserved_buckets), bkt_arr->bkt_buckets);
memset(bkt_arr, 0, sizeof(struct pk_bkt_arr));
bkt_arr->bkt_buckets = NULL;
bkt_arr->bkt_data = NULL;
@@ -2857,18 +2965,18 @@ struct pk_bkt_arr_handle pk_bkt_arr_new_handle(struct pk_bkt_arr *bkt_arr)
if (bkt_arr->head_r.b == bkt_arr->reserved_buckets && bkt_arr->head_r.i == 0) {
bkt_arr->reserved_buckets += 1;
- unsigned long long *new_idx_unused = (unsigned long long *)pk_new(sizeof(unsigned long long) * bkt_arr->reserved_buckets, alignof(unsigned long long), bkt_arr->bkt_buckets);
- void **new_data_ptrs = (void **)pk_new(sizeof(void *) * bkt_arr->reserved_buckets, alignof(void *), bkt_arr->bkt_buckets);
+ unsigned long long *new_idx_unused = (unsigned long long *)pk_new_bkt(sizeof(unsigned long long) * bkt_arr->reserved_buckets, alignof(unsigned long long), bkt_arr->bkt_buckets);
+ void **new_data_ptrs = (void **)pk_new_bkt(sizeof(void *) * bkt_arr->reserved_buckets, alignof(void *), bkt_arr->bkt_buckets);
for (b = 0; b < bkt_arr->reserved_buckets - 1; ++b) {
new_idx_unused[b] = bkt_arr->idx_unused[b];
new_data_ptrs[b] = bkt_arr->bucketed_data[b];
}
new_idx_unused[bkt_arr->reserved_buckets - 1] = PK_BKT_ARR_ALL_UNUSED_VAL;
- new_data_ptrs[bkt_arr->reserved_buckets - 1] = pk_new(bkt_arr->stride * bkt_arr->limits.i, bkt_arr->alignment, bkt_arr->bkt_data);
+ new_data_ptrs[bkt_arr->reserved_buckets - 1] = pk_new_bkt(bkt_arr->stride * bkt_arr->limits.i, bkt_arr->alignment, bkt_arr->bkt_data);
- pk_delete((void *)bkt_arr->idx_unused, sizeof(unsigned long long) * (bkt_arr->reserved_buckets - 1), bkt_arr->bkt_buckets);
- pk_delete((void *)bkt_arr->bucketed_data, sizeof(void *) * (bkt_arr->reserved_buckets - 1), bkt_arr->bkt_buckets);
+ pk_delete_bkt((void *)bkt_arr->idx_unused, sizeof(unsigned long long) * (bkt_arr->reserved_buckets - 1), bkt_arr->bkt_buckets);
+ pk_delete_bkt((void *)bkt_arr->bucketed_data, sizeof(void *) * (bkt_arr->reserved_buckets - 1), bkt_arr->bkt_buckets);
bkt_arr->idx_unused = new_idx_unused;
bkt_arr->bucketed_data = new_data_ptrs;
}
@@ -2926,12 +3034,80 @@ struct pk_bkt_arr_handle pk_bkt_arr_handle_decrement(struct pk_bkt_arr *arr, str
return h;
}
+bool pk_bkt_arr_iter_begin(struct pk_bkt_arr *arr, struct pk_iter *it) {
+ it->data = nullptr;
+ it->id.bkt.b = 0;
+ it->id.bkt.i = 0;
+ if ((arr->idx_unused[it->id.bkt.b] & (1ull << it->id.bkt.i)) != 0) return false;
+ it->data = arr->bucketed_data[0];
+ return true;
+}
+
+bool pk_bkt_arr_iter_end(struct pk_bkt_arr *arr, struct pk_iter *it) {
+ it->data = nullptr;
+ it->id.bkt.b = 0;
+ it->id.bkt.i = 0;
+ if (arr->head_r.b == 0 && arr->head_r.i == 0) return false;
+ do {
+ struct pk_bkt_arr_handle handle = arr->head_r;
+ for (;;) {
+ if ((arr->idx_unused[handle.b] & (1ull << handle.i)) == 0) break;
+ if (handle.b == 0 && handle.i == 0) return false;
+ handle = pk_bkt_arr_handle_decrement(arr, handle);
+ }
+ it->id.bkt.b = handle.b;
+ it->id.bkt.i = handle.i;
+ break;
+ } while (true);
+ if (arr->bucketed_data != nullptr && arr->bucketed_data[it->id.bkt.b] != nullptr) {
+ it->data = (char*)(arr->bucketed_data[it->id.bkt.b]) + (arr->stride * it->id.bkt.i);
+ return true;
+ }
+ return false;
+}
+
+bool pk_bkt_arr_iter_increment(struct pk_bkt_arr *arr, struct pk_iter *it) {
+ struct pk_bkt_arr_handle handle = {
+ .b = it->id.bkt.b,
+ .i = it->id.bkt.i,
+ };
+ if (it->id.bkt.b == arr->limits.b-1 && it->id.bkt.i == arr->limits.i-1) return false;
+ for (;;) {
+ handle = pk_bkt_arr_handle_increment(arr, handle);
+ if (handle.b >= arr->reserved_buckets) return false;
+ if ((arr->idx_unused[handle.b] & (1ull << handle.i)) == 0) break;
+ }
+ it->id.bkt.b = handle.b;
+ it->id.bkt.i = handle.i;
+ if ((arr->idx_unused[it->id.bkt.b] & (1ull << it->id.bkt.i)) != 0) return false;
+ it->data = (char*)(arr->bucketed_data[it->id.bkt.b]) + (arr->stride * it->id.bkt.i);
+ return true;
+}
+
+bool pk_bkt_arr_iter_decrement(struct pk_bkt_arr *arr, struct pk_iter *it) {
+ struct pk_bkt_arr_handle handle = {
+ .b = it->id.bkt.b,
+ .i = it->id.bkt.i,
+ };
+ for (;;) {
+ handle = pk_bkt_arr_handle_decrement(arr, handle);
+ if ((arr->idx_unused[handle.b] & (1ull << handle.i)) == 0) break;
+ if (handle.b == 0 && handle.i == 0) break;
+ }
+ if (it->id.bkt.b == handle.b && it->id.bkt.i == handle.i) return false;
+ it->id.bkt.b = handle.b;
+ it->id.bkt.i = handle.i;
+ if ((arr->idx_unused[it->id.bkt.b] & (1ull << it->id.bkt.i)) != 0) return false;
+ it->data = ((char*)(arr->bucketed_data[it->id.bkt.b])) + (arr->stride * it->id.bkt.i);
+ return true;
+}
+
#endif /* PK_IMPL_BKTARR */
#ifndef PK_PKFUNCINSTR_H
#define PK_PKFUNCINSTR_H
-#define PK_FUNCINSTR_CHILDREN_INCREMENT_COUNT 8
+#include <stdio.h>
struct pk_funcinstr;
struct pk_funcinstr {
@@ -2945,6 +3121,7 @@ struct pk_funcinstr {
};
void pk_funcinstr_init();
+void pk_funcinstr_set_ouputs(FILE *out, FILE *err);
void pk_funcinstr_teardown();
#if defined(__cplusplus)
@@ -2955,6 +3132,17 @@ extern "C" {
// clang
#elif defined(__GNUC__) || defined(__GNUG__)
+#ifndef __USE_GNU
+ #define __USE_GNU
+#endif
+#if defined(__cplusplus)
+#include <cxxabi.h>
+#endif
+#include <dlfcn.h>
+#include <link.h>
+#include <string.h>
+
+
void __cyg_profile_func_enter(void* this_fn, void* call_site);
void __cyg_profile_func_exit(void* this_fn, void* call_site);
@@ -2974,16 +3162,13 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site);
#include <threads.h>
#include <string.h>
-// TODO 2025-06-02 JCB
-// There's some speed improvements that can be made here by growing faster.
-// OR use some type of bucket
-// - might be a good chance to isolate some of the pkmem logic
-
-#define PK_FUNCINSTR_BKT_START_COUNT 4
-#define PK_FUNCINSTR_BKT_GROW_AMOUNT 4
-#define PK_FUNCINSTR_BKT_DATA_COUNT 255
+#define PK_FUNCINSTR_CHILDREN_START_COUNT 8
+#define PK_FUNCINSTR_CHILDREN_GROW_RATIO 2.0
+#define PK_FUNCINSTR_BKT_START_COUNT 64
+#define PK_FUNCINSTR_BKT_GROW_RATIO 2.0
+#define PK_FUNCINSTR_BKT_DATA_COUNT 0xFFFF
struct pk_funcinstr_bkt {
- uint8_t used_count;
+ uint16_t used_count;
uint8_t guard_enter;
uint8_t guard_exit;
struct timespec reset_time;
@@ -2991,6 +3176,8 @@ struct pk_funcinstr_bkt {
};
struct pk_funcinstr_mstr {
mtx_t mtx;
+ FILE *out;
+ FILE *err;
struct timespec reset_time;
struct pk_funcinstr_bkt **buckets;
size_t r_buckets;
@@ -3004,19 +3191,72 @@ static struct pk_funcinstr_mstr thrd_mstr;
__attribute__((no_instrument_function))
void pk_funcinstr_init() {
+ assert(thrd_mstr.out == NULL);
+ assert(thrd_mstr.err == NULL);
assert(thrd_mstr.reset_time.tv_sec == 0);
assert(thrd_mstr.reset_time.tv_nsec == 0);
assert(thrd_mstr.buckets == NULL);
assert(thrd_mstr.r_buckets == 0);
assert(thrd_mstr.n_buckets == 0);
mtx_init(&thrd_mstr.mtx, mtx_plain);
+ thrd_mstr.out = stdout;
+ thrd_mstr.err = stderr;
thrd_mstr.r_buckets = PK_FUNCINSTR_BKT_START_COUNT;
thrd_mstr.buckets = (struct pk_funcinstr_bkt**)aligned_alloc(alignof(struct pk_funcinstr_bkt *), (sizeof(struct pk_funcinstr_bkt *) * PK_FUNCINSTR_BKT_START_COUNT));
- memset(thrd_mstr.buckets, 0, (sizeof(struct pk_funcinstr_bkt *) * PK_FUNCINSTR_BKT_START_COUNT));
clock_gettime(PK_TMR_CLOCK, &thrd_mstr.reset_time);
}
__attribute__((no_instrument_function))
+void pk_funcinstr_set_ouputs(FILE *out, FILE *err) {
+ thrd_mstr.out = out;
+ thrd_mstr.err = err;
+}
+
+__attribute__((no_instrument_function))
+void pk_funcinstr_write(FILE *f) {
+ int64_t i, k, s;
+ struct pk_funcinstr_bkt *bkt = nullptr;
+ struct pk_funcinstr *instr = nullptr;
+ struct pk_tmr fake_tmr;
+ Dl_info info;
+ mtx_lock(&thrd_mstr.mtx);
+ fake_tmr.b = thrd_mstr.reset_time;
+ fprintf(f, "[");
+ for (i = 0; i < (int64_t)thrd_mstr.n_buckets; ++i) {
+ bkt = thrd_mstr.buckets[i];
+ for (k = 0; k < (int64_t)bkt->used_count; ++k) {
+ instr = &bkt->data[k];
+ for (s = 0; s < 2; ++s) {
+ if (i == 0 && k == 0 && s == 0) {
+ fprintf(f, "{");
+ } else {
+ fprintf(f, ",{");
+ }
+ if (dladdr(instr->fn, &info) != 0) {
+ fprintf(f, "\"name\": \"%s\",", info.dli_sname);
+ } else {
+ fprintf(f, "\"name\": \"unknown\",");
+ }
+ fprintf(f, "\"cat\": \"%s\",", "funcinstr");
+ if (s == 0) {
+ fake_tmr.e = instr->tmr.b;
+ fprintf(f, "\"ph\": \"%c\",", 'B');
+ } else {
+ fake_tmr.e = instr->tmr.e;
+ fprintf(f, "\"ph\": \"%c\",", 'E');
+ }
+ fprintf(f, "\"ts\": %lli,", pk_tmr_duration_u64_nano(fake_tmr));
+ fprintf(f, "\"pid\": %i,", 69);
+ fprintf(f, "\"tid\": %ld", thrd_current());
+ fprintf(f, "}");
+ }
+ }
+ }
+ fprintf(f, "]");
+ mtx_unlock(&thrd_mstr.mtx);
+}
+
+__attribute__((no_instrument_function))
void pk_funcinstr_teardown() {
int64_t i, k;
mtx_lock(&thrd_mstr.mtx);
@@ -3027,6 +3267,8 @@ void pk_funcinstr_teardown() {
}
}
free(thrd_mstr.buckets);
+ thrd_mstr.out = NULL;
+ thrd_mstr.err = NULL;
thrd_mstr.reset_time.tv_sec = 0;
thrd_mstr.reset_time.tv_nsec = 0;
thrd_mstr.buckets = NULL;
@@ -3041,16 +3283,6 @@ void pk_funcinstr_teardown() {
// Come up with pk macros since XRay requires attributes to instrument?
#elif defined(__GNUC__) || defined(__GNUG__)
-#ifndef __USE_GNU
- #define __USE_GNU
-#endif
-#if defined(__cplusplus)
-#include <cxxabi.h>
-#endif
-#include <dlfcn.h>
-#include <link.h>
-#include <string.h>
-
__attribute__((no_instrument_function))
bool pk_funcinstr_detect_not_initialized() {
if (thrd_mstr.buckets == NULL) return true;
@@ -3076,10 +3308,9 @@ void pk_funcinstr_detect_and_handle_reset() {
if (should_reset) {
if (thrd_mstr.n_buckets == thrd_mstr.r_buckets) {
mtx_lock(&thrd_mstr.mtx);
- thrd_mstr.r_buckets += PK_FUNCINSTR_BKT_GROW_AMOUNT;
+ thrd_mstr.r_buckets *= PK_FUNCINSTR_BKT_GROW_RATIO;
struct pk_funcinstr_bkt **buckets = (struct pk_funcinstr_bkt**)aligned_alloc(alignof(void *), sizeof(void *) * thrd_mstr.r_buckets);
memcpy(buckets, thrd_mstr.buckets, sizeof(void *) * (thrd_mstr.n_buckets));
- memset((char*)buckets + (sizeof(void *) * (thrd_mstr.n_buckets)), 0, (sizeof(void *) * thrd_mstr.r_buckets) - sizeof(void *) * (thrd_mstr.n_buckets));
free(thrd_mstr.buckets);
thrd_mstr.buckets = buckets;
mtx_unlock(&thrd_mstr.mtx);
@@ -3113,11 +3344,11 @@ __attribute__((no_instrument_function))
struct pk_funcinstr *pk_funcinstr_create_funcinstr(void *this_fn) {
struct pk_funcinstr *funcinstr = &pk_funcinstr_thrd_bkt->data[pk_funcinstr_thrd_bkt->used_count];
pk_funcinstr_thrd_bkt->used_count++;
- pk_tmr_start(funcinstr->tmr);
funcinstr->fn = this_fn;
+ pk_tmr_start(funcinstr->tmr);
funcinstr->parent = pk_funcinstr_thrd_instr;
- funcinstr->children = NULL;
funcinstr->first_child = NULL;
+ funcinstr->children = NULL;
funcinstr->n_children = 0;
funcinstr->r_children = 0;
@@ -3127,9 +3358,12 @@ struct pk_funcinstr *pk_funcinstr_create_funcinstr(void *this_fn) {
pk_funcinstr_thrd_instr->first_child = funcinstr;
} else {
if (pk_funcinstr_thrd_instr->n_children == pk_funcinstr_thrd_instr->r_children) {
- pk_funcinstr_thrd_instr->r_children += PK_FUNCINSTR_CHILDREN_INCREMENT_COUNT;
+ if (pk_funcinstr_thrd_instr->r_children == 0) {
+ pk_funcinstr_thrd_instr->r_children = PK_FUNCINSTR_CHILDREN_START_COUNT;
+ } else {
+ pk_funcinstr_thrd_instr->r_children *= PK_FUNCINSTR_CHILDREN_GROW_RATIO;
+ }
struct pk_funcinstr **children = (struct pk_funcinstr **)aligned_alloc(alignof(void *), sizeof(void *) * pk_funcinstr_thrd_instr->r_children);
- memset((char*)children + (sizeof(void *) * (pk_funcinstr_thrd_instr->n_children)), 0, (sizeof(void *) * pk_funcinstr_thrd_instr->r_children) - sizeof(void *) * (pk_funcinstr_thrd_instr->n_children));
if (pk_funcinstr_thrd_instr->children != NULL) {
memcpy(children, pk_funcinstr_thrd_instr->children, sizeof(void *) * pk_funcinstr_thrd_instr->n_children);
free(pk_funcinstr_thrd_instr->children);
@@ -3169,7 +3403,9 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site) {
if (pk_funcinstr_thrd_instr == NULL) return; // exit called before enter?
pk_funcinstr_thrd_bkt->guard_exit++;
+#ifdef PK_FUNCINSTR_PRINT
Dl_info info;
+#endif /* PK_FUNCINSTR_PRINT */
if (this_fn != pk_funcinstr_thrd_instr->fn) {
int64_t i = (int64_t)pk_funcinstr_thrd_bkt->used_count - 1;
@@ -3187,26 +3423,31 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site) {
struct pk_tmr tmr = pk_funcinstr_thrd_instr->tmr;
pk_funcinstr_thrd_instr = pk_funcinstr_create_funcinstr(this_fn);
pk_funcinstr_thrd_instr->tmr = tmr;
- fprintf(stdout, "[pkfuncinstr] func mismatch; Parent func? Duration not accurate.");
+#ifdef PK_FUNCINSTR_PRINT
+ fprintf(thrd_mstr.out, "[pkfuncinstr] func mismatch; Parent func? Duration not accurate.");
+#endif /* PK_FUNCINSTR_PRINT */
} else {
- fprintf(stderr, "[pkfuncinstr] func mismatch. Last: '");
+#ifdef PK_FUNCINSTR_PRINT
+ fprintf(thrd_mstr.err, "[pkfuncinstr] func mismatch. Last: '");
if (dladdr(pk_funcinstr_thrd_instr->fn, &info) != 0) {
- fprintf(stderr, "%s", info.dli_sname);
+ fprintf(thrd_mstr.err, "%s", info.dli_sname);
} else {
- fprintf(stderr, "(unknown)");
+ fprintf(thrd_mstr.err, "(unknown)");
}
- fprintf(stderr, "'. Current: '");
+ fprintf(thrd_mstr.err, "'. Current: '");
if (dladdr(this_fn, &info) != 0) {
- fprintf(stderr, "%s'.\n", info.dli_sname);
+ fprintf(thrd_mstr.err, "%s'.\n", info.dli_sname);
} else {
- fprintf(stderr, "(unknown)'.\n");
+ fprintf(thrd_mstr.err, "(unknown)'.\n");
}
+#endif /* PK_FUNCINSTR_PRINT */
pk_funcinstr_thrd_bkt->guard_exit=0;
return;
}
}
pk_tmr_stop(pk_funcinstr_thrd_instr->tmr);
+#ifdef PK_FUNCINSTR_PRINT
if (dladdr(this_fn, &info) != 0) {
int depth = 0;
// TODO track depth in a better way
@@ -3221,7 +3462,7 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site) {
demangled = abi::__cxa_demangle(info.dli_sname, NULL, NULL, NULL);
#endif
}
- fprintf(stdout, "[pkfuncinstr] %p %*s %s took %.6f ms\n"
+ fprintf(thrd_mstr.out, "[pkfuncinstr] %p %*s %s took %.6f ms\n"
,this_fn
,depth, ""
,demangled != NULL ? demangled : info.dli_sname != NULL ? info.dli_sname : "???"
@@ -3229,6 +3470,7 @@ void __cyg_profile_func_exit(void* this_fn, void* call_site) {
);
if (demangled != NULL) free(demangled);
}
+#endif /* PK_FUNCINSTR_PRINT */
pk_funcinstr_thrd_bkt->guard_exit=0;
pk_funcinstr_thrd_instr = pk_funcinstr_thrd_instr->parent;
}
diff --git a/src/scene.cpp b/src/scene.cpp
index 5d0b096..bdb7a3a 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -11,15 +11,18 @@
#include <filesystem>
struct pke_scene_master {
+ pk_membucket *bkt;
pk_bkt_arr_t<pke_scene> bc;
} scene_mstr;
void pke_scene_master_init() {
- new (&scene_mstr.bc) pk_bkt_arr_t<pke_scene>{ pk_bkt_arr_handle_MAX_constexpr };
+ scene_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr scene", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&scene_mstr.bc) pk_bkt_arr_t<pke_scene>{ pk_bkt_arr_handle_MAX_constexpr, scene_mstr.bkt, scene_mstr.bkt };
}
void pke_scene_master_teardown() {
scene_mstr.bc.~pk_bkt_arr_t<pke_scene>();
+ pk_mem_bucket_destroy(scene_mstr.bkt);
}
pke_scene *pke_scene_create(const char *scene_name) {
diff --git a/src/thread-pool.cpp b/src/thread-pool.cpp
index 68353b9..f9ff155 100644
--- a/src/thread-pool.cpp
+++ b/src/thread-pool.cpp
@@ -19,6 +19,7 @@ struct ThreadPool {
};
struct ThreadPoolMaster {
+ pk_membucket *bkt;
pk_bkt_arr_t<ThreadPool> bc{};
}thrdpl_mstr;
@@ -124,7 +125,8 @@ void inline PkeThreads_Shutdown_Inner(ThreadPool &tp) {
}
void PkeThreads_Init() {
- new (&thrdpl_mstr.bc) pk_bkt_arr_t<ThreadPool>{ pk_bkt_arr_handle_MAX_constexpr };
+ thrdpl_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr threads", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
+ new (&thrdpl_mstr.bc) pk_bkt_arr_t<ThreadPool>{ pk_bkt_arr_handle_MAX_constexpr, thrdpl_mstr.bkt, thrdpl_mstr.bkt };
}
ThreadPoolHandle PkeThreads_Init(uint8_t threadCount, uint8_t maxQueueCount, struct pk_membucket *bkt) {
@@ -215,4 +217,5 @@ void PkeThreads_Teardown(ThreadPoolHandle handle) {
void PkeThreads_Teardown() {
pk_bkt_arr_teardown(&thrdpl_mstr.bc);
+ pk_mem_bucket_destroy(thrdpl_mstr.bkt);
}
diff --git a/tests/pke-test-stubs.cpp b/tests/pke-test-stubs.cpp
new file mode 100644
index 0000000..8db3c39
--- /dev/null
+++ b/tests/pke-test-stubs.cpp
@@ -0,0 +1,15 @@
+
+#include "pke-test-stubs.h"
+
+#include "pk.h"
+
+extern pk_membucket *MemBkt_Vulkan;
+
+void pke_test_stub_init_vulkan() {
+ MemBkt_Vulkan = pk_mem_bucket_create("test stub vulkan", PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE);
+}
+
+void pke_test_stub_teardown_vulkan() {
+ pk_mem_bucket_destroy(MemBkt_Vulkan);
+ MemBkt_Vulkan = NULL;
+}
diff --git a/tests/pke-test-stubs.h b/tests/pke-test-stubs.h
new file mode 100644
index 0000000..d16f3e9
--- /dev/null
+++ b/tests/pke-test-stubs.h
@@ -0,0 +1,9 @@
+#ifndef PKE_TEST_STUBS_H
+#define PKE_TEST_STUBS_H
+
+#include "pk.h"
+
+void pke_test_stub_init_vulkan();
+void pke_test_stub_teardown_vulkan();
+
+#endif /* PKE_TEST_STUBS_H */
diff --git a/tests/pke-test.cpp b/tests/pke-test.cpp
index 21babbb..97694b2 100644
--- a/tests/pke-test.cpp
+++ b/tests/pke-test.cpp
@@ -1,6 +1,7 @@
#include "./pke-test-types.h"
+#include "./pke-test-stubs.h"
#include "./pke-test-audio.h"
#include "./pke-test-asset-manager.h"
#include "./pke-test-dummy.h"
@@ -57,6 +58,7 @@ int main(int argc, char *argv[])
struct pk_membucket *bkt = pk_mem_bucket_create("pke-test-bucket", PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE);
pk_mem_bucket_set_client_mem_bucket(bkt);
fprintf(stdout, "[pke-test]:[%s]:[%s] Begin.\n", group->title, group->tests[k].title);
+ pke_test_stub_init_vulkan();
if (group->test_setup != NULL) (group->test_setup)();
lj.expected_exit = 0;
lj.caught = 0;
@@ -73,6 +75,7 @@ int main(int argc, char *argv[])
fprintf(stdout, "[pke-test]:[%s]:[%s] %sFailed.%s Expected: '%i' Got: '%i'.\n", group->title, group->tests[k].title, CLR_RED, CLR_WHITE, group->tests[k].expected_result, result);
}
if (group->test_teardown != NULL) (group->test_teardown)();
+ pke_test_stub_teardown_vulkan();
pk_mem_bucket_destroy(bkt);
}
if (group->group_teardown != NULL) (group->group_teardown)();