ucontext.h
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);int swapcontext(ucontext_t *oucp, ucontext_t *ucp);
在 System-V 环境中,有一个类型叫做 ucontext_t 和四个函数 getcontext(), setcontext(), makecontext(), swapcontext() ,它们定义在
getcontext() 获取当前的 context,setcontext() 设置当前的 context ,也就是激活这个 context
makecontext() 函数修改 ucp 指向的 context(通过 getcontext() 调用获得)。在调用 makecontext() 之前,调用方必须为 context 分配新的栈,并且假定他的地址是 ucp->uc_stack,定义一个后继 context,假定他的地址是 ucp->uc_link。当 context 稍后激活调用的函数,传递下面的 int 序列参数,调用这必须制定这些参数的数量,当这个函数返回,接下来的 context 被激活,如果接下来的 context 的指针是 NULL, 线程退出。
swapcontext() 函数保存当前的 context(保存在 oucp 中),然后激活被 ucp 指向的 context。

图一:
Coroutine
Coroutine 就是依赖 ucontext 实现的,给每一个 context 绑定上一个函数,每次激活 Context 就是调用这个函数。每一个 Coroutine 有四个状态,状态图如下:

图二:state
这里还需要解决的一个问题就是栈状态转换的问题。

图二:schedule
为什么这里 Schedule 需要一个 ucontext_t?
