• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2          Copyright Oliver Kowalke 2014.
3 Distributed under the Boost Software License, Version 1.0.
4    (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt
6]
7
8[section:intro Introduction]
9
10[heading Definition]
11
12In computer science routines are defined as a sequence of operations. The
13execution of routines forms a parent-child relationship and the child terminates
14always before the parent. Coroutines (the term was introduced by Melvin
15Conway [footnote Conway, Melvin E.. "Design of a Separable Transition-Diagram Compiler".
16Commun. ACM, Volume 6 Issue 7, July 1963, Article No. 7]),
17are a generalization of routines (Donald Knuth [footnote Knuth, Donald Ervin (1997).
18"Fundamental Algorithms. The Art of Computer Programming 1", (3rd ed.)]).
19The principal difference between coroutines and routines
20is that a coroutine enables explicit suspend and resume of its progress via
21additional operations by preserving execution state and thus provides an
22[*enhanced control flow] (maintaining the execution context).
23
24
25[heading How it works]
26
27Functions foo() and bar() are supposed to alternate their execution (leave and
28enter function body).
29
30[$../../../../libs/coroutine2/doc/images/foo_bar.png [align center]]
31
32If coroutines were called exactly like routines, the stack would grow with
33every call and would never be popped. A jump into the middle of a coroutine
34would not be possible, because the return address would be on top of
35stack entries.
36
37The solution is that each coroutine has its own stack and control-block
38(__fcontext__ from __boost_context__).
39Before the coroutine gets suspended, the non-volatile registers (including stack
40and instruction/program pointer) of the currently active coroutine are stored in
41the coroutine's control-block.
42The registers of the newly activated coroutine must be restored from its
43associated control-block before it is resumed.
44
45The context switch requires no system privileges and provides cooperative
46multitasking convenient to C++. Coroutines provide quasi parallelism.
47When a program is supposed to do several things at the same time, coroutines
48help to do this much more simply and elegantly than with only a single flow of
49control.
50The advantages can be seen particularly clearly with the use of a recursive
51function, such as traversal of binary trees (see example 'same fringe').
52
53
54[heading characteristics]
55Characteristics [footnote Moura, Ana Lucia De and Ierusalimschy, Roberto.
56"Revisiting coroutines". ACM Trans. Program. Lang. Syst., Volume 31 Issue 2,
57February 2009, Article No. 6] of a coroutine are:
58
59* values of local data persist between successive calls (context switches)
60* execution is suspended as control leaves coroutine and is resumed at certain time later
61* symmetric or asymmetric control-transfer mechanism; see below
62* first-class object (can be passed as argument, returned by procedures,
63   stored in a data structure to be used later or freely manipulated by
64   the developer)
65* stackful or stackless
66
67Coroutines are useful in simulation, artificial intelligence, concurrent
68programming, text processing and data manipulation, supporting
69the implementation of components such as cooperative tasks (fibers), iterators,
70generators, infinite lists, pipes etc.
71
72
73[heading execution-transfer mechanism]
74Two categories of coroutines exist: symmetric and asymmetric coroutines.
75
76An asymmetric coroutine knows its invoker, using a special operation to
77implicitly yield control specifically to its invoker. By contrast, all symmetric
78coroutines are equivalent; one symmetric coroutine may pass control to any
79other symmetric coroutine. Because of this, a symmetric coroutine ['must]
80specify the coroutine to which it intends to yield control.
81
82[$../../../../libs/coroutine2/doc/images/foo_bar_seq.png [align center]]
83
84Both concepts are equivalent and a fully-general coroutine library can provide
85either symmetric or asymmetric coroutines.
86
87
88[heading stackfulness]
89In contrast to a stackless coroutine a stackful coroutine can be suspended
90from within a nested stackframe. Execution resumes at exactly the same point
91in the code where it was suspended before.
92With a stackless coroutine, only the top-level routine may be suspended. Any
93routine called by that top-level routine may not itself suspend. This prohibits
94providing suspend/resume operations in routines within a general-purpose library.
95
96[heading first-class continuation]
97A first-class continuation can be passed as an argument, returned by a
98function and stored in a data structure to be used later.
99In some implementations (for instance C# ['yield]) the continuation can
100not be directly accessed or directly manipulated.
101
102Without stackfulness and first-class semantics, some useful execution control
103flows cannot be supported (for instance cooperative multitasking or
104checkpointing).
105
106[endsect]
107