#include "c_LinkStack.h" #include "c_Test.h" #include #include typedef struct { int thread_id; uint32_t pc_register; } ThreadContext_t; TEST_CASE(test_link_stack_closure_and_lifo_flow) { c_LinkStack_t stack; // 初始化一个专门存放 ThreadContext_t 结构的泛型单向链式栈 ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Init(&stack, sizeof(ThreadContext_t), NULL)); ASSERT_TRUE(c_LinkStack_IsEmpty(&stack)); ASSERT_TRUE(stack.top == NULL); ThreadContext_t ctx1 = { .thread_id = 10, .pc_register = 0x00A0 }; ThreadContext_t ctx2 = { .thread_id = 20, .pc_register = 0x00B0 }; ThreadContext_t ctx3 = { .thread_id = 30, .pc_register = 0x00C0 }; // 1. 验证入栈操作 (Push) 与 LIFO 排列 ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Push(&stack, &ctx1)); // 第一次插入:top -> ctx1 ASSERT_PTR_NOT_NULL(stack.top); ASSERT_TRUE(stack.top->next == NULL); ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Push(&stack, &ctx2)); // 此时排列:top -> ctx2 -> ctx1 ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Push(&stack, &ctx3)); // 此时排列:top -> ctx3 -> ctx2 -> ctx1 ASSERT_INT_EQ(3, c_LinkStack_Size(&stack)); // 强隔离隔离性检查:修改外部临时变量,内部数据必须牢不可破 ctx3.thread_id = 999; // 2. 验证 Peek 窥探能力 ThreadContext_t* peeked = (ThreadContext_t*)c_LinkStack_Peek(&stack); ASSERT_PTR_NOT_NULL(peeked); ASSERT_INT_EQ(30, peeked->thread_id); // 应该依旧是原值 30,证明深度值复制有效 // 3. 【严苛验证变长内存布局的拓扑对齐情况】 // 根据变长公式寻址:STACK_NODE_DATA(node) 必须与抛出的数据指针完全吻合 ASSERT_TRUE(c_LinkStackNode_Get(stack.top) == peeked); // 验证更深一层的 LIFO 相对位置节点: // top 的下一个应当是 ctx2 对应的控制头,提取其内部用户数据区地址 ThreadContext_t* second_data = (ThreadContext_t*)c_LinkStackNode_Get(stack.top->next); ASSERT_INT_EQ(20, second_data->thread_id); // 4. 出栈顺序与后进先出(LIFO)及边界复位断言 (Pop) ThreadContext_t out_res; // 弹出第 1 个:应当是最后进来的 ctx3 ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Pop(&stack, &out_res)); ASSERT_INT_EQ(30, out_res.thread_id); ASSERT_INT_EQ(0, c_LinkStack_IsEmpty(&stack)); // 弹出第 2 个:应当是 ctx2 ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Pop(&stack, &out_res)); ASSERT_INT_EQ(20, out_res.thread_id); // 弹出第 3 个:应当是最早进来的 ctx1 ASSERT_INT_EQ(C_ERR_OK, c_LinkStack_Pop(&stack, &out_res)); ASSERT_INT_EQ(10, out_res.thread_id); // 终极下溢与纯净复位检查 ASSERT_TRUE(c_LinkStack_IsEmpty(&stack)); ASSERT_TRUE(stack.top == NULL); ASSERT_INT_EQ(0, c_LinkStack_Size(&stack)); // 防御重复下溢出栈,应当优雅报错 ASSERT_INT_EQ(C_ERR_OUTOFBOUND, c_LinkStack_Pop(&stack, &out_res)); ASSERT_TRUE(c_LinkStack_Peek(&stack) == NULL); c_LinkStack_Destroy(&stack); } int main(void) { printf("\n"); TEST_START(C_LinkStack_Generic_Layout_Tests); RUN_TEST(test_link_stack_closure_and_lifo_flow); TEST_REPORT(); RETURN_TEST_STATUS; }