Blame libs/coroutine2/doc/coroutine.qbk

Packit 58578d
[/
Packit 58578d
          Copyright Oliver Kowalke 2014.
Packit 58578d
 Distributed under the Boost Software License, Version 1.0.
Packit 58578d
    (See accompanying file LICENSE_1_0.txt or copy at
Packit 58578d
          http://www.boost.org/LICENSE_1_0.txt
Packit 58578d
]
Packit 58578d
Packit 58578d
[section:coroutine Coroutine]
Packit 58578d
Packit 58578d
__boost_coroutine__ provides asymmetric coroutines.
Packit 58578d
Packit 58578d
Implementations that produce sequences of values typically use asymmetric
Packit 58578d
coroutines.
Packit 58578d
[footnote Moura, Ana Lucia De and Ierusalimschy, Roberto.
Packit 58578d
"Revisiting coroutines". ACM Trans. Program. Lang. Syst., Volume 31 Issue 2,
Packit 58578d
February 2009, Article No. 6]
Packit 58578d
Packit 58578d
Packit 58578d
[heading stackful]
Packit 58578d
Each instance of a coroutine has its own stack.
Packit 58578d
Packit 58578d
In contrast to stackless coroutines, stackful coroutines allow invoking the
Packit 58578d
suspend operation out of arbitrary sub-stackframes, enabling escape-and-reenter
Packit 58578d
recursive operations.
Packit 58578d
Packit 58578d
Packit 58578d
[heading move-only]
Packit 58578d
A coroutine is moveable-only.
Packit 58578d
Packit 58578d
If it were copyable, then its stack with all the objects allocated on it
Packit 58578d
would be copied too. That would force undefined behaviour if some of these
Packit 58578d
objects were RAII-classes (manage a resource via RAII pattern). When the first
Packit 58578d
of the coroutine copies terminates (unwinds its stack), the RAII class
Packit 58578d
destructors will release their managed resources. When the second copy
Packit 58578d
terminates, the same destructors will try to doubly-release the same resources,
Packit 58578d
leading to undefined behaviour.
Packit 58578d
Packit 58578d
Packit 58578d
[heading clean-up]
Packit 58578d
On coroutine destruction the associated stack will be unwound.
Packit 58578d
Packit 58578d
The constructor of coroutine allows you to pass a customized ['stack-allocator].
Packit 58578d
['stack-allocator] is free to deallocate the stack or cache it for future usage
Packit 58578d
(for coroutines created later).
Packit 58578d
Packit 58578d
Packit 58578d
[heading segmented stack]
Packit 58578d
__push_coro__ and __pull_coro__ support segmented stacks (growing on demand).
Packit 58578d
Packit 58578d
It is not always possible to accurately estimate the required stack size - in
Packit 58578d
most cases too much memory is allocated (waste of virtual address-space).
Packit 58578d
Packit 58578d
At construction a coroutine starts with a default (minimal) stack size. This
Packit 58578d
minimal stack size is the maximum of page size and the canonical size for signal
Packit 58578d
stack (macro SIGSTKSZ on POSIX).
Packit 58578d
Packit 58578d
At this time of writing only GCC (4.7)
Packit 58578d
[footnote [@http://gcc.gnu.org/wiki/SplitStacks Ian Lance Taylor, Split Stacks in GCC]]
Packit 58578d
is known to support segmented stacks. With version 1.54 __boost_coroutine__
Packit 58578d
provides support for [link segmented ['segmented stacks]].
Packit 58578d
Packit 58578d
The destructor releases the associated stack. The implementer is free to
Packit 58578d
deallocate the stack or to cache it for later usage.
Packit 58578d
Packit 58578d
Packit 58578d
[heading context switch]
Packit 58578d
A coroutine saves and restores registers according to the underlying ABI on
Packit 58578d
each context switch (using __boost_context__).
Packit 58578d
Packit 58578d
A context switch is done via __push_coro_op__ and __pull_coro_op__.
Packit 58578d
Packit 58578d
[warning Calling __push_coro_op__ and __pull_coro_op__ from inside the [_same]
Packit 58578d
coroutine results in undefined behaviour.]
Packit 58578d
Packit 58578d
As an example, the code below will result in undefined behaviour:
Packit 58578d
Packit 58578d
        boost::coroutines2::coroutine<void>::push_type coro(
Packit 58578d
            [&](boost::coroutines2::coroutine<void>::pull_type& yield){
Packit 58578d
                yield();
Packit 58578d
        });
Packit 58578d
        coro();
Packit 58578d
Packit 58578d
Packit 58578d
[include asymmetric.qbk]
Packit 58578d
Packit 58578d
Packit 58578d
[section Implementations: fcontext_t, ucontext_t and WinFiber]
Packit 58578d
Packit 58578d
[heading fcontext_t]
Packit 58578d
Packit 58578d
The implementation uses __fcontext__ per default. fcontext_t is based on
Packit 58578d
assembler and not available for all platforms. It provides a much better
Packit 58578d
performance than __ucontext__
Packit 58578d
(the context switch takes two magnitudes of order less CPU cycles) and __winfib__.
Packit 58578d
Packit 58578d
Packit 58578d
[heading ucontext_t]
Packit 58578d
Packit 58578d
As an alternative, [@https://en.wikipedia.org/wiki/Setcontext __ucontext__]
Packit 58578d
can be used by compiling with `BOOST_USE_UCONTEXT` and b2 property `context-impl=ucontext`.
Packit 58578d
__ucontext__ might be available on a broader range of POSIX-platforms but has
Packit 58578d
some (for instance deprecated since POSIX.1-2003, not C99 conform).
Packit 58578d
Packit 58578d
[note __cc__ supports [link segmented ['Segmented stacks]] only with
Packit 58578d
__ucontext__ as its implementation.]
Packit 58578d
Packit 58578d
Packit 58578d
[heading WinFiber]
Packit 58578d
Packit 58578d
With `BOOST_USE_WINFIB` and b2 property `context-impl=winfib` Win32-Fibers are used
Packit 58578d
as implementation for __cc__.
Packit 58578d
Packit 58578d
Because the TIB (thread information block) is not fully described in the MSDN,
Packit 58578d
it might be possible that not all required TIB-parts are swapped.
Packit 58578d
Packit 58578d
[note The first call of __cc__ converts the thread into a Windows fiber by
Packit 58578d
invoking `ConvertThreadToFiber()`. If desired, `ConvertFiberToThread()` has
Packit 58578d
to be called by the user explicitly in order to release resources allocated
Packit 58578d
by `ConvertThreadToFiber()` (e.g. after using boost.context). ]
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[endsect]