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:coroutine Coroutine] 9 10__boost_coroutine__ provides asymmetric coroutines. 11 12Implementations that produce sequences of values typically use asymmetric 13coroutines. 14[footnote Moura, Ana Lucia De and Ierusalimschy, Roberto. 15"Revisiting coroutines". ACM Trans. Program. Lang. Syst., Volume 31 Issue 2, 16February 2009, Article No. 6] 17 18 19[heading stackful] 20Each instance of a coroutine has its own stack. 21 22In contrast to stackless coroutines, stackful coroutines allow invoking the 23suspend operation out of arbitrary sub-stackframes, enabling escape-and-reenter 24recursive operations. 25 26 27[heading move-only] 28A coroutine is moveable-only. 29 30If it were copyable, then its stack with all the objects allocated on it 31would be copied too. That would force undefined behaviour if some of these 32objects were RAII-classes (manage a resource via RAII pattern). When the first 33of the coroutine copies terminates (unwinds its stack), the RAII class 34destructors will release their managed resources. When the second copy 35terminates, the same destructors will try to doubly-release the same resources, 36leading to undefined behaviour. 37 38 39[heading clean-up] 40On coroutine destruction the associated stack will be unwound. 41 42The constructor of coroutine allows you to pass a customized ['stack-allocator]. 43['stack-allocator] is free to deallocate the stack or cache it for future usage 44(for coroutines created later). 45 46 47[heading segmented stack] 48__push_coro__ and __pull_coro__ support segmented stacks (growing on demand). 49 50It is not always possible to accurately estimate the required stack size - in 51most cases too much memory is allocated (waste of virtual address-space). 52 53At construction a coroutine starts with a default (minimal) stack size. This 54minimal stack size is the maximum of page size and the canonical size for signal 55stack (macro SIGSTKSZ on POSIX). 56 57At this time of writing only GCC (4.7) 58[footnote [@http://gcc.gnu.org/wiki/SplitStacks Ian Lance Taylor, Split Stacks in GCC]] 59is known to support segmented stacks. With version 1.54 __boost_coroutine__ 60provides support for [link segmented ['segmented stacks]]. 61 62The destructor releases the associated stack. The implementer is free to 63deallocate the stack or to cache it for later usage. 64 65 66[heading context switch] 67A coroutine saves and restores registers according to the underlying ABI on 68each context switch (using __boost_context__). 69 70A context switch is done via __push_coro_op__ and __pull_coro_op__. 71 72[warning Calling __push_coro_op__ and __pull_coro_op__ from inside the [_same] 73coroutine results in undefined behaviour.] 74 75As an example, the code below will result in undefined behaviour: 76 77 boost::coroutines2::coroutine<void>::push_type coro( 78 [&](boost::coroutines2::coroutine<void>::pull_type& yield){ 79 coro(); 80 }); 81 coro(); 82 83 84[include asymmetric.qbk] 85 86 87[section Implementations: fcontext_t, ucontext_t and WinFiber] 88 89[heading fcontext_t] 90 91The implementation uses __fcontext__ per default. fcontext_t is based on 92assembler and not available for all platforms. It provides a much better 93performance than __ucontext__ 94(the context switch takes two magnitudes of order less CPU cycles) and __winfib__. 95 96 97[heading ucontext_t] 98 99As an alternative, [@https://en.wikipedia.org/wiki/Setcontext __ucontext__] 100can be used by compiling with `BOOST_USE_UCONTEXT` and b2 property `context-impl=ucontext`. 101__ucontext__ might be available on a broader range of POSIX-platforms but has 102some (for instance deprecated since POSIX.1-2003, not C99 conform). 103 104[note __cc__ supports [link segmented ['Segmented stacks]] only with 105__ucontext__ as its implementation.] 106 107 108[heading WinFiber] 109 110With `BOOST_USE_WINFIB` and b2 property `context-impl=winfib` Win32-Fibers are used 111as implementation for __cc__. 112 113Because the TIB (thread information block) is not fully described in the MSDN, 114it might be possible that not all required TIB-parts are swapped. 115 116[note The first call of __cc__ converts the thread into a Windows fiber by 117invoking `ConvertThreadToFiber()`. If desired, `ConvertFiberToThread()` has 118to be called by the user explicitly in order to release resources allocated 119by `ConvertThreadToFiber()` (e.g. after using boost.context). ] 120 121[endsect] 122 123[endsect] 124