xhawk18 / s_task

awaitable coroutine library for C
Other
594 stars 87 forks source link

关于最小stack要求,以及一些代码文档建议 #13

Open jerrygzy opened 1 year ago

jerrygzy commented 1 year ago

hawk 你好,

最近试用了一下s_task, 感觉很不错, 不过因为对代码的理解有限,还希望能请教几个问题。

char g_stack0[384];    // 64 * 6  
char g_stack1[384];

我测试了一下, 64*5 的stack, 也可以运行, 但64*4 就出现了报错 fprintf(stderr, "stack overflow in lower bits");

if(((int *)real_stack)[0] != S_TASK_STACK_MAGIC) {
#ifndef NDEBUG
            fprintf(stderr, "stack overflow in lower bits");
#endif
            while(1);   /* dead */
        }

这里的 S_TASK_STACK_MAGIC ((int)0x5AA55AA5), 没有看到什么文档, 请问具体是什么含义。

另外,swapcontext 两个注释掉的指令, 请问被注释的原因是什么。

static void swapcontext(ucontext_t *old_tcb, const ucontext_t *new_tcb) {
    __asm__ __volatile__(
        "PUSH    {r4-r12,lr}\n"
        "STR     sp, [r0]\n"
        //"LDR     r2, [r1]\n"
        //"MOV     sp, r2\n"
        "LDR     sp, [r1]\n"
        "POP     {r4-r12,lr}\n"

        "BX      lr\n"
   );
}

最后, 如果关于create_context, 的-1 和 -10 两个常数有相关说明就非常好了。

static void create_context(ucontext_t *oucp, void *stack, size_t stack_size) {
    uint32_t *top_sp;
    uint32_t int_sp;

    int_sp = (int )((char *)stack + stack_size);
    int_sp = int_sp / 4 * 4;  //alignment
    top_sp = (uint32_t *)int_sp;

    top_sp[-1] = (int)&s_task_context_entry;
    oucp->sp = (int)&top_sp[-10];
}
xhawk18 commented 1 year ago

S_TASK_STACK_MAGIC 在栈最大空间处放置的魔数,当栈溢出时,这个数据就破坏了。在这样或许能检测栈是否完整。。

LDR sp,r2去掉是因为cortex m3 (v7m架构)可以直接将 [r1]复制到sp,然而cortex m0(v6m架构)不支持,只能先复制到r2,再从r2复制到sp。换到v7m这么写就没必要了。

[-10] 是sp的位置(根据swapcontext开头两句push,str可以计算出)。

jerrygzy commented 1 year ago

@xhawk18 了解,感谢回复。

这边又做了点小优化 POP {r4-r12,pc} 实测运行正常, 可以省去 BX lr 这条指令