The protothreads implementation can be found in core/sys/pt.h. A protothread is a function that returns a char indicating its state. The states are PT_WAITING, PT_YIELDED, PT_EXITED, and PT_ENDED. Each operation that causes the thread to block actually makes the function return, so the values of local variables are not preserved.
The resume execution of a protothread is based on “local continuation” which has two implementations. One uses the switch statement to create a Duff's device (see core/sys/lc-switch.h), and another one based on a GCC __label__ extension (see core/sys/lc-addrlabels.h).
Despite the simplicity of the implementation, here are limitations of protothreads:
- Local variables are in undefined state after context switching, so they must be used extremely carefully. Most examples will let the thread take an external “context” struct argument and store state there.
- Context switching can only happen inside the main protothread routine but not in sub-function calls. This limitation is very similar to Cilk (not surprising because Cilk is a compiler that generates code very similar to that of protothread).
I think that continuation passing style is the answer. And it looks like someone else agrees.