20260829 Redesign

This commit is contained in:
2026-08-29 00:53:40 +08:00
parent f9345bdc0a
commit bf5fc3bda6
44 changed files with 2941 additions and 1 deletions
+87
View File
@@ -0,0 +1,87 @@
#include "c_Pool.h"
#include <stdlib.h>
#include <stdio.h>
#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;
}