#include "c_Pool.h" #include #include #include "c_Test.h" #include "c_Memory.h" #define C_ASSERT_ALIGNED_TO(ptr, align) \ C_ASSERT(((uintptr_t)(ptr) % (align)) == 0, "Pool分配出的块地址不符合对齐边界") /* ============================================================================== * 🧪 1. 测试全自动“无感自愈扩容”核心行为流 (c_Pool_Alloc) * ============================================================================== */ C_TEST_CASE(test_pool_auto_healing_expansion) { c_Pool_t pool; /* 初始化:每个块 24 字节,每页(ChunkSize)只装载极小的 2 个块 */ c_err_t err = c_Pool_Init(&pool, 24, 2); C_ASSERT_INT_EQ(err, C_ERR_OK, "弹性自愈内存池初始化必须返回 C_OK"); C_ASSERT_INT_EQ(pool.instanceCount, 0, "初始活跃贷出对象数必须为 0"); /* 1. 连续掏空第一页的 2 个默认格子 */ void* block_1 = c_Pool_Alloc(&pool); void* block_2 = c_Pool_Alloc(&pool); C_ASSERT(block_1 != NULL && block_2 != NULL, "第一页的额度分配顺利通过"); C_ASSERT_INT_EQ(pool.instanceCount, 2, "此时贷出计数必须动态变更为 2"); /* 2. 🎯 核心高能看点:在上一版设计中,此时再 Alloc 会直接返回 NULL。 但在这一代高级设计下,池子会在内部发现 freelist 为空,从而自动追加串联一个新 Page! */ void* block_3_auto_healed = c_Pool_Alloc(&pool); /* 断言:分配绝对不能为 NULL,上层代码完全没有感知到任何耗尽异常! */ C_ASSERT(block_3_auto_healed != NULL, "耗尽时追加申请,分配器必须完成全自动无感自愈扩容!"); C_ASSERT_INT_EQ(pool.instanceCount, 3, "贷出计数动态累加为 3"); /* 规范回收其中两个 */ c_Pool_Free(&pool, block_2); c_Pool_Free(&pool, block_3_auto_healed); C_ASSERT_INT_EQ(pool.instanceCount, 1, "主动还回 2 个对象后,instanceCount 必须平滑退回 1"); c_Pool_DryUp(&pool); c_Pool_Destroy(&pool); } /* ============================================================================== * 🧪 2. 测试 `c_Pool_DryUp` 强制全量洗净一键清零机制 * ============================================================================== */ C_TEST_CASE(test_pool_dry_up_force_reset) { c_Pool_t pool; c_Pool_Init(&pool, sizeof(double), 5); /* 每页 5 个对象 */ /* 连续狂点分配 12 次,这会迫使池子在内部自动开辟 3 个 Page 页(5 + 5 + 5 = 15) */ for (int i = 0; i < 12; ++i) { void* ptr = c_Pool_Alloc(&pool); C_UNUSED(ptr); } C_ASSERT_INT_EQ(pool.instanceCount, 12, "12 个活跃对象驻留在外"); /* 🛠️ 执行高能一键强制回收 */ c_Pool_DryUp(&pool); /* 断言:执行一键 DryUp 后,无论刚才贷出了多少,活跃计数瞬间全量归零! */ C_ASSERT_INT_EQ(pool.instanceCount, 0, "执行 DryUp 后,活跃贷出计数必须强行全量斩断复位为 0"); /* 此时,池子内部历史上申请的 3 个物理大页并没有被销毁(不释放传统堆,防止高频申请时的性能抖动), 但所有的 15 个空闲格子已经被全部强行重新串联回 freelist,可以直接重新欢快地发牌复用! */ void* fresh_ptr = c_Pool_Alloc(&pool); C_ASSERT(fresh_ptr != NULL, "DryUp 后,内存池可以在零传统堆开销下立刻无缝重新投入使用"); c_Pool_Free(&pool, fresh_ptr); c_Pool_Destroy(&pool); } /* ============================================================================== * 🚀 测试套件统一注册调度主函数 * ============================================================================== */ int main(int argc, char** argv){ C_TEST_SUITE_BEGIN(MemoryPoolAutoHealingTestSuite) C_RUN_TEST_CASE(test_pool_auto_healing_expansion); C_RUN_TEST_CASE(test_pool_dry_up_force_reset); C_TEST_SUITE_END() return 0; }