diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-08-27 17:19:24 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-08-28 14:03:31 -0400 |
| commit | 3583af4e1c7979e8d309693d53fbe9184e067a50 (patch) | |
| tree | 5056df53961561568ac4ff3a09a8b9ec4167c799 | |
| parent | 77b548f0241aaecf9f53d31b436a99c80519f00b (diff) | |
pk.h: update to 0.9.0, handle breaking changes
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | src/asset-manager.cpp | 5 | ||||
| -rw-r--r-- | src/camera.cpp | 33 | ||||
| -rw-r--r-- | src/ecs.cpp | 12 | ||||
| -rw-r--r-- | src/entities.cpp | 5 | ||||
| -rw-r--r-- | src/level.cpp | 5 | ||||
| -rw-r--r-- | src/pk.h | 348 | ||||
| -rw-r--r-- | src/scene.cpp | 5 | ||||
| -rw-r--r-- | src/thread-pool.cpp | 5 | ||||
| -rw-r--r-- | tests/pke-test-stubs.cpp | 15 | ||||
| -rw-r--r-- | tests/pke-test-stubs.h | 9 | ||||
| -rw-r--r-- | tests/pke-test.cpp | 3 |
12 files changed, 369 insertions, 77 deletions
@@ -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); } /* @@ -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)(); |
