Description
#
Model descriptionThere are 4 basic elements of an ordinary execution state: {cpu_registers, code, heap, stack}
.
Since the code information is indicated by ({E|R})?IP
register, and the address of the memory allocated from heap is normally stored in the stack directly or indirectly, thus we could simplify the 4 elements into only 2 of them: {cpu_registers, stack}
.
We define the main co
as the coroutine who monopolizes the default stack of the current thread. And since the main co is the only user of this stack, we only need to save/restore the necessary cpu registers' state of the main co when it's been yielded-from/resumed-to (switched-out/switched-in).
Next, the definition of the non-main co
is the coroutine whose execution stack is a stack which is not the default stack of the current thread and may be shared with the other non-main co. Thus the non-main co must have a private save stack
memory buffer to save/restore its execution stack when it is been switched-out/switched-in (because the succeeding/preceding co may would/had use/used the share stack as its execution stack).
There is a special case of non-main co, that is standalone non-main co
what we called in libaco: the share stack of the non-main coroutine has only one co user. Thus there is no need to do saving/restoring stuff of its private save stack when it is been switched-out/switched-in since there is no other co will touch the execution stack of the standalone non-main co except itself.
Finally, we get the big picture of libaco.
There is a proof of correctness part you may find really helpful if you want to dive into the internal of libaco or want to implement your own coroutine library.
It is also highly recommended to read the source code of the tutorials and benchmark next. The benchmark result is very impressive and enlightening too.
#
Synopsis#
The code#
The build and testFor more information abot how to build you may refer to the build and test.