void coroutine_yield(struct schedule * S) { int id = S->running; assert(id >= 0); struct coroutine * C = S->co[id]; assert((char *)&C > S->stack); _save_stack(C, S->stack + STACK_SIZE); // 用于保存堆栈的信息 C->status = COROUTINE_SUSPEND; // 状态变成了挂起 S->running = -1; swapcontext(&C->ctx, &S->main); }
static void _run(struct coroutine *co) { _set_running_coroutine(co); _resume(co); _set_running_coroutine(NULL); if (co->status == STATUS_EXITING) { coroutine_delete(co); return; } _save_stack(co); }
void coroutine_yield(struct schedule * sched) { int id = sched->running; assert(id >= 0); struct coroutine * C = sched->co[id]; assert((char *)&C > sched->stack); _save_stack(C,sched->stack + STACK_SIZE); C->status = COROUTINE_SUSPEND; sched->running = -1; swapcontext(&C->ctx , &sched->main); // 这里resume/delete的时候一定要把原来的函数context执行完,不然函数里声明类的析构函数不会被执行! }
void coroutine_yield(struct schedule * S) { printf("%s:%s\n", __FILE__, __FUNCTION__); int id = S->running; //这个assert(id>=0) 即暗示了此函数只会在coroutine中调用。 assert(id >= 0); //取出正在运行的croutine struct coroutine * C = S->co[id]; //这个assert()是何意? 这里的S->stack为何是栈上的地址?不是从堆上分配的吗 //上面的疑问解答:因为swapcontext()时,指定了ss_sp这S->stack,这样当context执行时,它的栈是放在S->stack上的。 //所以C, S->stack 它们的地址都是在相近地 printf("&C:%p S->stack:%p\n", &C, S->stack); assert((char *)&C > S->stack); //保存这个coroutine的stack _save_stack(C,S->stack + STACK_SIZE); //使进入SUSPEND状态 C->status = COROUTINE_SUSPEND; S->running = -1; //切换回S->main, 就是当初从coroutine_resume()中过来的那里 swapcontext(&C->ctx , &S->main); }