123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- [/
- Copyright Oliver Kowalke 2009.
- Distributed under the Boost Software License, Version 1.0.
- (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt
- ]
- [section:coroutine Coroutine]
- __boost_coroutine__ provides two implementations - asymmetric and symmetric
- coroutines.
- Symmetric coroutines occur usually in the context of concurrent programming
- in order to represent independent units of execution.
- Implementations that produce sequences of values typically use asymmetric
- coroutines.
- [footnote Moura, Ana Lucia De and Ierusalimschy, Roberto.
- "Revisiting coroutines". ACM Trans. Program. Lang. Syst., Volume 31 Issue 2,
- February 2009, Article No. 6]
- [heading stackful]
- Each instance of a coroutine has its own stack.
- In contrast to stackless coroutines, stackful coroutines allow invoking the
- suspend operation out of arbitrary sub-stackframes, enabling escape-and-reenter
- recursive operations.
- [heading move-only]
- A coroutine is moveable-only.
- If it were copyable, then its stack with all the objects allocated on it
- would be copied too. That would force undefined behaviour if some of these
- objects were RAII-classes (manage a resource via RAII pattern). When the first
- of the coroutine copies terminates (unwinds its stack), the RAII class
- destructors will release their managed resources. When the second copy
- terminates, the same destructors will try to doubly-release the same resources,
- leading to undefined behaviour.
- [heading clean-up]
- On coroutine destruction the associated stack will be unwound.
- The constructor of coroutine allows you to pass a customized ['stack-allocator].
- ['stack-allocator] is free to deallocate the stack or cache it for future usage
- (for coroutines created later).
- [heading segmented stack]
- __call_coro__, __push_coro__ and __pull_coro__ support segmented stacks
- (growing on demand).
- It is not always possible to accurately estimate the required stack size - in
- most cases too much memory is allocated (waste of virtual address-space).
- At construction a coroutine starts with a default (minimal) stack size. This
- minimal stack size is the maximum of page size and the canonical size for signal
- stack (macro SIGSTKSZ on POSIX).
- At this time of writing only GCC (4.7)
- [footnote [@http://gcc.gnu.org/wiki/SplitStacks Ian Lance Taylor, Split Stacks in GCC]]
- is known to support segmented stacks. With version 1.54 __boost_coroutine__
- provides support for segmented stacks.
- The destructor releases the associated stack. The implementer is free to
- deallocate the stack or to cache it for later usage.
- [heading context switch]
- A coroutine saves and restores registers according to the underlying ABI on
- each context switch (using __boost_context__).
- Some applications do not use floating-point registers and can disable preserving
- FPU registers for performance reasons.
- [note According to the calling convention the FPU registers are preserved by
- default.]
- On POSIX systems, the coroutine context switch does not preserve signal masks
- for performance reasons.
- A context switch is done via __call_coro_op__, __push_coro_op__ and
- __pull_coro_op__.
- [warning Calling __call_coro_op__, __push_coro_op__ and __pull_coro_op__ from
- inside the [_same] coroutine results in undefined behaviour.]
- As an example, the code below will result in undefined behaviour:
- boost::coroutines::symmetric_coroutine<void>::call_type coro(
- [&](boost::coroutines::symmetric_coroutine<void>::yield_type& yield){
- yield(coro); // yield to same symmetric_coroutine
- });
- coro();
- [include asymmetric.qbk]
- [include symmetric.qbk]
- [endsect]
|