early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,39 @@
# (C) Copyright 2008 Oliver Kowalke
#
# 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)
project context/doc ;
import boostbook ;
import quickbook ;
import modules ;
path-constant here : . ;
boostbook context
:
context.qbk
:
# Path for links to Boost:
<xsl:param>boost.root=../../../..
# HTML options first:
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=3
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=1
# How far down sections get TOC's
<xsl:param>toc.section.depth=10
# Max depth in each TOC:
<xsl:param>toc.max.depth=3
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=10
# Absolute path for images:
<format>pdf:<xsl:param>img.src.path=$(here)/html/
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : context ;
explicit boostrelease ;

View File

@@ -0,0 +1,16 @@
[/
Copyright Oliver Kowalke 2014.
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:acknowledgements Acknowledgments]
I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins,
Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon
Woodhull, Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith
Jeffery, Martin Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven
Watanabe, Vicente J. Botet Escriba, Wayne Piekarski.
[endsect]

View File

@@ -0,0 +1,39 @@
[/
Copyright Oliver Kowalke 2014.
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:architectures Architectures]
__boost_context__, using [link implementation ['fcontext_t]], supports following
architectures:
[table Supported architectures (<ABI|binary format>)
[[Architecture] [LINUX (UNIX)] [Windows] [MacOS X] [iOS]]
[[arm (aarch32)] [AAPCS|ELF] [AAPCS|PE] [-] [AAPCS|MACH-O]]
[[arm (aarch64)] [AAPCS|ELF] [-] [AAPCS|MACH-O] [AAPCS|MACH-O]]
[[i386] [SYSV|ELF] [MS|PE] [SYSV|MACH-O] [-]]
[[loongarch64] [SYSV|ELF] [-] [-] [-]]
[[mips] [O32|N64|ELF] [-] [-] [-]]
[[ppc32] [SYSV|ELF|XCOFF] [-] [SYSV|MACH-O] [-]]
[[ppc64] [SYSV|ELF|XCOFF] [-] [SYSV|MACH-O] [-]]
[[riscv64] [SYSV|ELF] [-] [SYSV] [-]]
[[s390x] [SYSV|ELF] [-] [-] [-]]
[[sparc] [-] [-] [-] [-]]
[[x86_64] [SYSV,X32|ELF] [MS|PE] [SYSV|MACH-O] [-]]
]
[note If the architecture is not supported but the platform provides
[link implementation __ucontext__], __boost_context__ should be
compiled with `BOOST_USE_UCONTEXT` and b2 property `context-impl=ucontext`.]
[section:crosscompiling Cross compiling]
Cross compiling the library requires to specify the build properties
<architecture>, <address-model>, <binary-format> and <abi> at b2 command line.
[endsect]
[endsect]

View File

@@ -0,0 +1,661 @@
[/
Copyright Oliver Kowalke 2016.
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
]
[#cc]
[section:cc Context switching with call/cc]
[note __callcc__ is the reference implementation of C++ proposal
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0534r3.pdf P0534R3:
call/cc (call-with-current-continuation): A low-level API for stackful context
switching].]
__callcc__ (call with current continuation) is a universal control operator
(well-known from the programming language Scheme) that captures the current
continuation as a first-class object and pass it as an argument to another
continuation.
A continuation (abstract concept of functional programming languages)
represents the state of the control flow of a program at a given point in time.
Continuations can be suspended and resumed later in order to change the control
flow of a program.
Modern micro-processors are registers machines; the content of processor
registers represent a continuation of the executed program at a given point in
time.
Operating systems simulate parallel execution of programs on a single processor
by switching between programs (context switch) by preserving and restoring the
continuation, e.g. the content of all registers.
[heading __cc__]
__cc__ is the C++ equivalent to Scheme's __callcc__ operator. It captures the
current continuation (the rest of the computation; code after __cc__) and
triggers a context switch. The context switch is achieved by preserving certain
registers (including instruction and stack pointer), defined by the calling
convention of the ABI, of the current continuation and restoring those
registers of the resumed continuation. The control flow of the resumed
continuation continues.
The current continuation is suspended and passed as argument to the resumed
continuation.
__cc__ expects a __context_fn__ with signature
`'continuation(continuation && c)'`. The parameter `c` represents the current
continuation from which this continuation was resumed (e.g. that has called
__cc__).
On return the __context_fn__ of the current continuation has to specify an
__con__ to which the execution control is transferred after termination
of the current continuation.
If an instance with valid state goes out of scope and the __context_fn__ has
not yet returned, the stack is traversed in order to access the control
structure (address stored at the first stack frame) and continuation's stack is
deallocated via the __stack_allocator__.
[note [link segmented ['Segmented stacks]] are supported by __cc__ using
[link implementation ['ucontext_t]].]
[heading __con__]
__con__ represents a continuation; it contains the content of preserved
registers and manages the associated stack (allocation/deallocation).
__con__ is a one-shot continuation - it can be used only once, after calling
__resume__ or __resume_with__ it is invalidated.
__con__ is only move-constructible and move-assignable.
As a first-class object __con__ can be applied to and returned from a function,
assigned to a variable or stored in a container.
A continuation is continued by calling `resume()`/`resume_with()`.
[heading Usage]
namespace ctx=boost::context;
int a;
ctx::continuation source=ctx::callcc(
[&a](ctx::continuation && sink){
a=0;
int b=1;
for(;;){
sink=sink.resume();
int next=a+b;
a=b;
b=next;
}
return std::move(sink);
});
for (int j=0;j<10;++j) {
std::cout << a << " ";
source=source.resume();
}
output:
0 1 1 2 3 5 8 13 21 34
This simple example demonstrates the basic usage of __callcc__ as a ['generator].
The continuation `sink` represents the ['main]-continuation (function `main()`).
`sink` is captured (current-continuation) by invoking __cc__ and passed as
parameter to the lambda.
Because the state is invalidated (one-shot continuation) by each call of
__resume__, the new state of the __con__, returned by __resume__, needs to be
assigned to `sink` after each call.
The lambda that calculates the Fibonacci numbers is executed inside the
continuation represented by `source`. Calculated Fibonacci numbers are
transferred between the two continuations via variable `a` (lambda capture
reference).
The locale variables `b` and ` next` remain their values during each context
switch. This is possible due `source` has its own stack and the stack is
exchanged by each context switch.
[heading Parameter passing]
Data can be transferred between two continuations via global pointers,
calling wrappers (like `std::bind`) or lambda captures.
namespace ctx=boost::context;
int i=1;
ctx::continuation c1=callcc([&i](ctx::continuation && c2){
std::printf("inside c1,i==%d\n",i);
i+=1;
return c2.resume();
});
std::printf("i==%d\n",i);
output:
inside c1,i==1
i==2
`callcc(<lambda>)` enters the lambda in continuation represented by `c1` with
lambda capture reference `i=1`.
The expression `c2.resume()` resumes the continuation `c2`.
On return of `callcc(<lambda>)`, the variable `i` has the value of `i+1`.
[heading Exception handling]
If the function executed inside a __context_fn__ emits an exception, the
application is terminated by calling `std::terminate()`. `std::exception_ptr`
can be used to transfer exceptions between different continuations.
[important Do not jump from inside a catch block.]
[#cc_ontop]
[heading Executing function on top of a continuation]
Sometimes it is useful to execute a new function on top of a resumed
continuation. For this purpose __resume_with__ has to be used.
The function passed as argument must accept a rvalue reference to __con__ and
return __con__.
namespace ctx=boost::context;
int data=0;
ctx::continuation c=ctx::callcc([&data](ctx::continuation && c) {
std::cout << "f1: entered first time: " << data << std::endl;
data+=1;
c=c.resume();
std::cout << "f1: entered second time: " << data << std::endl;
data+=1;
c=c.resume();
std::cout << "f1: entered third time: " << data << std::endl;
return std::move(c);
});
std::cout << "f1: returned first time: " << data << std::endl;
data+=1;
c=c.resume();
std::cout << "f1: returned second time: " << data << std::endl;
data+=1;
c=c.resume_with([&data](ctx::continuation && c){
std::cout << "f2: entered: " << data << std::endl;
data=-1;
return std::move( c);
});
std::cout << "f1: returned third time" << std::endl;
output:
f1: entered first time: 0
f1: returned first time: 1
f1: entered second time: 2
f1: returned second time: 3
f2: entered: 4
f1: entered third time: -1
f1: returned third time
The expression `c.resume_with(...)` executes a lambda on top of continuation
`c`, e.g. an additional stack frame is allocated on top of the stack.
This lambda assigns `-1` to `data` and returns to the second invocation of
`c.resume()`.
Another option is to execute a function on top of the continuation that throws
an exception.
namespace ctx=boost::context;
struct my_exception : public std::runtime_error {
ctx::continuation c;
my_exception(ctx::continuation && c_,std::string const& what) :
std::runtime_error{ what },
c{ std::move( c_) } {
}
};
ctx::continuation c=ctx::callcc([](ctx::continuation && c) {
for (;;) {
try {
std::cout << "entered" << std::endl;
c=c.resume();
} catch (my_exception & ex) {
std::cerr << "my_exception: " << ex.what() << std::endl;
return std::move(ex.c);
}
}
return std::move(c);
});
c = c.resume_with(
[](ctx::continuation && c){
throw my_exception(std::move(c),"abc");
return std::move( c);
});
output:
entered
my_exception: abc
In this exception `my_exception` is throw from a function invoked on-top of
continuation `c` and catched inside the `for`-loop.
[heading Stack unwinding]
On construction of __con__ a stack is allocated.
If the __context_fn__ returns the stack will be destructed.
If the __context_fn__ has not yet returned and the destructor of an valid
__con__ instance (e.g. ['continuation::operator bool()] returns
`true`) is called, the stack will be destructed too.
[important Code executed by __context_fn__ must not prevent the propagation ofs
the __forced_unwind__ exception. Absorbing that exception will cause stack
unwinding to fail. Thus, any code that catches all exceptions must re-throw any
pending __forced_unwind__ exception.]
[#cc_prealloc]
[heading Allocating control structures on top of stack]
Allocating control structures on top of the stack requires to allocated the
__stack_context__ and create the control structure with placement new before
__con__ is created.
[note The user is responsible for destructing the control structure at the top
of the stack.]
namespace ctx=boost::context;
// stack-allocator used for (de-)allocating stack
fixedsize_stack salloc(4048);
// allocate stack space
stack_context sctx(salloc.allocate());
// reserve space for control structure on top of the stack
void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure);
std::size_t size=sctx.size-sizeof(my_control_structure);
// placement new creates control structure on reserved space
my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc);
...
// destructing the control structure
cs->~my_control_structure();
...
struct my_control_structure {
// captured continuation
ctx::continuation c;
template< typename StackAllocator >
my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) :
// create captured continuation
c{} {
c=ctx::callcc(std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func);
}
...
};
[heading Inverting the control flow]
namespace ctx=boost::context;
/*
* grammar:
* P ---> E '\0'
* E ---> T {('+'|'-') T}
* T ---> S {('*'|'/') S}
* S ---> digit | '(' E ')'
*/
class Parser{
char next;
std::istream& is;
std::function<void(char)> cb;
char pull(){
return std::char_traits<char>::to_char_type(is.get());
}
void scan(){
do{
next=pull();
}
while(isspace(next));
}
public:
Parser(std::istream& is_,std::function<void(char)> cb_) :
next(), is(is_), cb(cb_)
{}
void run() {
scan();
E();
}
private:
void E(){
T();
while (next=='+'||next=='-'){
cb(next);
scan();
T();
}
}
void T(){
S();
while (next=='*'||next=='/'){
cb(next);
scan();
S();
}
}
void S(){
if (isdigit(next)){
cb(next);
scan();
}
else if(next=='('){
cb(next);
scan();
E();
if (next==')'){
cb(next);
scan();
}else{
throw std::runtime_error("parsing failed");
}
}
else{
throw std::runtime_error("parsing failed");
}
}
};
std::istringstream is("1+1");
// execute parser in new continuation
ctx::continuation source;
// user-code pulls parsed data from parser
// invert control flow
char c;
bool done=false;
source=ctx::callcc(
[&is,&c,&done](ctx::continuation && sink){
// create parser with callback function
Parser p(is,
[&sink,&c](char c_){
// resume main continuation
c=c_;
sink=sink.resume();
});
// start recursive parsing
p.run();
// signal termination
done=true;
// resume main continuation
return std::move(sink);
});
while(!done){
printf("Parsed: %c\n",c);
source=source.resume();
}
output:
Parsed: 1
Parsed: +
Parsed: 1
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using __callcc__ the control flow can be inverted, e.g. the
user-code pulls parsed symbols from the parser - instead to get pushed from the
parser (via callback).
The data (character) is transferred between the two continuations.
[#implementation]
[section Implementations: fcontext_t, ucontext_t and WinFiber]
[heading fcontext_t]
The implementation uses __fcontext__ per default. fcontext_t is based on
assembler and not available for all platforms. It provides a much better
performance than __ucontext__
(the context switch takes two magnitudes of order less CPU cycles; see section
[link performance ['performance]]) and __winfib__.
[note Because the TIB (thread information block on Windows) is not fully
described in the MSDN, it might be possible that not all required TIB-parts are
swapped. Using WinFiber implementation migh be an alternative.]
[heading ucontext_t]
As an alternative, [@https://en.wikipedia.org/wiki/Setcontext __ucontext__]
can be used by compiling with `BOOST_USE_UCONTEXT` and b2 property
`context-impl=ucontext`.
__ucontext__ might be available on a broader range of POSIX-platforms but has
some [link ucontext ['disadvantages]] (for instance deprecated since
POSIX.1-2003, not C99 conform).
[note __cc__ supports [link segmented ['Segmented stacks]] only with
__ucontext__ as its implementation.]
[heading WinFiber]
With `BOOST_USE_WINFIB` and b2 property `context-impl=winfib` Win32-Fibers are
used as implementation for __cc__.
[note The first call of __cc__ converts the thread into a Windows fiber by
invoking `ConvertThreadToFiber()`. If desired, `ConvertFiberToThread()` has
to be called by the user explicitly in order to release resources allocated
by `ConvertThreadToFiber()` (e.g. after using boost.context). ]
[endsect]
[section Class `continuation`]
#include <boost/context/continuation.hpp>
class continuation {
public:
continuation() noexcept = default;
~continuation();
continuation(continuation && other) noexcept;
continuation & operator=(continuation && other) noexcept;
continuation(continuation const& other) noexcept = delete;
continuation & operator=(continuation const& other) noexcept = delete;
continuation resume();
template<typename Fn>
continuation resume_with(Fn && fn);
explicit operator bool() const noexcept;
bool operator!() const noexcept;
bool operator==(continuation const& other) const noexcept;
bool operator!=(continuation const& other) const noexcept;
bool operator<(continuation const& other) const noexcept;
bool operator>(continuation const& other) const noexcept;
bool operator<=(continuation const& other) const noexcept;
bool operator>=(continuation const& other) const noexcept;
template<typename charT,class traitsT>
friend std::basic_ostream<charT,traitsT> &
operator<<(std::basic_ostream<charT,traitsT> & os,continuation const& other) {
void swap(continuation & other) noexcept;
};
[constructor_heading cc..constructor]
continuation() noexcept;
[variablelist
[[Effects:] [Creates a invalid continuation.]]
[[Throws:] [Nothing.]]
]
[destructor_heading cc..destructor destructor]
~continuation();
[variablelist
[[Effects:] [Destructs the associated stack if `*this` is a valid continuation,
e.g. ['continuation::operator bool()] returns `true`.]]
[[Throws:] [Nothing.]]
]
[move_constructor_heading cc..move constructor]
continuation(continuation && other) noexcept;
[variablelist
[[Effects:] [Moves underlying capture continuation to `*this`.]]
[[Throws:] [Nothing.]]
]
[move_assignment_heading cc..move assignment]
continuation & operator=(continuation && other) noexcept;
[variablelist
[[Effects:] [Moves the state of `other` to `*this` using move semantics.]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_call..operator()]
continuation resume();
template<typename Fn>
continuation resume_with(Fn && fn);
[variablelist
[[Effects:] [Captures current continuation and resumes `*this`.
The function `resume_with`, is used to execute function `fn` in the execution context of
`*this` (e.g. the stack frame of `fn` is allocated on stack of `*this`).]]
[[Returns:] [The continuation representing the continuation that has been
suspended.]]
[[Note:] [Function `fn` needs to return `continuation`.]]
[[Note:] [The returned continuation indicates if the suspended continuation has
terminated (return from context-function) via `bool operator()`.]]
]
[operator_heading cc..operator_bool..operator bool]
explicit operator bool() const noexcept;
[variablelist
[[Returns:] [`true` if `*this` points to a captured continuation.]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_not..operator!]
bool operator!() const noexcept;
[variablelist
[[Returns:] [`true` if `*this` does not point to a captured continuation.]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_equal..operator==]
bool operator==(continuation const& other) const noexcept;
[variablelist
[[Returns:] [`true` if `*this` and `other` represent the same continuation,
`false` otherwise.]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_notequal..operator!=]
bool operator!=(continuation const& other) const noexcept;
[variablelist
[[Returns:] [[`! (other == * this)]]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_less..operator<]
bool operator<(continuation const& other) const noexcept;
[variablelist
[[Returns:] [`true` if `*this != other` is true and the
implementation-defined total order of `continuation` values places `*this`
before `other`, false otherwise.]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_greater..operator>]
bool operator>(continuation const& other) const noexcept;
[variablelist
[[Returns:] [`other < * this`]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_lesseq..operator<=]
bool operator<=(continuation const& other) const noexcept;
[variablelist
[[Returns:] [`! (other < * this)`]]
[[Throws:] [Nothing.]]
]
[operator_heading cc..operator_greatereq..operator>=]
bool operator>=(continuation const& other) const noexcept;
[variablelist
[[Returns:] [`! (* this < other)`]]
[[Throws:] [Nothing.]]
]
[hding cc_..Non-member function [`operator<<()]]
template<typename charT,class traitsT>
std::basic_ostream<charT,traitsT> &
operator<<(std::basic_ostream<charT,traitsT> & os,continuation const& other);
[variablelist
[[Effects:] [Writes the representation of `other` to stream `os`.]]
[[Returns:] [`os`]]
]
[heading Call with current continuation]
#include <boost/context/continuation.hpp>
template<typename Fn>
continuation callcc(Fn && fn);
template<typename StackAlloc,typename Fn>
continuation callcc(std::allocator_arg_t,StackAlloc salloc,Fn && fn);
template<typename StackAlloc,typename Fn>
continuation callcc(std::allocator_arg_t,preallocated palloc,StackAlloc salloc,Fn && fn);
[variablelist
[[Effects:] [Captures current continuation and creates a new continuation
prepared to execute `fn`. `fixedsize_stack` is used as default stack allocator
(stack size == fixedsize_stack::traits::default_size()).
The function with argument type `preallocated`, is used to create a user
defined data [link cc_prealloc (for instance additional control structures)] on
top of the stack.]]
[[Returns:] [The continuation representing the contexcontinuation that has been
suspended.]]
[[Note:] [The returned continuation indicates if the suspended continuation has
terminated (return from context-function) via `bool operator()`.]]
]
[endsect]
[endsect]

View File

@@ -0,0 +1,172 @@
[/
Copyright Oliver Kowalke 2014.
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
]
[library Context
[quickbook 1.5]
[authors [Kowalke, Oliver]]
[copyright 2014 Oliver Kowalke]
[id context]
[purpose C++ Library for swiching different user ctx]
[category text]
[license
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])
]
]
[def __boost_build__ [*Boost.Build]]
[def __boost_context__ [*Boost.Context]]
[template mdash[] '''&mdash;''']
[template superscript[exp] '''<superscript>'''[exp]'''</superscript>''']
[template class_heading[class_name]
[hding class_[class_name]..Class [`[class_name]]]
]
[template class_link[class_name] [dblink class_[class_name]..[`[class_name]]]]
[template template_heading[class_name]
[hding class_[class_name]..Template [`[class_name]<>]]
]
[template template_link[class_name] [dblink class_[class_name]..[`[class_name]<>]]]
[template member_heading[class_name method_name]
[operator_heading [class_name]..[method_name]..[method_name]]
]
[template member_link[class_name method_name] [operator_link [class_name]..[method_name]..[method_name]]]
[template operator_heading[class_name method_name method_text]
[hding [class_name]_[method_name]..Member function [`[method_text]]()]
]
[template operator_link[class_name method_name method_text] [dblink [class_name]_[method_name]..[`[class_name]::[method_text]()]]]
[template template_member_heading[class_name method_name]
[hding [class_name]_[method_name]..Templated member function [`[method_name]]()]
]
[template template_member_link[class_name method_name] [member_link [class_name]..[method_name]]]
[template static_member_heading[class_name method_name]
[hding [class_name]_[method_name]..Static member function [`[method_name]]()]
]
[template static_member_link[class_name method_name] [member_link [class_name]..[method_name]]]
[template data_member_heading[class_name member_name]
[hding [class_name]_[member_name]..Data member [`[member_name]]]
]
[template data_member_link[class_name member_name] [dblink [class_name]_[member_name]..[`[class_name]::[member_name]]]]
[template function_heading[function_name]
[hding [function_name]..Non-member function [`[function_name]()]]
]
[template function_link[function_name] [dblink [function_name]..[`[function_name]()]]]
[template ns_function_heading[namespace function_name]
[hding [namespace]_[function_name]..Non-member function [`[namespace]::[function_name]()]]
]
[template ns_function_link[namespace function_name] [dblink [namespace]_[function_name]..[`[namespace]::[function_name]()]]]
[template constructor_heading[class_name constructor_name]
[hding [class_name]_[constructor_name]..Constructor]
]
[template destructor_heading[class_name destructor_name]
[hding [class_name]_[destructor_name]..Destructor]
]
[template copy_constructor_heading[class_name copy_constructor_name]
[hding [class_name]_[copy_constructor_name]..Copy constructor]
]
[template move_constructor_heading[class_name move_constructor_name]
[hding [class_name]_[move_constructor_name]..Move constructor]
]
[template copy_assignment_heading[class_name copy_assignment_name]
[hding [class_name]_[copy_assignment_name]..Copy assignment operator]
]
[template move_assignment_heading[class_name move_assignment_name]
[hding [class_name]_[move_assignment_name]..Move assignment operator]
]
[template anchor[name] '''<anchor id="'''[name]'''"/>''']
[template hding[name title]
'''<bridgehead renderas="sect4" id="'''[name]_bridgehead'''">
<phrase id="'''[name]'''"/>
<link linkend="'''[name]'''">'''[title]'''</link>
</bridgehead>'''
]
[template dblink[id text] '''<link linkend="'''[id]'''">'''[text]'''</link>''']
[template `[text] '''<code>'''[text]'''</code>''']
[def __callcc__ ['call/cc]]
[def __context_fn__ ['context-function]]
[def __coroutine__ ['coroutine]]
[def __coroutines__ ['coroutines]]
[def __coop_threads__ ['cooperative threads (userland threads)]]
[def __fiber__ ['fiber]]
[def __fls__ ['fiber-local storage]]
[def __guard_page__ ['guard-page]]
[def __not_a_context__ ['not-a-context]]
[def __stack__ ['stack]]
[def __thread__ ['thread]]
[def __threads__ ['threads]]
[def __tls__ ['thread-local storage]]
[def __toe__ ['thread-of-execution]]
[def __stack_allocator__ ['StackAllocator]]
[def __stack_allocator_concept__ ['stack-allocator concept]]
[def __stack_traits__ ['stack-traits]]
[def __cc__ [link cc ['callcc()]]]
[def __con__ [link cc ['continuation]]]
[def __fib__ [link ff ['fiber]]]
[def __fcontext__ ['fcontext_t]]
[def __forced_unwind__ ['detail::forced_unwind]]
[def __ucontext__ ['ucontext_t]]
[def __fixedsize__ ['fixedsize_stack]]
[def __pooled_fixedsize__ ['pooled_fixedsize_stack]]
[def __protected_fixedsize__ ['protected_fixedsize_stack]]
[def __resume__ ['continuation::resume()]]
[def __resume_with__ ['continuation::resume_with()]]
[def __segmented__ [link segmented ['segmented_stack]]]
[def __segmented_stack__ ['segmented_stack]]
[def __stack_context__ ['stack_context]]
[def __winfib__ ['WinFiber]]
[def __fls_alloc__ ['::FlsAlloc()]]
[def __fls_free__ ['::FlsFree()]]
[def __bad_alloc__ ['std::bad_alloc]]
[def __ec_current__ ['execution_context::current()]]
[def __ec_op__ ['execution_context::operator()]]
[def __fc_base__ ['fc_base]]
[def __fc_link__ ['fc_link]]
[def __jump_fcontext__ ['jump_fcontext()]]
[def __make_fcontext__ ['make_fcontext()]]
[def __invalid_argument__ ['std::invalid_argument]]
[def __ot_error__ ['ontop_error]]
[def __stack_alloc__ ['allocate()]]
[def __stack_dealloc__ ['deallocate()]]
[def __stack_helper__ ['stack_helper]]
[def __yield__ ['yield]]
[def __context_ns__ ['boost::context]]
[include overview.qbk]
[include requirements.qbk]
[include fiber.qbk]
[include callcc.qbk]
[include stack.qbk]
[include preallocated.qbk]
[include performance.qbk]
[include architectures.qbk]
[include rationale.qbk]
[include reference.qbk]
[include acknowledgements.qbk]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,643 @@
[/
Copyright Oliver Kowalke 2016.
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
]
[#ff]
[section:ff Context switching with fibers]
[note __fiber__ is the reference implementation of C++ proposal
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0876r0.pdf P0876R0:
fibers without scheduler].]
A __fiber__ represents the state of the control flow of a program at a given
point in time. Fibers can be suspended and resumed later in order to change the
control flow of a program.
Modern micro-processors are registers machines; the content of processor
registers represent a fiber of the executed program at a given point in time.
Operating systems simulate parallel execution of programs on a single processor
by switching between programs (context switch) by preserving and restoring the
fiber, e.g. the content of all registers.
[heading __fib__]
__fib__ captures the current fiber (the rest of the computation; code after
__fib__) and triggers a context switch. The context switch is achieved by
preserving certain registers (including instruction and stack pointer), defined
by the calling convention of the ABI, of the current fiber and restoring those
registers of the resumed fiber. The control flow of the resumed fiber continues.
The current fiber is suspended and passed as argument to the resumed fiber.
__fib__ expects a __context_fn__ with signature `'fiber(fiber && f)'`. The
parameter `f` represents the current fiber from which this fiber was resumed
(e.g. that has called __fib__).
On return the __context_fn__ of the current fiber has to specify an __fib__ to
which the execution control is transferred after termination of the current
fiber.
If an instance with valid state goes out of scope and the __context_fn__ has not
yet returned, the stack is traversed in order to access the control structure
(address stored at the first stack frame) and fiber's stack is deallocated via
the __stack_allocator__.
[note [link segmented ['Segmented stacks]] are supported by __fib__ using [link
implementation ['ucontext_t]].]
__fib__ represents a __fiber__; it contains the content of preserved registers
and manages the associated stack (allocation/deallocation). __fib__ is a
one-shot fiber - it can be used only once, after calling __resume__ or
__resume_with__ it is invalidated.
__fib__ is only move-constructible and move-assignable.
As a first-class object __fib__ can be applied to and returned from a function,
assigned to a variable or stored in a container.
A fiber is continued by calling `resume()`/`resume_with()`.
[heading Usage]
namespace ctx=boost::context;
int a;
ctx::fiber source{[&a](ctx::fiber&& sink){
a=0;
int b=1;
for(;;){
sink=std::move(sink).resume();
int next=a+b;
a=b;
b=next;
}
return std::move(sink);
}};
for (int j=0;j<10;++j) {
source=std::move(source).resume();
std::cout << a << " ";
}
output:
0 1 1 2 3 5 8 13 21 34
This simple example demonstrates the basic usage of __fib__ as a ['generator].
The fiber `sink` represents the ['main]-fiber (function `main()`).
`sink` is captured (current-fiber) by invoking __fib__ and passed as parameter
to the lambda.
Because the state is invalidated (one-shot fiber) by each call of __resume__,
the new state of the __fib__, returned by __resume__, needs to be assigned to
`sink` after each call. In order to express the invalidation of the resumed fiber,
the member functions `resume()` and `resume_with()` are rvalue-ref qualified.
Both functions bind only to rvalues. Thus an lvalue fiber must be casted to an
rvalue via `std::move()`.
The lambda that calculates the Fibonacci numbers is executed inside the fiber
represented by `source`. Calculated Fibonacci numbers are transferred between
the two fibers via variable `a` (lambda capture reference).
The locale variables `b` and ` next` remain their values during each context
switch. This is possible due `source` has its own stack and the stack is
exchanged by each context switch.
[heading Parameter passing]
Data can be transferred between two fibers via global pointers, calling wrappers
(like `std::bind`) or lambda captures.
namespace ctx=boost::context;
int i=1;
ctx::fiber f1{[&i](ctx::fiber&& f2){
std::printf("inside f1,i==%d\n",i);
i+=1;
return std::move(f2).resume();
}};
f1=std::move(f1).resume();
std::printf("i==%d\n",i);
output:
inside c1,i==1
i==2
`f1.resume()` enters the lambda in fiber represented by `f1` with lambda capture
reference `i=1`. The expression `f2.resume()` resumes the fiber `f2`. On return
of `f1.resume()`, the variable `i` has the value of `i+1`.
[heading Exception handling]
If the function executed inside a __context_fn__ emits an exception, the
application is terminated by calling `std::terminate()`. `std::exception_ptr`
can be used to transfer exceptions between different fibers.
[important Do not jump from inside a catch block.]
[#ff_ontop]
[heading Executing function on top of a fiber]
Sometimes it is useful to execute a new function on top of a resumed fiber. For
this purpose __resume_with__ has to be used.
The function passed as argument must accept a rvalue reference to __fib__ and
return __fib__.
namespace ctx=boost::context;
int data=0;
ctx::fiber f1{[&data](ctx::fiber&& f2) {
std::cout << "f1: entered first time: " << data << std::endl;
data+=1;
f2=std::move(f2).resume();
std::cout << "f1: entered second time: " << data << std::endl;
data+=1;
f2=std::move(f2).resume();
std::cout << "f1: entered third time: " << data << std::endl;
return std::move(f2);
}};
f1=std::move(f1).resume();
std::cout << "f1: returned first time: " << data << std::endl;
data+=1;
f1=std::move(f1).resume();
std::cout << "f1: returned second time: " << data << std::endl;
data+=1;
f1=std::move(f1).resume_with([&data](ctx::fiber&& f2){
std::cout << "f2: entered: " << data << std::endl;
data=-1;
return std::move(f2);
});
std::cout << "f1: returned third time" << std::endl;
output:
f1: entered first time: 0
f1: returned first time: 1
f1: entered second time: 2
f1: returned second time: 3
f2: entered: 4
f1: entered third time: -1
f1: returned third time
The expression `f1.resume_with(...)` executes a lambda on top of fiber `f1`,
e.g. an additional stack frame is allocated on top of the stack.
This lambda assigns `-1` to `data` and returns to the second invocation of
`f1.resume()`.
Another option is to execute a function on top of the fiber that throws
an exception.
namespace ctx=boost::context;
struct my_exception : public std::runtime_error {
ctx::fiber f;
my_exception(ctx::fiber&& f_,std::string const& what) :
std::runtime_error{ what },
f{ std::move(f_) } {
}
};
ctx::fiber f{[](ctx::fiber && f) ->ctx::fiber {
std::cout << "entered" << std::endl;
try {
f=std::move(f).resume();
} catch (my_exception & ex) {
std::cerr << "my_exception: " << ex.what() << std::endl;
return std::move(ex.f);
}
return {};
});
f=std::move(f).resume();
f=std::move(f).resume_with([](ctx::fiber && f) ->ctx::fiber {
throw my_exception(std::move(f),"abc");
return {};
});
output:
entered
my_exception: abc
In this exception `my_exception` is throw from a function invoked on-top of
fiber `f` and catched inside the `for`-loop.
[heading Stack unwinding]
On construction of __fib__ a stack is allocated.
If the __context_fn__ returns the stack will be destructed.
If the __context_fn__ has not yet returned and the destructor of an valid
__fib__ instance (e.g. ['fiber::operator bool()] returns
`true`) is called, the stack will be destructed too.
[important Code executed by __context_fn__ must not prevent the propagation ofs
the __forced_unwind__ exception. Absorbing that exception will cause stack
unwinding to fail. Thus, any code that catches all exceptions must re-throw any
pending __forced_unwind__ exception.]
[#ff_prealloc]
[heading Allocating control structures on top of stack]
Allocating control structures on top of the stack requires to allocated the
__stack_context__ and create the control structure with placement new before
__fib__ is created.
[note The user is responsible for destructing the control structure at the top
of the stack.]
namespace ctx=boost::context;
// stack-allocator used for (de-)allocating stack
fixedsize_stack salloc(4048);
// allocate stack space
stack_context sctx(salloc.allocate());
// reserve space for control structure on top of the stack
void * sp=static_cast<char*>(sctx.sp)-sizeof(my_control_structure);
std::size_t size=sctx.size-sizeof(my_control_structure);
// placement new creates control structure on reserved space
my_control_structure * cs=new(sp)my_control_structure(sp,size,sctx,salloc);
...
// destructing the control structure
cs->~my_control_structure();
...
struct my_control_structure {
// captured fiber
ctx::fiber f;
template< typename StackAllocator >
my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) :
// create captured fiber
f{std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func} {
}
...
};
[heading Inverting the control flow]
namespace ctx=boost::context;
/*
* grammar:
* P ---> E '\0'
* E ---> T {('+'|'-') T}
* T ---> S {('*'|'/') S}
* S ---> digit | '(' E ')'
*/
class Parser{
char next;
std::istream& is;
std::function<void(char)> cb;
char pull(){
return std::char_traits<char>::to_char_type(is.get());
}
void scan(){
do{
next=pull();
}
while(isspace(next));
}
public:
Parser(std::istream& is_,std::function<void(char)> cb_) :
next(), is(is_), cb(cb_)
{}
void run() {
scan();
E();
}
private:
void E(){
T();
while (next=='+'||next=='-'){
cb(next);
scan();
T();
}
}
void T(){
S();
while (next=='*'||next=='/'){
cb(next);
scan();
S();
}
}
void S(){
if (isdigit(next)){
cb(next);
scan();
}
else if(next=='('){
cb(next);
scan();
E();
if (next==')'){
cb(next);
scan();
}else{
throw std::runtime_error("parsing failed");
}
}
else{
throw std::runtime_error("parsing failed");
}
}
};
std::istringstream is("1+1");
// user-code pulls parsed data from parser
// invert control flow
char c;
bool done=false;
// execute parser in new fiber
ctx::fiber source{[&is,&c,&done](ctx::fiber&& sink){
// create parser with callback function
Parser p(is,
[&sink,&c](char c_){
// resume main fiber
c=c_;
sink=std::move(sink).resume();
});
// start recursive parsing
p.run();
// signal termination
done=true;
// resume main fiber
return std::move(sink);
}};
source=std::move(source).resume();
while(!done){
printf("Parsed: %c\n",c);
source=std::move(source).resume();
}
output:
Parsed: 1
Parsed: +
Parsed: 1
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using __fib__ the control flow can be inverted, e.g. the
user-code pulls parsed symbols from the parser - instead to get pushed from the
parser (via callback).
The data (character) is transferred between the two fibers.
[#implementation]
[section Implementations: fcontext_t, ucontext_t and WinFiber]
[heading fcontext_t]
The implementation uses __fcontext__ per default. fcontext_t is based on
assembler and not available for all platforms. It provides a much better
performance than __ucontext__
(the context switch takes two magnitudes of order less CPU cycles; see section
[link performance ['performance]]) and __winfib__.
[note Because the TIB (thread information block on Windows) is not fully
described in the MSDN, it might be possible that not all required TIB-parts are
swapped. Using WinFiber implementation migh be an alternative.]
[heading ucontext_t]
As an alternative, [@https://en.wikipedia.org/wiki/Setcontext __ucontext__]
can be used by compiling with `BOOST_USE_UCONTEXT` and b2 property
`context-impl=ucontext`.
__ucontext__ might be available on a broader range of POSIX-platforms but has
some [link ucontext ['disadvantages]] (for instance deprecated since
POSIX.1-2003, not C99 conform).
[note __fib__ supports [link segmented ['Segmented stacks]] only with
__ucontext__ as its implementation.]
[heading WinFiber]
With `BOOST_USE_WINFIB` and b2 property `context-impl=winfib` Win32-Fibers are
used as implementation for __fib__.
[note The first call of __fib__ converts the thread into a Windows fiber by
invoking `ConvertThreadToFiber()`. If desired, `ConvertFiberToThread()` has
to be called by the user explicitly in order to release resources allocated
by `ConvertThreadToFiber()` (e.g. after using boost.context). ]
[endsect]
[section Class `fiber`]
#include <boost/context/fiber.hpp>
class fiber {
public:
fiber() noexcept;
template<typename Fn>
fiber(Fn && fn);
template<typename StackAlloc, typename Fn>
fiber(std::allocator_arg_t, StackAlloc && salloc, Fn && fn);
~fiber();
fiber(fiber && other) noexcept;
fiber & operator=(fiber && other) noexcept;
fiber(fiber const& other) noexcept = delete;
fiber & operator=(fiber const& other) noexcept = delete;
fiber resume() &&;
template<typename Fn>
fiber resume_with(Fn && fn) &&;
explicit operator bool() const noexcept;
bool operator!() const noexcept;
bool operator==(fiber const& other) const noexcept;
bool operator!=(fiber const& other) const noexcept;
bool operator<(fiber const& other) const noexcept;
bool operator>(fiber const& other) const noexcept;
bool operator<=(fiber const& other) const noexcept;
bool operator>=(fiber const& other) const noexcept;
template<typename charT,class traitsT>
friend std::basic_ostream<charT,traitsT> &
operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other) {
void swap(fiber & other) noexcept;
};
[constructor_heading ff..constructor1]
fiber() noexcept;
[variablelist
[[Effects:] [Creates a invalid fiber.]]
[[Throws:] [Nothing.]]
]
[constructor_heading ff..constructor2]
template<typename Fn>
fiber(Fn && fn);
template<typename StackAlloc, typename Fn>
fiber(std::allocator_arg_t, StackAlloc && salloc, Fn && fn);
[variablelist
[[Effects:] [Creates a new fiber and prepares the context to execute `fn`.
`fixedsize_stack` is used as default stack allocator
(stack size == fixedsize_stack::traits::default_size()). The constructor with
argument type `preallocated`, is used to create a user defined data
[link ff_prealloc (for instance additional control structures)] on top of the
stack.]]
]
[destructor_heading ff..destructor destructor]
~fiber();
[variablelist
[[Effects:] [Destructs the associated stack if `*this` is a valid fiber,
e.g. ['fiber::operator bool()] returns `true`.]]
[[Throws:] [Nothing.]]
]
[move_constructor_heading ff..move constructor]
fiber(fiber && other) noexcept;
[variablelist
[[Effects:] [Moves underlying capture fiber to `*this`.]]
[[Throws:] [Nothing.]]
]
[move_assignment_heading ff..move assignment]
fiber & operator=(fiber && other) noexcept;
[variablelist
[[Effects:] [Moves the state of `other` to `*this` using move semantics.]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_call..operator()]
fiber resume() &&;
template<typename Fn>
fiber resume_with(Fn && fn) &&;
[variablelist
[[Effects:] [Captures current fiber and resumes `*this`.
The function `resume_with`, is used to execute function `fn` in the execution context of
`*this` (e.g. the stack frame of `fn` is allocated on stack of `*this`).]]
[[Returns:] [The fiber representing the fiber that has been
suspended.]]
[[Note:] [Because `*this` gets invalidated, `resume()` and `resume_with()` are rvalue-ref
qualified and bind only to rvalues.]]
[[Note:] [Function `fn` needs to return `fiber`.]]
[[Note:] [The returned fiber indicates if the suspended fiber has
terminated (return from context-function) via `bool operator()`.]]
]
[operator_heading ff..operator_bool..operator bool]
explicit operator bool() const noexcept;
[variablelist
[[Returns:] [`true` if `*this` points to a captured fiber.]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_not..operator!]
bool operator!() const noexcept;
[variablelist
[[Returns:] [`true` if `*this` does not point to a captured fiber.]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_equal..operator==]
bool operator==(fiber const& other) const noexcept;
[variablelist
[[Returns:] [`true` if `*this` and `other` represent the same fiber,
`false` otherwise.]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_notequal..operator!=]
bool operator!=(fiber const& other) const noexcept;
[variablelist
[[Returns:] [[`! (other == * this)]]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_less..operator<]
bool operator<(fiber const& other) const noexcept;
[variablelist
[[Returns:] [`true` if `*this != other` is true and the
implementation-defined total order of `fiber` values places `*this`
before `other`, false otherwise.]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_greater..operator>]
bool operator>(fiber const& other) const noexcept;
[variablelist
[[Returns:] [`other < * this`]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_lesseq..operator<=]
bool operator<=(fiber const& other) const noexcept;
[variablelist
[[Returns:] [`! (other < * this)`]]
[[Throws:] [Nothing.]]
]
[operator_heading ff..operator_greatereq..operator>=]
bool operator>=(fiber const& other) const noexcept;
[variablelist
[[Returns:] [`! (* this < other)`]]
[[Throws:] [Nothing.]]
]
[hding ff_..Non-member function [`operator<<()]]
template<typename charT,class traitsT>
std::basic_ostream<charT,traitsT> &
operator<<(std::basic_ostream<charT,traitsT> & os,fiber const& other);
[variablelist
[[Effects:] [Writes the representation of `other` to stream `os`.]]
[[Returns:] [`os`]]
]
[endsect]
[endsect]

View File

@@ -0,0 +1,49 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Acknowledgments</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="reference.html" title="Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.acknowledgements"></a><a class="link" href="acknowledgements.html" title="Acknowledgments">Acknowledgments</a>
</h2></div></div></div>
<p>
I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins,
Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull,
Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin
Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente
J. Botet Escriba, Wayne Piekarski.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="reference.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,396 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Architectures</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="performance.html" title="Performance">
<link rel="next" href="architectures/crosscompiling.html" title="Cross compiling">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="performance.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="architectures/crosscompiling.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.architectures"></a><a class="link" href="architectures.html" title="Architectures">Architectures</a>
</h2></div></div></div>
<div class="toc"><dl><dt><span class="section"><a href="architectures/crosscompiling.html">Cross compiling</a></span></dt></dl></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span>, using <a class="link" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>fcontext_t</em></span></a>,
supports following architectures:
</p>
<div class="table">
<a name="context.architectures.supported_architectures___abi_binary_format__"></a><p class="title"><b>Table&#160;1.2.&#160;Supported architectures (&lt;ABI|binary format&gt;)</b></p>
<div class="table-contents"><table class="table" summary="Supported architectures (&lt;ABI|binary format&gt;)">
<colgroup>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Architecture
</p>
</th>
<th>
<p>
LINUX (UNIX)
</p>
</th>
<th>
<p>
Windows
</p>
</th>
<th>
<p>
MacOS X
</p>
</th>
<th>
<p>
iOS
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
arm (aarch32)
</p>
</td>
<td>
<p>
AAPCS|ELF
</p>
</td>
<td>
<p>
AAPCS|PE
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
AAPCS|MACH-O
</p>
</td>
</tr>
<tr>
<td>
<p>
arm (aarch64)
</p>
</td>
<td>
<p>
AAPCS|ELF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
AAPCS|MACH-O
</p>
</td>
</tr>
<tr>
<td>
<p>
i386
</p>
</td>
<td>
<p>
SYSV|ELF
</p>
</td>
<td>
<p>
MS|PE
</p>
</td>
<td>
<p>
SYSV|MACH-O
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
loongarch64
</p>
</td>
<td>
<p>
SYSV|ELF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
mips
</p>
</td>
<td>
<p>
O32,N64|ELF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
ppc32
</p>
</td>
<td>
<p>
SYSV|ELF,XCOFF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
SYSV|MACH-O
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
ppc64
</p>
</td>
<td>
<p>
SYSV|ELF,XCOFF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
SYSV|MACH-O
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
riscv64
</p>
</td>
<td>
<p>
SYSV|ELF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
SYSV
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
s390x
</p>
</td>
<td>
<p>
SYSV|ELF
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
sparc
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
<tr>
<td>
<p>
x86_64
</p>
</td>
<td>
<p>
SYSV,X32|ELF
</p>
</td>
<td>
<p>
MS|PE
</p>
</td>
<td>
<p>
SYSV|MACH-O
</p>
</td>
<td>
<p>
-
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
If the architecture is not supported but the platform provides <a class="link" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>ucontext_t</em></span></a>,
<span class="bold"><strong>Boost.Context</strong></span> should be compiled with <code class="computeroutput"><span class="identifier">BOOST_USE_UCONTEXT</span></code> and b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">ucontext</span></code>.
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="performance.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="architectures/crosscompiling.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,48 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Cross compiling</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../architectures.html" title="Architectures">
<link rel="prev" href="../architectures.html" title="Architectures">
<link rel="next" href="../rationale.html" title="Rationale">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../architectures.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../architectures.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../rationale.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.architectures.crosscompiling"></a><a class="link" href="crosscompiling.html" title="Cross compiling">Cross compiling</a>
</h3></div></div></div>
<p>
Cross compiling the library requires to specify the build properties &lt;architecture&gt;,
&lt;address-model&gt;, &lt;binary-format&gt; and &lt;abi&gt; at b2 command
line.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../architectures.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../architectures.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../rationale.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,538 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Context switching with call/cc</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="ff/class__fiber_.html" title="Class fiber">
<link rel="next" href="cc/implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ff/class__fiber_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cc/implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.cc"></a><a name="cc"></a><a class="link" href="cc.html" title="Context switching with call/cc">Context switching with call/cc</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="cc/implementations__fcontext_t__ucontext_t_and_winfiber.html">Implementations:
fcontext_t, ucontext_t and WinFiber</a></span></dt>
<dt><span class="section"><a href="cc/class__continuation_.html">Class <code class="computeroutput"><span class="identifier">continuation</span></code></a></span></dt>
</dl></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>call/cc</em></span> is the reference implementation of C++ proposal
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0534r3.pdf" target="_top">P0534R3:
call/cc (call-with-current-continuation): A low-level API for stackful context
switching</a>.
</p></td></tr>
</table></div>
<p>
<span class="emphasis"><em>call/cc</em></span> (call with current continuation) is a universal
control operator (well-known from the programming language Scheme) that captures
the current continuation as a first-class object and pass it as an argument
to another continuation.
</p>
<p>
A continuation (abstract concept of functional programming languages) represents
the state of the control flow of a program at a given point in time. Continuations
can be suspended and resumed later in order to change the control flow of a
program.
</p>
<p>
Modern micro-processors are registers machines; the content of processor registers
represent a continuation of the executed program at a given point in time.
Operating systems simulate parallel execution of programs on a single processor
by switching between programs (context switch) by preserving and restoring
the continuation, e.g. the content of all registers.
</p>
<h4>
<a name="context.cc.h0"></a>
<span><a name="context.cc._link_linkend__cc___emphasis_callcc____emphasis___link_"></a></span><a class="link" href="cc.html#context.cc._link_linkend__cc___emphasis_callcc____emphasis___link_"><a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a></a>
</h4>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a> is the C++ equivalent
to Scheme's <span class="emphasis"><em>call/cc</em></span> operator. It captures the current
continuation (the rest of the computation; code after <a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>)
and triggers a context switch. The context switch is achieved by preserving
certain registers (including instruction and stack pointer), defined by the
calling convention of the ABI, of the current continuation and restoring those
registers of the resumed continuation. The control flow of the resumed continuation
continues. The current continuation is suspended and passed as argument to
the resumed continuation.
</p>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a> expects a <span class="emphasis"><em>context-function</em></span>
with signature <code class="computeroutput"><span class="char">'continuation(continuation &amp;&amp;
c)'</span></code>. The parameter <code class="computeroutput"><span class="identifier">c</span></code>
represents the current continuation from which this continuation was resumed
(e.g. that has called <a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>).
</p>
<p>
On return the <span class="emphasis"><em>context-function</em></span> of the current continuation
has to specify an <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
to which the execution control is transferred after termination of the current
continuation.
</p>
<p>
If an instance with valid state goes out of scope and the <span class="emphasis"><em>context-function</em></span>
has not yet returned, the stack is traversed in order to access the control
structure (address stored at the first stack frame) and continuation's stack
is deallocated via the <span class="emphasis"><em>StackAllocator</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<a class="link" href="stack/segmented.html#segmented"><span class="emphasis"><em>Segmented stacks</em></span></a> are
supported by <a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a> using
<a class="link" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>ucontext_t</em></span></a>.
</p></td></tr>
</table></div>
<h4>
<a name="context.cc.h1"></a>
<span><a name="context.cc._link_linkend__cc___emphasis_continuation__emphasis___link_"></a></span><a class="link" href="cc.html#context.cc._link_linkend__cc___emphasis_continuation__emphasis___link_"><a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a></a>
</h4>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> represents a continuation;
it contains the content of preserved registers and manages the associated stack
(allocation/deallocation). <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
is a one-shot continuation - it can be used only once, after calling <span class="emphasis"><em>continuation::resume()</em></span>
or <span class="emphasis"><em>continuation::resume_with()</em></span> it is invalidated.
</p>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> is only move-constructible
and move-assignable.
</p>
<p>
As a first-class object <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
can be applied to and returned from a function, assigned to a variable or stored
in a container.
</p>
<p>
A continuation is continued by calling <code class="computeroutput"><span class="identifier">resume</span><span class="special">()</span></code>/<code class="computeroutput"><span class="identifier">resume_with</span><span class="special">()</span></code>.
</p>
<h4>
<a name="context.cc.h2"></a>
<span><a name="context.cc.usage"></a></span><a class="link" href="cc.html#context.cc.usage">Usage</a>
</h4>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">source</span><span class="special">=</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">callcc</span><span class="special">(</span>
<span class="special">[&amp;</span><span class="identifier">a</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">){</span>
<span class="identifier">a</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">b</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">for</span><span class="special">(;;){</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">sink</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">int</span> <span class="identifier">next</span><span class="special">=</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">=</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">b</span><span class="special">=</span><span class="identifier">next</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">j</span><span class="special">=</span><span class="number">0</span><span class="special">;</span><span class="identifier">j</span><span class="special">&lt;</span><span class="number">10</span><span class="special">;++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">source</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span>
</pre>
<p>
This simple example demonstrates the basic usage of <span class="emphasis"><em>call/cc</em></span>
as a <span class="emphasis"><em>generator</em></span>. The continuation <code class="computeroutput"><span class="identifier">sink</span></code>
represents the <span class="emphasis"><em>main</em></span>-continuation (function <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code>).
<code class="computeroutput"><span class="identifier">sink</span></code> is captured (current-continuation)
by invoking <a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a> and passed
as parameter to the lambda.
</p>
<p>
Because the state is invalidated (one-shot continuation) by each call of <span class="emphasis"><em>continuation::resume()</em></span>,
the new state of the <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>,
returned by <span class="emphasis"><em>continuation::resume()</em></span>, needs to be assigned
to <code class="computeroutput"><span class="identifier">sink</span></code> after each call.
</p>
<p>
The lambda that calculates the Fibonacci numbers is executed inside the continuation
represented by <code class="computeroutput"><span class="identifier">source</span></code>. Calculated
Fibonacci numbers are transferred between the two continuations via variable
<code class="computeroutput"><span class="identifier">a</span></code> (lambda capture reference).
</p>
<p>
The locale variables <code class="computeroutput"><span class="identifier">b</span></code> and
<code class="computeroutput"> <span class="identifier">next</span></code> remain their values during
each context switch. This is possible due <code class="computeroutput"><span class="identifier">source</span></code>
has its own stack and the stack is exchanged by each context switch.
</p>
<h4>
<a name="context.cc.h3"></a>
<span><a name="context.cc.parameter_passing"></a></span><a class="link" href="cc.html#context.cc.parameter_passing">Parameter
passing</a>
</h4>
<p>
Data can be transferred between two continuations via global pointers, calling
wrappers (like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>) or lambda captures.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">c1</span><span class="special">=</span><span class="identifier">callcc</span><span class="special">([&amp;</span><span class="identifier">i</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">c2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside c1,i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">i</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">c2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">});</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">c1</span><span class="special">,</span><span class="identifier">i</span><span class="special">==</span><span class="number">1</span>
<span class="identifier">i</span><span class="special">==</span><span class="number">2</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">callcc</span><span class="special">(&lt;</span><span class="identifier">lambda</span><span class="special">&gt;)</span></code>
enters the lambda in continuation represented by <code class="computeroutput"><span class="identifier">c1</span></code>
with lambda capture reference <code class="computeroutput"><span class="identifier">i</span><span class="special">=</span><span class="number">1</span></code>. The expression
<code class="computeroutput"><span class="identifier">c2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>
resumes the continuation <code class="computeroutput"><span class="identifier">c2</span></code>.
On return of <code class="computeroutput"><span class="identifier">callcc</span><span class="special">(&lt;</span><span class="identifier">lambda</span><span class="special">&gt;)</span></code>,
the variable <code class="computeroutput"><span class="identifier">i</span></code> has the value
of <code class="computeroutput"><span class="identifier">i</span><span class="special">+</span><span class="number">1</span></code>.
</p>
<h4>
<a name="context.cc.h4"></a>
<span><a name="context.cc.exception_handling"></a></span><a class="link" href="cc.html#context.cc.exception_handling">Exception
handling</a>
</h4>
<p>
If the function executed inside a <span class="emphasis"><em>context-function</em></span> emits
an exception, the application is terminated by calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span><span class="special">()</span></code>. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>
can be used to transfer exceptions between different continuations.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Do not jump from inside a catch block and then re-throw the exception in
another continuation.
</p></td></tr>
</table></div>
<a name="cc_ontop"></a><h4>
<a name="context.cc.h5"></a>
<span><a name="context.cc.executing_function_on_top_of_a_continuation"></a></span><a class="link" href="cc.html#context.cc.executing_function_on_top_of_a_continuation">Executing
function on top of a continuation</a>
</h4>
<p>
Sometimes it is useful to execute a new function on top of a resumed continuation.
For this purpose <span class="emphasis"><em>continuation::resume_with()</em></span> has to be
used. The function passed as argument must accept a rvalue reference to <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> and return <code class="computeroutput"><span class="keyword">void</span></code>.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">data</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">c</span><span class="special">=</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">callcc</span><span class="special">([&amp;</span><span class="identifier">data</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">c</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered third time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">c</span><span class="special">);</span>
<span class="special">});</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">([&amp;</span><span class="identifier">data</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">c</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: entered: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">=-</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">c</span><span class="special">);</span>
<span class="special">});</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned third time"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">0</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">2</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">3</span>
<span class="identifier">f2</span><span class="special">:</span> <span class="identifier">entered</span><span class="special">:</span> <span class="number">4</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">third</span> <span class="identifier">time</span><span class="special">:</span> <span class="special">-</span><span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">third</span> <span class="identifier">time</span>
</pre>
<p>
The expression <code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">(...)</span></code>
executes a lambda on top of continuation <code class="computeroutput"><span class="identifier">c</span></code>,
e.g. an additional stack frame is allocated on top of the stack. This lambda
assigns <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
to <code class="computeroutput"><span class="identifier">data</span></code> and returns to the
second invocation of <code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>.
</p>
<p>
Another option is to execute a function on top of the continuation that throws
an exception.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">struct</span> <span class="identifier">my_exception</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span> <span class="special">{</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">c</span><span class="special">;</span>
<span class="identifier">my_exception</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">c_</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">what</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">{</span> <span class="identifier">what</span> <span class="special">},</span>
<span class="identifier">c</span><span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">c_</span><span class="special">)</span> <span class="special">}</span> <span class="special">{</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">c</span><span class="special">=</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">callcc</span><span class="special">([](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">c</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">for</span> <span class="special">(;;)</span> <span class="special">{</span>
<span class="keyword">try</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"entered"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">my_exception</span> <span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"my_exception: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ex</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ex</span><span class="special">.</span><span class="identifier">c</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">c</span><span class="special">);</span>
<span class="special">});</span>
<span class="identifier">c</span> <span class="special">=</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">(</span>
<span class="special">[](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">c</span><span class="special">){</span>
<span class="keyword">throw</span> <span class="identifier">my_exception</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">c</span><span class="special">),</span><span class="string">"abc"</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">c</span><span class="special">);</span>
<span class="special">});</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">entered</span>
<span class="identifier">my_exception</span><span class="special">:</span> <span class="identifier">abc</span>
</pre>
<p>
In this exception <code class="computeroutput"><span class="identifier">my_exception</span></code>
is throw from a function invoked on-top of continuation <code class="computeroutput"><span class="identifier">c</span></code>
and catched inside the <code class="computeroutput"><span class="keyword">for</span></code>-loop.
</p>
<h4>
<a name="context.cc.h6"></a>
<span><a name="context.cc.stack_unwinding"></a></span><a class="link" href="cc.html#context.cc.stack_unwinding">Stack
unwinding</a>
</h4>
<p>
On construction of <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
a stack is allocated. If the <span class="emphasis"><em>context-function</em></span> returns
the stack will be destructed. If the <span class="emphasis"><em>context-function</em></span>
has not yet returned and the destructor of an valid <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
instance (e.g. <span class="emphasis"><em>continuation::operator bool()</em></span> returns
<code class="computeroutput"><span class="keyword">true</span></code>) is called, the stack will
be destructed too.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Code executed by <span class="emphasis"><em>context-function</em></span> must not prevent the
propagation ofs the <span class="emphasis"><em>detail::forced_unwind</em></span> exception.
Absorbing that exception will cause stack unwinding to fail. Thus, any code
that catches all exceptions must re-throw any pending <span class="emphasis"><em>detail::forced_unwind</em></span>
exception.
</p></td></tr>
</table></div>
<a name="cc_prealloc"></a><h4>
<a name="context.cc.h7"></a>
<span><a name="context.cc.allocating_control_structures_on_top_of_stack"></a></span><a class="link" href="cc.html#context.cc.allocating_control_structures_on_top_of_stack">Allocating
control structures on top of stack</a>
</h4>
<p>
Allocating control structures on top of the stack requires to allocated the
<span class="emphasis"><em>stack_context</em></span> and create the control structure with placement
new before <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> is created.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The user is responsible for destructing the control structure at the top
of the stack.
</p></td></tr>
</table></div>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="comment">// stack-allocator used for (de-)allocating stack</span>
<span class="identifier">fixedsize_stack</span> <span class="identifier">salloc</span><span class="special">(</span><span class="number">4048</span><span class="special">);</span>
<span class="comment">// allocate stack space</span>
<span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">(</span><span class="identifier">salloc</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">());</span>
<span class="comment">// reserve space for control structure on top of the stack</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">=</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span><span class="special">)-</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">=</span><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">-</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="comment">// placement new creates control structure on reserved space</span>
<span class="identifier">my_control_structure</span> <span class="special">*</span> <span class="identifier">cs</span><span class="special">=</span><span class="keyword">new</span><span class="special">(</span><span class="identifier">sp</span><span class="special">)</span><span class="identifier">my_control_structure</span><span class="special">(</span><span class="identifier">sp</span><span class="special">,</span><span class="identifier">size</span><span class="special">,</span><span class="identifier">sctx</span><span class="special">,</span><span class="identifier">salloc</span><span class="special">);</span>
<span class="special">...</span>
<span class="comment">// destructing the control structure</span>
<span class="identifier">cs</span><span class="special">-&gt;~</span><span class="identifier">my_control_structure</span><span class="special">();</span>
<span class="special">...</span>
<span class="keyword">struct</span> <span class="identifier">my_control_structure</span> <span class="special">{</span>
<span class="comment">// captured continuation</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">c</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAllocator</span> <span class="special">&gt;</span>
<span class="identifier">my_control_structure</span><span class="special">(</span><span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span><span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">,</span><span class="identifier">StackAllocator</span> <span class="identifier">salloc</span><span class="special">)</span> <span class="special">:</span>
<span class="comment">// create captured continuation</span>
<span class="identifier">c</span><span class="special">{}</span> <span class="special">{</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">callcc</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg</span><span class="special">,</span><span class="identifier">preallocated</span><span class="special">(</span><span class="identifier">sp</span><span class="special">,</span><span class="identifier">size</span><span class="special">,</span><span class="identifier">sctx</span><span class="special">),</span><span class="identifier">salloc</span><span class="special">,</span><span class="identifier">entry_func</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<h4>
<a name="context.cc.h8"></a>
<span><a name="context.cc.inverting_the_control_flow"></a></span><a class="link" href="cc.html#context.cc.inverting_the_control_flow">Inverting
the control flow</a>
</h4>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="comment">/*
* grammar:
* P ---&gt; E '\0'
* E ---&gt; T {('+'|'-') T}
* T ---&gt; S {('*'|'/') S}
* S ---&gt; digit | '(' E ')'
*/</span>
<span class="keyword">class</span> <span class="identifier">Parser</span><span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">next</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">char</span><span class="special">)&gt;</span> <span class="identifier">cb</span><span class="special">;</span>
<span class="keyword">char</span> <span class="identifier">pull</span><span class="special">(){</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;::</span><span class="identifier">to_char_type</span><span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">scan</span><span class="special">(){</span>
<span class="keyword">do</span><span class="special">{</span>
<span class="identifier">next</span><span class="special">=</span><span class="identifier">pull</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">isspace</span><span class="special">(</span><span class="identifier">next</span><span class="special">));</span>
<span class="special">}</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">Parser</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is_</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">char</span><span class="special">)&gt;</span> <span class="identifier">cb_</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">next</span><span class="special">(),</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">is_</span><span class="special">),</span> <span class="identifier">cb</span><span class="special">(</span><span class="identifier">cb_</span><span class="special">)</span>
<span class="special">{}</span>
<span class="keyword">void</span> <span class="identifier">run</span><span class="special">()</span> <span class="special">{</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">E</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">void</span> <span class="identifier">E</span><span class="special">(){</span>
<span class="identifier">T</span><span class="special">();</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'+'</span><span class="special">||</span><span class="identifier">next</span><span class="special">==</span><span class="char">'-'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">T</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">T</span><span class="special">(){</span>
<span class="identifier">S</span><span class="special">();</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'*'</span><span class="special">||</span><span class="identifier">next</span><span class="special">==</span><span class="char">'/'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">S</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">S</span><span class="special">(){</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">isdigit</span><span class="special">(</span><span class="identifier">next</span><span class="special">)){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">else</span> <span class="keyword">if</span><span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'('</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">E</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">')'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="special">}</span><span class="keyword">else</span><span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"parsing failed"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">else</span><span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"parsing failed"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="string">"1+1"</span><span class="special">);</span>
<span class="comment">// execute parser in new continuation</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="identifier">source</span><span class="special">;</span>
<span class="comment">// user-code pulls parsed data from parser</span>
<span class="comment">// invert control flow</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">done</span><span class="special">=</span><span class="keyword">false</span><span class="special">;</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">callcc</span><span class="special">(</span>
<span class="special">[&amp;</span><span class="identifier">is</span><span class="special">,&amp;</span><span class="identifier">c</span><span class="special">,&amp;</span><span class="identifier">done</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">){</span>
<span class="comment">// create parser with callback function</span>
<span class="identifier">Parser</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span>
<span class="special">[&amp;</span><span class="identifier">sink</span><span class="special">,&amp;</span><span class="identifier">c</span><span class="special">](</span><span class="keyword">char</span> <span class="identifier">c_</span><span class="special">){</span>
<span class="comment">// resume main continuation</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c_</span><span class="special">;</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">sink</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">});</span>
<span class="comment">// start recursive parsing</span>
<span class="identifier">p</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="comment">// signal termination</span>
<span class="identifier">done</span><span class="special">=</span><span class="keyword">true</span><span class="special">;</span>
<span class="comment">// resume main continuation</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">while</span><span class="special">(!</span><span class="identifier">done</span><span class="special">){</span>
<span class="identifier">printf</span><span class="special">(</span><span class="string">"Parsed: %c\n"</span><span class="special">,</span><span class="identifier">c</span><span class="special">);</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">source</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="special">+</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
</pre>
<p>
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using <span class="emphasis"><em>call/cc</em></span> the control flow can be inverted,
e.g. the user-code pulls parsed symbols from the parser - instead to get pushed
from the parser (via callback).
</p>
<p>
The data (character) is transferred between the two continuations.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ff/class__fiber_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cc/implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,507 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class continuation</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../cc.html" title="Context switching with call/cc">
<link rel="prev" href="implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">
<link rel="next" href="../stack.html" title="Stack allocation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../cc.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../stack.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.cc.class__continuation_"></a><a class="link" href="class__continuation_.html" title="Class continuation">Class <code class="computeroutput"><span class="identifier">continuation</span></code></a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">continuation</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">continuation</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">continuation</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
<span class="special">~</span><span class="identifier">continuation</span><span class="special">();</span>
<span class="identifier">continuation</span><span class="special">(</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">continuation</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">continuation</span><span class="special">(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
<span class="identifier">continuation</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
<span class="identifier">continuation</span> <span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">continuation</span> <span class="identifier">resume_with</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">traitsT</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">continuation</span> <span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<h5>
<a name="cc_constructor_bridgehead"></a>
<span><a name="cc_constructor"></a></span>
<a class="link" href="class__continuation_.html#cc_constructor">Constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">continuation</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Creates a invalid continuation.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_destructor%20destructor_bridgehead"></a>
<span><a name="cc_destructor%20destructor"></a></span>
<a class="link" href="class__continuation_.html#cc_destructor%20destructor">Destructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="special">~</span><span class="identifier">continuation</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Destructs the associated stack if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is a valid continuation, e.g.
<span class="emphasis"><em>continuation::operator bool()</em></span> returns <code class="computeroutput"><span class="keyword">true</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_move%20constructor_bridgehead"></a>
<span><a name="cc_move%20constructor"></a></span>
<a class="link" href="class__continuation_.html#cc_move%20constructor">Move
constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">continuation</span><span class="special">(</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves underlying capture continuation to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_move%20assignment_bridgehead"></a>
<span><a name="cc_move%20assignment"></a></span>
<a class="link" href="class__continuation_.html#cc_move%20assignment">Move assignment
operator</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">continuation</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">continuation</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves the state of <code class="computeroutput"><span class="identifier">other</span></code>
to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
using move semantics.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_call_bridgehead"></a>
<span><a name="cc_operator_call"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_call">Member function
<code class="computeroutput">operator()</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">continuation</span> <span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">continuation</span> <span class="identifier">resume_with</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Captures current continuation and resumes <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>. The function <code class="computeroutput"><span class="identifier">resume_with</span></code>,
is used to execute function <code class="computeroutput"><span class="identifier">fn</span></code>
in the execution context of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> (e.g. the stack frame of <code class="computeroutput"><span class="identifier">fn</span></code> is allocated on stack of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>).
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The continuation representing the continuation that has been suspended.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
Function <code class="computeroutput"><span class="identifier">fn</span></code> needs to
return <code class="computeroutput"><span class="identifier">continuation</span></code>.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned continuation indicates if the suspended continuation has
terminated (return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_bool_bridgehead"></a>
<span><a name="cc_operator_bool"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_bool">Member function
<code class="computeroutput">operator bool</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
points to a captured continuation.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_not_bridgehead"></a>
<span><a name="cc_operator_not"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_not">Member function <code class="computeroutput">operator!</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
does not point to a captured continuation.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_equal_bridgehead"></a>
<span><a name="cc_operator_equal"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_equal">Member function
<code class="computeroutput">operator==</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
and <code class="computeroutput"><span class="identifier">other</span></code> represent
the same continuation, <code class="computeroutput"><span class="keyword">false</span></code>
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_notequal_bridgehead"></a>
<span><a name="cc_operator_notequal"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_notequal">Member
function <code class="computeroutput">operator!=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput">! (other == * this)</code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_less_bridgehead"></a>
<span><a name="cc_operator_less"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_less">Member function
<code class="computeroutput">operator&lt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="identifier">other</span></code>
is true and the implementation-defined total order of <code class="computeroutput"><span class="identifier">continuation</span></code> values places <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
before <code class="computeroutput"><span class="identifier">other</span></code>, false
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_greater_bridgehead"></a>
<span><a name="cc_operator_greater"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_greater">Member
function <code class="computeroutput">operator&gt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_lesseq_bridgehead"></a>
<span><a name="cc_operator_lesseq"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_lesseq">Member function
<code class="computeroutput">operator&lt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(</span><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc_operator_greatereq_bridgehead"></a>
<span><a name="cc_operator_greatereq"></a></span>
<a class="link" href="class__continuation_.html#cc_operator_greatereq">Member
function <code class="computeroutput">operator&gt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(*</span>
<span class="keyword">this</span> <span class="special">&lt;</span>
<span class="identifier">other</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="cc__bridgehead"></a>
<span><a name="cc_"></a></span>
<a class="link" href="class__continuation_.html#cc_">Non-member function <code class="computeroutput">operator&lt;&lt;()</code></a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">traitsT</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span><span class="identifier">continuation</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Writes the representation of <code class="computeroutput"><span class="identifier">other</span></code>
to stream <code class="computeroutput"><span class="identifier">os</span></code>.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">os</span></code>
</p></dd>
</dl>
</div>
<h5>
<a name="context.cc.class__continuation_.h0"></a>
<span><a name="context.cc.class__continuation_.call_with_current_continuation"></a></span><a class="link" href="class__continuation_.html#context.cc.class__continuation_.call_with_current_continuation">Call
with current continuation</a>
</h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">continuation</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">continuation</span> <span class="identifier">callcc</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">continuation</span> <span class="identifier">callcc</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span><span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">continuation</span> <span class="identifier">callcc</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span><span class="identifier">preallocated</span> <span class="identifier">palloc</span><span class="special">,</span><span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Captures current continuation and creates a new continuation prepared
to execute <code class="computeroutput"><span class="identifier">fn</span></code>. <code class="computeroutput"><span class="identifier">fixedsize_stack</span></code> is used as default
stack allocator (stack size == fixedsize_stack::traits::default_size()).
The function with argument type <code class="computeroutput"><span class="identifier">preallocated</span></code>,
is used to create a user defined data <a class="link" href="../cc.html#cc_prealloc">(for
instance additional control structures)</a> on top of the stack.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The continuation representing the contexcontinuation that has been
suspended.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned continuation indicates if the suspended continuation has
terminated (return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../cc.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../stack.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,108 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Implementations: fcontext_t, ucontext_t and WinFiber</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../cc.html" title="Context switching with call/cc">
<link rel="prev" href="../cc.html" title="Context switching with call/cc">
<link rel="next" href="class__continuation_.html" title="Class continuation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../cc.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../cc.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="class__continuation_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber"></a><a name="implementation0"></a><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">Implementations:
fcontext_t, ucontext_t and WinFiber</a>
</h3></div></div></div>
<h5>
<a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h0"></a>
<span><a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</a>
</h5>
<p>
The implementation uses <span class="emphasis"><em>fcontext_t</em></span> per default. fcontext_t
is based on assembler and not available for all platforms. It provides a
much better performance than <span class="emphasis"><em>ucontext_t</em></span> (the context
switch takes two magnitudes of order less CPU cycles; see section <a class="link" href="../performance.html#performance"><span class="emphasis"><em>performance</em></span></a>)
and <span class="emphasis"><em>WinFiber</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Because the TIB (thread information block on Windows) is not fully described
in the MSDN, it might be possible that not all required TIB-parts are swapped.
Using WinFiber implementation migh be an alternative.
</p></td></tr>
</table></div>
<h5>
<a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h1"></a>
<span><a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</a>
</h5>
<p>
As an alternative, <a href="https://en.wikipedia.org/wiki/Setcontext" target="_top"><span class="emphasis"><em>ucontext_t</em></span></a>
can be used by compiling with <code class="computeroutput"><span class="identifier">BOOST_USE_UCONTEXT</span></code>
and b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">ucontext</span></code>.
<span class="emphasis"><em>ucontext_t</em></span> might be available on a broader range of
POSIX-platforms but has some <a class="link" href="../rationale/other_apis_.html#ucontext"><span class="emphasis"><em>disadvantages</em></span></a>
(for instance deprecated since POSIX.1-2003, not C99 conform).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<a class="link" href="../cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a> supports <a class="link" href="../stack/segmented.html#segmented"><span class="emphasis"><em>Segmented stacks</em></span></a> only with
<span class="emphasis"><em>ucontext_t</em></span> as its implementation.
</p></td></tr>
</table></div>
<h5>
<a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h2"></a>
<span><a name="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</a>
</h5>
<p>
With <code class="computeroutput"><span class="identifier">BOOST_USE_WINFIB</span></code> and
b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">winfib</span></code>
Win32-Fibers are used as implementation for <a class="link" href="../cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The first call of <a class="link" href="../cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>
converts the thread into a Windows fiber by invoking <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code>. If desired, <code class="computeroutput"><span class="identifier">ConvertFiberToThread</span><span class="special">()</span></code> has to be called by the user explicitly
in order to release resources allocated by <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code> (e.g. after using boost.context).
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../cc.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../cc.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="class__continuation_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,879 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class execution_context (version 1)</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="ecv2.html" title="Class execution_context (version 2)">
<link rel="next" href="stack.html" title="Stack allocation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ecv2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.ecv1"></a><a name="ecv1"></a><a class="link" href="ecv1.html" title="Class execution_context (version 1)">Class execution_context
(version 1)</a>
</h2></div></div></div>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>execution_context</em></span> (v1) is deprecated (does not prevent
UB).
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>execution_context</em></span> (v1) is the reference implementation
of C++ proposal <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0099r0.pdf" target="_top">P099R0:
A low-level API for stackful context switching</a>.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>execution_context</em></span> (v1) resides in sub-namespace <code class="computeroutput"><span class="identifier">v1</span></code>.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Segmented stacks (<span class="emphasis"><em>segmented-stacks=on</em></span>), e.g. on demand
growing stacks, can be used with <span class="emphasis"><em>execution_context</em></span> (v1).
</p></td></tr>
</table></div>
<p>
Class <span class="emphasis"><em>execution_context</em></span> encapsulates context switching
and manages the associated context' stack (allocation/deallocation).
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> allocates the context stack (using its
<a class="link" href="stack.html#stack"><span class="emphasis"><em>StackAllocator</em></span></a> argument)
and creates a control structure on top of it. This structure is responsible
for managing context' stack. Instances of <span class="emphasis"><em>execution_context</em></span>,
associated with a specific context, share the ownership of the control structure.
If the last reference goes out of scope, the control structure is destroyed
and the stack gets deallocated via the <span class="emphasis"><em>StackAllocator</em></span>.
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> is copy-constructible, move-constructible,
copy-assignable and move-assignable.
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> maintains a static (thread-local) pointer,
accessed by <span class="emphasis"><em>execution_context::current()</em></span>, pointing to
the active context. On each context switch the pointer is updated. The usage
of this global pointer makes the context switch a little bit slower (due access
of thread local storage) but has some advantages. It allows to access the control
structure of the current active context from arbitrary code paths required
in order to support segmented stacks, which require to call certain maintenance
functions (like __splitstack_getcontext() etc.) before each context switch
(each context switch exchanges the stack).
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> expects a function/functor with signature
<code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="keyword">void</span><span class="special">*</span> <span class="identifier">vp</span><span class="special">)</span></code> (<code class="computeroutput"><span class="identifier">vp</span></code>
is the data passed at the first invocation of <a class="link" href="ecv1.html#ecv1_operator_call"> <code class="computeroutput">ecv1::operator()()</code></a>).
</p>
<h4>
<a name="context.ecv1.h0"></a>
<span><a name="context.ecv1.usage_of__emphasis_execution_context__emphasis_"></a></span><a class="link" href="ecv1.html#context.ecv1.usage_of__emphasis_execution_context__emphasis_">usage
of <span class="emphasis"><em>execution_context</em></span></a>
</h4>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">n</span><span class="special">=</span><span class="number">35</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span> <span class="identifier">sink</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">::</span><span class="identifier">current</span><span class="special">());</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span> <span class="identifier">source</span><span class="special">(</span>
<span class="special">[</span><span class="identifier">n</span><span class="special">,&amp;</span><span class="identifier">sink</span><span class="special">](</span><span class="keyword">void</span><span class="special">*)</span><span class="keyword">mutable</span><span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">b</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">--&gt;</span><span class="number">0</span><span class="special">){</span>
<span class="identifier">sink</span><span class="special">(&amp;</span><span class="identifier">a</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">next</span><span class="special">=</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">=</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">b</span><span class="special">=</span><span class="identifier">next</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">});</span>
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span><span class="identifier">i</span><span class="special">&lt;</span><span class="number">10</span><span class="special">;++</span><span class="identifier">i</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;*(</span><span class="keyword">int</span><span class="special">*)</span><span class="identifier">source</span><span class="special">()&lt;&lt;</span><span class="string">" "</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span>
</pre>
<p>
This simple example demonstrates the basic usage of <span class="emphasis"><em>execution_context</em></span>.
The context <code class="computeroutput"><span class="identifier">sink</span></code>, returned
by <span class="emphasis"><em>execution_context::current()</em></span>, represents the <span class="emphasis"><em>main</em></span>-context
(function <span class="emphasis"><em>main()</em></span> running) and is one of the captured parameters
in the lambda expression. The lambda that calculates the Fibonacci numbers
is executed inside the context represented by <code class="computeroutput"><span class="identifier">source</span></code>.
Calculated Fibonacci numbers are transferred between the two context' via expression
<span class="emphasis"><em>sink(&amp;a)</em></span> (and returned by <span class="emphasis"><em>source()</em></span>).
</p>
<p>
The locale variables <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">b</span></code> and <code class="computeroutput"> <span class="identifier">next</span></code>
remain their values during each context switch (<span class="emphasis"><em>yield(a)</em></span>).
This is possible because <code class="computeroutput"><span class="identifier">ctx</span></code>
owns a stack (exchanged by context switch).
</p>
<h4>
<a name="context.ecv1.h1"></a>
<span><a name="context.ecv1.inverting_the_control_flow"></a></span><a class="link" href="ecv1.html#context.ecv1.inverting_the_control_flow">inverting
the control flow</a>
</h4>
<pre class="programlisting"><span class="comment">/*
* grammar:
* P ---&gt; E '\0'
* E ---&gt; T {('+'|'-') T}
* T ---&gt; S {('*'|'/') S}
* S ---&gt; digit | '(' E ')'
*/</span>
<span class="keyword">class</span> <span class="identifier">Parser</span><span class="special">{</span>
<span class="comment">// implementation omitted; see examples directory</span>
<span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="string">"1+1"</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">done</span><span class="special">=</span><span class="keyword">false</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">except</span><span class="special">;</span>
<span class="comment">// create handle to main execution context</span>
<span class="keyword">auto</span> <span class="identifier">main_ctx</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">::</span><span class="identifier">current</span><span class="special">());</span>
<span class="comment">// execute parser in new execution context</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span> <span class="identifier">source</span><span class="special">(</span>
<span class="special">[&amp;</span><span class="identifier">sink</span><span class="special">,&amp;</span><span class="identifier">is</span><span class="special">,&amp;</span><span class="identifier">done</span><span class="special">,&amp;</span><span class="identifier">except</span><span class="special">](</span><span class="keyword">void</span><span class="special">*){</span>
<span class="comment">// create parser with callback function</span>
<span class="identifier">Parser</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span>
<span class="special">[&amp;</span><span class="identifier">sink</span><span class="special">](</span><span class="keyword">char</span> <span class="identifier">ch</span><span class="special">){</span>
<span class="comment">// resume main execution context</span>
<span class="identifier">sink</span><span class="special">(&amp;</span><span class="identifier">ch</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">try</span> <span class="special">{</span>
<span class="comment">// start recursive parsing</span>
<span class="identifier">p</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(...)</span> <span class="special">{</span>
<span class="comment">// store other exceptions in exception-pointer</span>
<span class="identifier">except</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">current_exception</span><span class="special">();</span>
<span class="special">}</span>
<span class="comment">// set termination flag</span>
<span class="identifier">done</span><span class="special">=</span><span class="keyword">true</span><span class="special">;</span>
<span class="comment">// resume main execution context</span>
<span class="identifier">sink</span><span class="special">();</span>
<span class="special">});</span>
<span class="comment">// user-code pulls parsed data from parser</span>
<span class="comment">// invert control flow</span>
<span class="keyword">void</span><span class="special">*</span> <span class="identifier">vp</span> <span class="special">=</span> <span class="identifier">source</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">except</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">rethrow_exception</span><span class="special">(</span><span class="identifier">except</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">while</span><span class="special">(</span> <span class="special">!</span> <span class="identifier">done</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">printf</span><span class="special">(</span><span class="string">"Parsed: %c\n"</span><span class="special">,*</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">vp</span><span class="special">));</span>
<span class="identifier">vp</span> <span class="special">=</span> <span class="identifier">source</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">except</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">rethrow_exception</span><span class="special">(</span><span class="identifier">except</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="special">+</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
</pre>
<p>
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using <span class="emphasis"><em>execution_context</em></span> the control flow
can be inverted, e.g. the user-code pulls parsed symbols from the parser -
instead to get pushed from the parser (via callback).
</p>
<p>
The data (character) is transferred between the two <span class="emphasis"><em>execution_context</em></span>.
</p>
<p>
If the code executed by <span class="emphasis"><em>execution_context</em></span> emits an exception,
the application is terminated. <span class="emphasis"><em>std::exception_ptr</em></span> can
be used to transfer exceptions between different execution contexts.
</p>
<h4>
<a name="context.ecv1.h2"></a>
<span><a name="context.ecv1.stack_unwinding"></a></span><a class="link" href="ecv1.html#context.ecv1.stack_unwinding">stack
unwinding</a>
</h4>
<p>
Sometimes it is necessary to unwind the stack of an unfinished context to destroy
local stack variables so they can release allocated resources (RAII pattern).
The user is responsible for this task.
</p>
<a name="ecv1_prealloc"></a><h4>
<a name="context.ecv1.h3"></a>
<span><a name="context.ecv1.allocating_control_structures_on_top_of_stack"></a></span><a class="link" href="ecv1.html#context.ecv1.allocating_control_structures_on_top_of_stack">allocating
control structures on top of stack</a>
</h4>
<p>
Allocating control structures on top of the stack requires to allocated the
<span class="emphasis"><em>stack_context</em></span> and create the control structure with placement
new before <span class="emphasis"><em>execution_context</em></span> is created.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The user is responsible for destructing the control structure at the top
of the stack.
</p></td></tr>
</table></div>
<pre class="programlisting"><span class="comment">// stack-allocator used for (de-)allocating stack</span>
<span class="identifier">fixedsize_stack</span> <span class="identifier">salloc</span><span class="special">(</span> <span class="number">4048</span><span class="special">);</span>
<span class="comment">// allocate stack space</span>
<span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">(</span> <span class="identifier">salloc</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">()</span> <span class="special">);</span>
<span class="comment">// reserve space for control structure on top of the stack</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span><span class="special">)</span> <span class="special">-</span> <span class="keyword">sizeof</span><span class="special">(</span> <span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span> <span class="special">-</span> <span class="keyword">sizeof</span><span class="special">(</span> <span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="comment">// placement new creates control structure on reserved space</span>
<span class="identifier">my_control_structure</span> <span class="special">*</span> <span class="identifier">cs</span> <span class="special">=</span> <span class="keyword">new</span> <span class="special">(</span> <span class="identifier">sp</span><span class="special">)</span> <span class="identifier">my_control_structure</span><span class="special">(</span> <span class="identifier">sp</span><span class="special">,</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">sctx</span><span class="special">,</span> <span class="identifier">salloc</span><span class="special">);</span>
<span class="special">...</span>
<span class="comment">// destructing the control structure</span>
<span class="identifier">cs</span><span class="special">-&gt;~</span><span class="identifier">my_control_structure</span><span class="special">();</span>
<span class="special">...</span>
<span class="keyword">struct</span> <span class="identifier">my_control_structure</span> <span class="special">{</span>
<span class="comment">// execution context</span>
<span class="identifier">execution_context</span> <span class="identifier">ectx</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAllocator</span> <span class="special">&gt;</span>
<span class="identifier">my_control_structure</span><span class="special">(</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">,</span> <span class="identifier">StackAllocator</span> <span class="identifier">salloc</span><span class="special">)</span> <span class="special">:</span>
<span class="comment">// create execution context</span>
<span class="identifier">ectx</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg</span><span class="special">,</span> <span class="identifier">preallocated</span><span class="special">(</span> <span class="identifier">sp</span><span class="special">,</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">sctx</span><span class="special">),</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">entry_func</span><span class="special">)</span> <span class="special">{</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<h4>
<a name="context.ecv1.h4"></a>
<span><a name="context.ecv1.exception_handling"></a></span><a class="link" href="ecv1.html#context.ecv1.exception_handling">exception
handling</a>
</h4>
<p>
If the function executed inside a <span class="emphasis"><em>execution_context</em></span> emits
an exception, the application is terminated by calling <span class="emphasis"><em>std::terminate()</em></span>.
<span class="emphasis"><em>std::exception_ptr</em></span> can be used to transfer exceptions
between different execution contexts.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Do not jump from inside a catch block and then re-throw the exception in
another execution context.
</p></td></tr>
</table></div>
<h4>
<a name="context.ecv1.h5"></a>
<span><a name="context.ecv1.parameter_passing"></a></span><a class="link" href="ecv1.html#context.ecv1.parameter_passing">parameter
passing</a>
</h4>
<p>
The void pointer argument passed to <span class="emphasis"><em>execution_context::operator()</em></span>,
in one context, is passed as the last argument of the <span class="emphasis"><em>context-function</em></span>
if the context is started for the first time. In all following invocations
of <span class="emphasis"><em>execution_context::operator()</em></span> the void pointer passed
to <span class="emphasis"><em>execution_context::operator()</em></span>, in one context, is returned
by <span class="emphasis"><em>execution_context::operator()</em></span> in the other context.
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">X</span> <span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">excptr_</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span> <span class="identifier">caller_</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span> <span class="identifier">callee_</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">X</span><span class="special">()</span> <span class="special">:</span>
<span class="identifier">excptr_</span><span class="special">(),</span>
<span class="identifier">caller_</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">v1</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">::</span><span class="identifier">current</span><span class="special">()</span> <span class="special">),</span>
<span class="identifier">callee_</span><span class="special">(</span> <span class="special">[=]</span> <span class="special">(</span><span class="keyword">void</span> <span class="special">*</span> <span class="identifier">vp</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">try</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">vp</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">caller_</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_cast</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">{</span>
<span class="identifier">excptr_</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">current_exception</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">})</span>
<span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">ret</span> <span class="special">=</span> <span class="identifier">callee_</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">i</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">excptr_</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">rethrow_exception</span><span class="special">(</span><span class="identifier">excptr_</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="special">*</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">*</span> <span class="special">&gt;(</span> <span class="identifier">ret</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">(</span> <span class="number">7</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">7</span>
</pre>
<h4>
<a name="context.ecv1.h6"></a>
<span><a name="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_"></a></span><a class="link" href="ecv1.html#context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
<code class="computeroutput"><span class="identifier">execution_context</span></code></a>
</h4>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">execution_context</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">static</span> <span class="identifier">execution_context</span> <span class="identifier">current</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">preallocated</span> <span class="identifier">palloc</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">execution_context</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">execution_context</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">execution_context</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">execution_context</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">vp</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">exec_ontop_arg_t</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">vp</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
<span class="special">};</span>
</pre>
<p>
</p>
<h5>
<a name="ecv1_current_bridgehead"></a>
<span><a name="ecv1_current"></a></span>
<a class="link" href="ecv1.html#ecv1_current">Static member function <code class="computeroutput">current</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">static</span> <span class="identifier">execution_context</span> <span class="identifier">current</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
Returns an instance of excution_context pointing to the active execution
context.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_constructor_bridgehead"></a>
<span><a name="ecv1_constructor"></a></span>
<a class="link" href="ecv1.html#ecv1_constructor">Constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">preallocated</span> <span class="identifier">palloc</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Creates a new execution context and prepares the context to execute
<code class="computeroutput"><span class="identifier">fn</span></code>. <code class="computeroutput"><span class="identifier">fixedsize_stack</span></code>
is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
The constructor with argument type <code class="computeroutput"><span class="identifier">preallocated</span></code>,
is used to create a user defined data <a class="link" href="ecv1.html#ecv1_prealloc">(for
instance additional control structures)</a> on top of the stack.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_copy%20constructor_bridgehead"></a>
<span><a name="ecv1_copy%20constructor"></a></span>
<a class="link" href="ecv1.html#ecv1_copy%20constructor">Copy
constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Copies <code class="computeroutput"><span class="identifier">other</span></code>, e.g. underlying
control structure is shared with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_move%20constructor_bridgehead"></a>
<span><a name="ecv1_move%20constructor"></a></span>
<a class="link" href="ecv1.html#ecv1_move%20constructor">Move
constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">execution_context</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves underlying control structure to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_copy%20assignment_bridgehead"></a>
<span><a name="ecv1_copy%20assignment"></a></span>
<a class="link" href="ecv1.html#ecv1_copy%20assignment">Copy
assignment operator</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">execution_context</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Copies the state of <code class="computeroutput"><span class="identifier">other</span></code>
to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
control structure is shared.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_move%20assignment_bridgehead"></a>
<span><a name="ecv1_move%20assignment"></a></span>
<a class="link" href="ecv1.html#ecv1_move%20assignment">Move
assignment operator</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">execution_context</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">execution_context</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves the control structure of <code class="computeroutput"><span class="identifier">other</span></code>
to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
using move semantics.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_bool_bridgehead"></a>
<span><a name="ecv1_operator_bool"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_bool">Member function
<code class="computeroutput">operator bool</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> points to a control structure.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_not_bridgehead"></a>
<span><a name="ecv1_operator_not"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_not">Member function
<code class="computeroutput">operator!</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> does not point to a control structure.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_call_bridgehead"></a>
<span><a name="ecv1_operator_call"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_call">Member function
<code class="computeroutput">operator()</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">vp</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Stores internally the current context data (stack pointer, instruction
pointer, and CPU registers) of the current active context and restores
the context data from <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>, which implies jumping to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>'s
context. The void pointer argument, <code class="computeroutput"><span class="identifier">vp</span></code>,
is passed to the current context to be returned by the most recent call
to <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> in the same thread. <code class="computeroutput"><span class="identifier">fn</span></code>
is executed with arguments <code class="computeroutput"><span class="identifier">args</span></code>
on top of the stack of <code class="computeroutput"><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The behaviour is undefined if <code class="computeroutput"><span class="keyword">operator</span><span class="special">()()</span></code> is called while <span class="emphasis"><em>execution_context::current()</em></span>
returns <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
(e.g. resuming an already running context). If the top-level context
function returns, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exit</span><span class="special">()</span></code> is called.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The void pointer argument passed to the most recent call to <span class="emphasis"><em>execution_context::operator()</em></span>,
if any.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_call_ontop_bridgehead"></a>
<span><a name="ecv1_operator_call_ontop"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_call_ontop">Member
function <code class="computeroutput">operator(exec_ontop_arg_t)</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">exec_ontop_arg_t</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">vp</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Same as <span class="emphasis"><em>execution_context::operator()</em></span>. Additionally,
function <code class="computeroutput"><span class="identifier">fn</span></code> is executed
with arguments <code class="computeroutput"><span class="identifier">vp</span></code> in
the context of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
(e.g. the stack frame of <code class="computeroutput"><span class="identifier">fn</span></code>
is allocated on stack of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>).
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The void pointer argument passed to the most recent call to <span class="emphasis"><em>execution_context::operator()</em></span>,
if any.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_equal_bridgehead"></a>
<span><a name="ecv1_operator_equal"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_equal">Member
function <code class="computeroutput">operator==</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> and <code class="computeroutput"><span class="identifier">other</span></code>
represent the same execution context, <code class="computeroutput"><span class="keyword">false</span></code>
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_notequal_bridgehead"></a>
<span><a name="ecv1_operator_notequal"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_notequal">Member
function <code class="computeroutput">operator!=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput">! (other == * this)</code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_less_bridgehead"></a>
<span><a name="ecv1_operator_less"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_less">Member function
<code class="computeroutput">operator&lt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="identifier">other</span></code> is true and the implementation-defined
total order of <code class="computeroutput"><span class="identifier">execution_context</span></code>
values places <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
before <code class="computeroutput"><span class="identifier">other</span></code>, false otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_greater_bridgehead"></a>
<span><a name="ecv1_operator_greater"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_greater">Member
function <code class="computeroutput">operator&gt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_lesseq_bridgehead"></a>
<span><a name="ecv1_operator_lesseq"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_lesseq">Member
function <code class="computeroutput">operator&lt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(</span><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1_operator_greatereq_bridgehead"></a>
<span><a name="ecv1_operator_greatereq"></a></span>
<a class="link" href="ecv1.html#ecv1_operator_greatereq">Member
function <code class="computeroutput">operator&gt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(*</span>
<span class="keyword">this</span> <span class="special">&lt;</span>
<span class="identifier">other</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv1__bridgehead"></a>
<span><a name="ecv1_"></a></span>
<a class="link" href="ecv1.html#ecv1_">Non-member function <code class="computeroutput">operator&lt;&lt;()</code></a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Efects:</span></dt>
<dd><p>
Writes the representation of <code class="computeroutput"><span class="identifier">other</span></code>
to stream <code class="computeroutput"><span class="identifier">os</span></code>.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">os</span></code>
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="ecv2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,808 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class execution_context (version 2)</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="cc/class__continuation_.html" title="Class continuation">
<link rel="next" href="ecv1.html" title="Class execution_context (version 1)">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cc/class__continuation_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ecv1.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.ecv2"></a><a name="ecv2"></a><a class="link" href="ecv2.html" title="Class execution_context (version 2)">Class execution_context
(version 2)</a>
</h2></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>execution_context</em></span> (v2) is the reference implementation
of C++ proposal <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0099r1.pdf" target="_top">P099R1:
A low-level API for stackful context switching</a>.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>execution_context</em></span> (v2) resides in the inlined sub-namespace
<code class="computeroutput"><span class="identifier">v2</span></code>.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Segmented stacks (<span class="emphasis"><em>segmented-stacks=on</em></span>), e.g. on demand
growing stacks, are not supported by <span class="emphasis"><em>execution_context</em></span>
(v2).
</p></td></tr>
</table></div>
<p>
Class <span class="emphasis"><em>execution_context</em></span> encapsulates context switching
and manages the associated context' stack (allocation/deallocation).
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> allocates the context stack (using its
<a class="link" href="stack.html#stack"><span class="emphasis"><em>StackAllocator</em></span></a> argument)
and creates a control structure on top of it. This structure is responsible
for managing context' stack. The address of the control structure is stored
in the first frame of context' stack (e.g. it can not directly accessed from
within <span class="emphasis"><em>execution_context</em></span>). In contrast to <a class="link" href="ecv1.html#ecv1"><span class="emphasis"><em>execution_context</em></span>
(v1)</a> the ownership of the control structure is not shared (no member
variable to control structure in <span class="emphasis"><em>execution_context</em></span>).
<span class="emphasis"><em>execution_context</em></span> keeps internally a state that is moved
by a call of <span class="emphasis"><em>execution_context::operator()</em></span> (<code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> will be
invalidated), e.g. after a calling <span class="emphasis"><em>execution_context::operator()</em></span>,
<code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
can not be used for an additional context switch.
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> is only move-constructible and move-assignable.
</p>
<p>
The moved state is assigned to a new instance of <span class="emphasis"><em>execution_context</em></span>.
This object becomes the first argument of the context-function, if the context
was resumed the first time, or the first element in a tuple returned by <span class="emphasis"><em>execution_context::operator()</em></span>
that has been called in the resumed context. In contrast to <a class="link" href="ecv1.html#ecv1"><span class="emphasis"><em>execution_context</em></span>
(v1)</a>, the context switch is faster because no global pointer etc. is
involved.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Segmented stacks are not supported by <span class="emphasis"><em>execution_context</em></span>
(v2).
</p></td></tr>
</table></div>
<p>
On return the context-function of the current context has to specify an <span class="emphasis"><em>execution_context</em></span>
to which the execution control is transferred after termination of the current
context.
</p>
<p>
If an instance with valid state goes out of scope and the context-function
has not yet returned, the stack is traversed in order to access the control
structure (address stored at the first stack frame) and context' stack is deallocated
via the <span class="emphasis"><em>StackAllocator</em></span>. The stack walking makes the destruction
of <span class="emphasis"><em>execution_context</em></span> slow and should be prevented if possible.
</p>
<p>
<span class="emphasis"><em>execution_context</em></span> expects a <span class="emphasis"><em>context-function</em></span>
with signature <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">(</span><span class="identifier">execution_context</span>
<span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">)</span></code>. The
parameter <code class="computeroutput"><span class="identifier">ctx</span></code> represents the
context from which this context was resumed (e.g. that has called <span class="emphasis"><em>execution_context::operator()</em></span>
on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>)
and <code class="computeroutput"><span class="identifier">args</span></code> are the data passed
to <span class="emphasis"><em>execution_context::operator()</em></span>. The return value represents
the execution_context that has to be resumed, after termiantion of this context.
</p>
<p>
Benefits of <a class="link" href="ecv2.html#ecv2"><span class="emphasis"><em>execution_context</em></span> (v2)</a>
over <a class="link" href="ecv1.html#ecv1"><span class="emphasis"><em>execution_context</em></span> (v1)</a>
are: faster context switch, type-safety of passed/returned arguments.
</p>
<h4>
<a name="context.ecv2.h0"></a>
<span><a name="context.ecv2.usage_of__emphasis_execution_context__emphasis_"></a></span><a class="link" href="ecv2.html#context.ecv2.usage_of__emphasis_execution_context__emphasis_">usage
of <span class="emphasis"><em>execution_context</em></span></a>
</h4>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">n</span><span class="special">=</span><span class="number">35</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">source</span><span class="special">(</span>
<span class="special">[</span><span class="identifier">n</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">,</span><span class="keyword">int</span><span class="special">)</span> <span class="keyword">mutable</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">b</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">n</span><span class="special">--&gt;</span><span class="number">0</span><span class="special">){</span>
<span class="keyword">auto</span> <span class="identifier">result</span><span class="special">=</span><span class="identifier">sink</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">));</span>
<span class="keyword">auto</span> <span class="identifier">next</span><span class="special">=</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">=</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">b</span><span class="special">=</span><span class="identifier">next</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span><span class="identifier">i</span><span class="special">&lt;</span><span class="number">10</span><span class="special">;++</span><span class="identifier">i</span><span class="special">){</span>
<span class="keyword">auto</span> <span class="identifier">result</span><span class="special">=</span><span class="identifier">source</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">));</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">)&lt;&lt;</span><span class="string">" "</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span>
</pre>
<p>
This simple example demonstrates the basic usage of <span class="emphasis"><em>execution_context</em></span>
as a generator. The context <code class="computeroutput"><span class="identifier">sink</span></code>
represents the <span class="emphasis"><em>main</em></span>-context (function <span class="emphasis"><em>main()</em></span>
running). <code class="computeroutput"><span class="identifier">sink</span></code> is generated
by the framework (first element of lambda's parameter list). Because the state
is invalidated (== changed) by each call of <span class="emphasis"><em>execution_context::operator()</em></span>,
the new state of the <span class="emphasis"><em>execution_context</em></span>, returned by <span class="emphasis"><em>execution_context::operator()</em></span>,
needs to be assigned to <code class="computeroutput"><span class="identifier">sink</span></code>
after each call.
</p>
<p>
The lambda that calculates the Fibonacci numbers is executed inside the context
represented by <code class="computeroutput"><span class="identifier">source</span></code>. Calculated
Fibonacci numbers are transferred between the two context' via expression
<span class="emphasis"><em>sink(a)</em></span> (and returned by <span class="emphasis"><em>source()</em></span>).
Note that this example represents a <span class="emphasis"><em>generator</em></span> thus the
value transferred into the lambda via <span class="emphasis"><em>source()</em></span> is not
used. Using <span class="emphasis"><em>boost::optional&lt;&gt;</em></span> as transferred type,
might also appropriate to express this fact.
</p>
<p>
The locale variables <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">b</span></code> and <code class="computeroutput"> <span class="identifier">next</span></code>
remain their values during each context switch (<span class="emphasis"><em>yield(a)</em></span>).
This is possible due <code class="computeroutput"><span class="identifier">source</span></code>
has its own stack and the stack is exchanged by each context switch.
</p>
<h4>
<a name="context.ecv2.h1"></a>
<span><a name="context.ecv2.parameter_passing"></a></span><a class="link" href="ecv2.html#context.ecv2.parameter_passing">parameter
passing</a>
</h4>
<p>
With <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code> no
data will be transferred, only the context switch is executed.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">ctx1</span><span class="special">([](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">ctx2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside ctx1\n"</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">ctx2</span><span class="special">();</span>
<span class="special">});</span>
<span class="identifier">ctx1</span><span class="special">();</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">ctx1</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">ctx1</span><span class="special">()</span></code>
resumes <code class="computeroutput"><span class="identifier">ctx1</span></code>, e.g. the lambda
passed at the constructor of <code class="computeroutput"><span class="identifier">ctx1</span></code>
is entered. Argument <code class="computeroutput"><span class="identifier">ctx2</span></code> represents
the context that has been suspended with the invocation of <code class="computeroutput"><span class="identifier">ctx1</span><span class="special">()</span></code>. When the lambda returns <code class="computeroutput"><span class="identifier">ctx2</span></code>,
context <code class="computeroutput"><span class="identifier">ctx1</span></code> will be terminated
while the context represented by <code class="computeroutput"><span class="identifier">ctx2</span></code>
is resumed, hence the control of execution returns from <code class="computeroutput"><span class="identifier">ctx1</span><span class="special">()</span></code>.
</p>
<p>
The arguments passed to <span class="emphasis"><em>execution_context::operator()</em></span>,
in one context, is passed as the last arguments of the <span class="emphasis"><em>context-function</em></span>
if the context is started for the first time. In all following invocations
of <span class="emphasis"><em>execution_context::operator()</em></span> the arguments passed
to <span class="emphasis"><em>execution_context::operator()</em></span>, in one context, is returned
by <span class="emphasis"><em>execution_context::operator()</em></span> in the other context.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx1</span><span class="special">([](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">ctx2</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">j</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside ctx1,j==%d\n"</span><span class="special">,</span><span class="identifier">j</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx2</span><span class="special">,</span><span class="identifier">j</span><span class="special">)=</span><span class="identifier">ctx2</span><span class="special">(</span><span class="identifier">j</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ctx2</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx1</span><span class="special">,</span><span class="identifier">i</span><span class="special">)=</span><span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">ctx1</span><span class="special">,</span><span class="identifier">j</span><span class="special">==</span><span class="number">1</span>
<span class="identifier">i</span><span class="special">==</span><span class="number">2</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span></code> enters
the lambda in context <code class="computeroutput"><span class="identifier">ctx1</span></code>
with argument <code class="computeroutput"><span class="identifier">j</span><span class="special">=</span><span class="number">1</span></code>. The expression <code class="computeroutput"><span class="identifier">ctx2</span><span class="special">(</span><span class="identifier">j</span><span class="special">+</span><span class="number">1</span><span class="special">)</span></code> resumes the
context represented by <code class="computeroutput"><span class="identifier">ctx2</span></code>
and transfers back an integer of <code class="computeroutput"><span class="identifier">j</span><span class="special">+</span><span class="number">1</span></code>. On return
of <code class="computeroutput"><span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span></code>, the variable
<code class="computeroutput"><span class="identifier">i</span></code> contains the value of <code class="computeroutput"><span class="identifier">j</span><span class="special">+</span><span class="number">1</span></code>.
</p>
<p>
If more than one argument has to be transferred, the signature of the context-function
is simply extended.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx1</span><span class="special">([](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">ctx2</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">j</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside ctx1,i==%d,j==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">,</span><span class="identifier">j</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx2</span><span class="special">,</span><span class="identifier">i</span><span class="special">,</span><span class="identifier">j</span><span class="special">)=</span><span class="identifier">ctx2</span><span class="special">(</span><span class="identifier">i</span><span class="special">+</span><span class="identifier">j</span><span class="special">,</span><span class="identifier">i</span><span class="special">-</span><span class="identifier">j</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ctx2</span><span class="special">);</span>
<span class="special">});</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">2</span><span class="special">,</span><span class="identifier">j</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx1</span><span class="special">,</span><span class="identifier">i</span><span class="special">,</span><span class="identifier">j</span><span class="special">)=</span><span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span><span class="identifier">j</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i==%d,j==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">,</span><span class="identifier">j</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">ctx1</span><span class="special">,</span><span class="identifier">i</span><span class="special">==</span><span class="number">2</span><span class="special">,</span><span class="identifier">j</span><span class="special">==</span><span class="number">1</span>
<span class="identifier">i</span><span class="special">==</span><span class="number">3</span><span class="special">,</span><span class="identifier">j</span><span class="special">==</span><span class="number">1</span>
</pre>
<p>
For use-cases, that require to transfer data of different type in each direction,
<span class="emphasis"><em>boost::variant&lt;&gt;</em></span> could be used.
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">X</span><span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">excptr_</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;&gt;</span> <span class="identifier">ctx_</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">X</span><span class="special">():</span>
<span class="identifier">excptr_</span><span class="special">(),</span>
<span class="identifier">ctx_</span><span class="special">([=](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">ctx</span><span class="special">,</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">){</span>
<span class="keyword">try</span> <span class="special">{</span>
<span class="keyword">for</span> <span class="special">(;;)</span> <span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">data</span><span class="special">);</span>
<span class="identifier">data</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;(</span><span class="identifier">i</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">result</span><span class="special">=</span><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">);</span>
<span class="identifier">ctx</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">));</span>
<span class="identifier">data</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_cast</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">{</span>
<span class="identifier">excptr_</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">current_exception</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
<span class="special">})</span>
<span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">){</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">=</span><span class="identifier">i</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result</span><span class="special">=</span><span class="identifier">ctx_</span><span class="special">(</span><span class="identifier">data</span><span class="special">);</span>
<span class="identifier">ctx_</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">));</span>
<span class="identifier">data</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">excptr_</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">rethrow_exception</span><span class="special">(</span><span class="identifier">excptr_</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;(</span><span class="identifier">data</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span><span class="special">(</span><span class="number">7</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">7</span>
</pre>
<p>
In the case of unidirectional transfer of data, <span class="emphasis"><em>boost::optional&lt;&gt;</em></span>
or a pointer are appropriate.
</p>
<h4>
<a name="context.ecv2.h2"></a>
<span><a name="context.ecv2.exception_handling"></a></span><a class="link" href="ecv2.html#context.ecv2.exception_handling">exception
handling</a>
</h4>
<p>
If the function executed inside a <span class="emphasis"><em>execution_context</em></span> emits
an exception, the application is terminated by calling <span class="emphasis"><em>std::terminate()</em></span>.
<span class="emphasis"><em>std::exception_ptr</em></span> can be used to transfer exceptions
between different execution contexts.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Do not jump from inside a catch block and then re-throw the exception in
another execution context.
</p></td></tr>
</table></div>
<a name="ecv2_ontop"></a><h4>
<a name="context.ecv2.h3"></a>
<span><a name="context.ecv2.executing_function_on_top_of_a_context"></a></span><a class="link" href="ecv2.html#context.ecv2.executing_function_on_top_of_a_context">Executing
function on top of a context</a>
</h4>
<p>
Sometimes it is useful to execute a new function on top of a resumed context.
For this purpose <span class="emphasis"><em>execution_context::operator()</em></span> with first
argument <code class="computeroutput"><span class="identifier">exec_ontop_arg</span></code> has
to be used. The function passed as argument must return a tuple of execution_context
and arguments.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">f1</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">ctx</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)=</span><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)=</span><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered third time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: entered: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">data</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">f1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)=</span><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)=</span><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)=</span><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">exec_ontop_arg</span><span class="special">,</span><span class="identifier">f2</span><span class="special">,</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">2</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">3</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">4</span>
<span class="identifier">f2</span><span class="special">:</span> <span class="identifier">entered</span><span class="special">:</span> <span class="number">5</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">third</span> <span class="identifier">time</span><span class="special">:</span> <span class="special">-</span><span class="number">1</span>
</pre>
<p>
The expression <code class="computeroutput"><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">exec_ontop_arg</span><span class="special">,</span><span class="identifier">f2</span><span class="special">,</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">)</span></code> executes <code class="computeroutput"><span class="identifier">f2</span><span class="special">()</span></code> on top of context <code class="computeroutput"><span class="identifier">ctx</span></code>,
e.g. an additional stack frame is allocated on top of the context stack (in
front of <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>).
<code class="computeroutput"><span class="identifier">f2</span><span class="special">()</span></code>
returns argument <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
that will returned by the second invocation of <code class="computeroutput"><span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">)</span></code> in <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>.
</p>
<p>
</p>
<h5>
<a name="ecv2_destructor%20destructor_bridgehead"></a>
<span><a name="ecv2_destructor%20destructor"></a></span>
<a class="link" href="ecv2.html#ecv2_destructor%20destructor">Destructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="special">~</span><span class="identifier">execution_context</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Destructs the associated stack if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is a valid context, e.g. <span class="emphasis"><em>execution_context::operator
bool()</em></span> returns <code class="computeroutput"><span class="keyword">true</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_move%20constructor_bridgehead"></a>
<span><a name="ecv2_move%20constructor"></a></span>
<a class="link" href="ecv2.html#ecv2_move%20constructor">Move
constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">execution_context</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves underlying capture record to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_move%20assignment_bridgehead"></a>
<span><a name="ecv2_move%20assignment"></a></span>
<a class="link" href="ecv2.html#ecv2_move%20assignment">Move
assignment operator</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">execution_context</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">execution_context</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves the state of <code class="computeroutput"><span class="identifier">other</span></code>
to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
using move semantics.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_bool_bridgehead"></a>
<span><a name="ecv2_operator_bool"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_bool">Member function
<code class="computeroutput">operator bool</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> points to a capture record.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_not_bridgehead"></a>
<span><a name="ecv2_operator_not"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_not">Member function
<code class="computeroutput">operator!</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> does not point to a capture record.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_call_bridgehead"></a>
<span><a name="ecv2_operator_call"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_call">Member function
<code class="computeroutput">operator()</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span> <span class="identifier">execution_context</span><span class="special">&lt;</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="special">&gt;,</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span> <span class="comment">// member of generic execution_context template</span>
<span class="identifier">execution_context</span><span class="special">&lt;</span> <span class="keyword">void</span> <span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()();</span> <span class="comment">// member of execution_context&lt; void &gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Stores internally the current context data (stack pointer, instruction
pointer, and CPU registers) of the current active context and restores
the context data from <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>, which implies jumping to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>'s
context. The arguments, <code class="computeroutput"><span class="special">...</span> <span class="identifier">args</span></code>, are passed to the current context
to be returned by the most recent call to <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> in the same thread.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The tuple of execution_context and returned arguments passed to the most
recent call to <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>, if any and a execution_context representing
the context that has been suspended.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned execution_context indicates if the suspended context has
terminated (return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
If the returned execution_context has terminated no data are transferred
in the returned tuple.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_call_ontop_bridgehead"></a>
<span><a name="ecv2_operator_call_ontop"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_call_ontop">Member
function <code class="computeroutput">operator()</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span> <span class="identifier">execution_context</span><span class="special">&lt;</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="special">&gt;,</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">exec_ontop_arg_t</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span> <span class="comment">// member of generic execution_context</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">&lt;</span> <span class="keyword">void</span> <span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">exec_ontop_arg_t</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span> <span class="comment">// member of execution_context&lt; void &gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Same as <span class="emphasis"><em>execution_context::operator()</em></span>. Additionally,
function <code class="computeroutput"><span class="identifier">fn</span></code> is executed
in the context of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
(e.g. the stack frame of <code class="computeroutput"><span class="identifier">fn</span></code>
is allocated on stack of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>).
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The tuple of execution_context and returned arguments passed to the most
recent call to <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>, if any and a execution_context representing
the context that has been suspended .
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The tuple of execution_context and returned arguments from <code class="computeroutput"><span class="identifier">fn</span></code> are passed as arguments to the context-function
of resumed context (if the context is entered the first time) or those
arguments are returned from <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> within the resumed context.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
Function <code class="computeroutput"><span class="identifier">fn</span></code> needs to
return a tuple of arguments (<a class="link" href="ecv2.html#ecv2_ontop">see description</a>).
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The context calling this function must not be destroyed before the arguments,
that will be returned from <code class="computeroutput"><span class="identifier">fn</span></code>,
are preserved at least in the stack frame of the resumed context.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned execution_context indicates if the suspended context has
terminated (return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
If the returned execution_context has terminated no data are transferred
in the returned tuple.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_equal_bridgehead"></a>
<span><a name="ecv2_operator_equal"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_equal">Member
function <code class="computeroutput">operator==</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> and <code class="computeroutput"><span class="identifier">other</span></code>
represent the same execution context, <code class="computeroutput"><span class="keyword">false</span></code>
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_notequal_bridgehead"></a>
<span><a name="ecv2_operator_notequal"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_notequal">Member
function <code class="computeroutput">operator!=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput">! (other == * this)</code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_less_bridgehead"></a>
<span><a name="ecv2_operator_less"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_less">Member function
<code class="computeroutput">operator&lt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="identifier">other</span></code> is true and the implementation-defined
total order of <code class="computeroutput"><span class="identifier">execution_context</span></code>
values places <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
before <code class="computeroutput"><span class="identifier">other</span></code>, false otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_greater_bridgehead"></a>
<span><a name="ecv2_operator_greater"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_greater">Member
function <code class="computeroutput">operator&gt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_lesseq_bridgehead"></a>
<span><a name="ecv2_operator_lesseq"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_lesseq">Member
function <code class="computeroutput">operator&lt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(</span><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2_operator_greatereq_bridgehead"></a>
<span><a name="ecv2_operator_greatereq"></a></span>
<a class="link" href="ecv2.html#ecv2_operator_greatereq">Member
function <code class="computeroutput">operator&gt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(*</span>
<span class="keyword">this</span> <span class="special">&lt;</span>
<span class="identifier">other</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ecv2__bridgehead"></a>
<span><a name="ecv2_"></a></span>
<a class="link" href="ecv2.html#ecv2_">Non-member function <code class="computeroutput">operator&lt;&lt;()</code></a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">execution_context</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Efects:</span></dt>
<dd><p>
Writes the representation of <code class="computeroutput"><span class="identifier">other</span></code>
to stream <code class="computeroutput"><span class="identifier">os</span></code>.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">os</span></code>
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cc/class__continuation_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ecv1.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,522 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Context switching with fibers</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="requirements.html" title="Requirements">
<link rel="next" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.ff"></a><a name="ff"></a><a class="link" href="ff.html" title="Context switching with fibers">Context switching with fibers</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html">Implementations:
fcontext_t, ucontext_t and WinFiber</a></span></dt>
<dt><span class="section"><a href="ff/class__fiber_.html">Class <code class="computeroutput"><span class="identifier">fiber</span></code></a></span></dt>
</dl></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<span class="emphasis"><em>fiber</em></span> is the reference implementation of C++ proposal
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0876r0.pdf" target="_top">P0876R0:
fibers without scheduler</a>.
</p></td></tr>
</table></div>
<p>
A <span class="emphasis"><em>fiber</em></span> represents the state of the control flow of a
program at a given point in time. Fibers can be suspended and resumed later
in order to change the control flow of a program.
</p>
<p>
Modern micro-processors are registers machines; the content of processor registers
represent a fiber of the executed program at a given point in time. Operating
systems simulate parallel execution of programs on a single processor by switching
between programs (context switch) by preserving and restoring the fiber, e.g.
the content of all registers.
</p>
<h4>
<a name="context.ff.h0"></a>
<span><a name="context.ff._link_linkend__ff___emphasis_fiber__emphasis___link_"></a></span><a class="link" href="ff.html#context.ff._link_linkend__ff___emphasis_fiber__emphasis___link_"><a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a></a>
</h4>
<p>
<a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> captures the current fiber
(the rest of the computation; code after <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>)
and triggers a context switch. The context switch is achieved by preserving
certain registers (including instruction and stack pointer), defined by the
calling convention of the ABI, of the current fiber and restoring those registers
of the resumed fiber. The control flow of the resumed fiber continues. The
current fiber is suspended and passed as argument to the resumed fiber.
</p>
<p>
<a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> expects a <span class="emphasis"><em>context-function</em></span>
with signature <code class="computeroutput"><span class="char">'fiber(fiber &amp;&amp; f)'</span></code>.
The parameter <code class="computeroutput"><span class="identifier">f</span></code> represents
the current fiber from which this fiber was resumed (e.g. that has called
<a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>).
</p>
<p>
On return the <span class="emphasis"><em>context-function</em></span> of the current fiber has
to specify an <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> to which
the execution control is transferred after termination of the current fiber.
</p>
<p>
If an instance with valid state goes out of scope and the <span class="emphasis"><em>context-function</em></span>
has not yet returned, the stack is traversed in order to access the control
structure (address stored at the first stack frame) and fiber's stack is deallocated
via the <span class="emphasis"><em>StackAllocator</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<a class="link" href="stack/segmented.html#segmented"><span class="emphasis"><em>Segmented stacks</em></span></a> are
supported by <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> using
<a class="link" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>ucontext_t</em></span></a>.
</p></td></tr>
</table></div>
<p>
<a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> represents a <span class="emphasis"><em>fiber</em></span>;
it contains the content of preserved registers and manages the associated stack
(allocation/deallocation). <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>
is a one-shot fiber - it can be used only once, after calling <span class="emphasis"><em>continuation::resume()</em></span>
or <span class="emphasis"><em>continuation::resume_with()</em></span> it is invalidated.
</p>
<p>
<a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> is only move-constructible
and move-assignable.
</p>
<p>
As a first-class object <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>
can be applied to and returned from a function, assigned to a variable or stored
in a container.
</p>
<p>
A fiber is continued by calling <code class="computeroutput"><span class="identifier">resume</span><span class="special">()</span></code>/<code class="computeroutput"><span class="identifier">resume_with</span><span class="special">()</span></code>.
</p>
<h4>
<a name="context.ff.h1"></a>
<span><a name="context.ff.usage"></a></span><a class="link" href="ff.html#context.ff.usage">Usage</a>
</h4>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">source</span><span class="special">{[&amp;</span><span class="identifier">a</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">){</span>
<span class="identifier">a</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">b</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">for</span><span class="special">(;;){</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">int</span> <span class="identifier">next</span><span class="special">=</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">=</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">b</span><span class="special">=</span><span class="identifier">next</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">}};</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">j</span><span class="special">=</span><span class="number">0</span><span class="special">;</span><span class="identifier">j</span><span class="special">&lt;</span><span class="number">10</span><span class="special">;++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">source</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span>
</pre>
<p>
This simple example demonstrates the basic usage of <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>
as a <span class="emphasis"><em>generator</em></span>. The fiber <code class="computeroutput"><span class="identifier">sink</span></code>
represents the <span class="emphasis"><em>main</em></span>-fiber (function <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code>). <code class="computeroutput"><span class="identifier">sink</span></code>
is captured (current-fiber) by invoking <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>
and passed as parameter to the lambda.
</p>
<p>
Because the state is invalidated (one-shot fiber) by each call of <span class="emphasis"><em>continuation::resume()</em></span>,
the new state of the <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>,
returned by <span class="emphasis"><em>continuation::resume()</em></span>, needs to be assigned
to <code class="computeroutput"><span class="identifier">sink</span></code> after each call. In
order to express the invalidation of the resumed fiber, the member functions
<code class="computeroutput"><span class="identifier">resume</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">resume_with</span><span class="special">()</span></code>
are rvalue-ref qualified. Both functions bind only to rvalues. Thus an lvalue
fiber must be casted to an rvalue via <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">()</span></code>.
</p>
<p>
The lambda that calculates the Fibonacci numbers is executed inside the fiber
represented by <code class="computeroutput"><span class="identifier">source</span></code>. Calculated
Fibonacci numbers are transferred between the two fibers via variable <code class="computeroutput"><span class="identifier">a</span></code> (lambda capture reference).
</p>
<p>
The locale variables <code class="computeroutput"><span class="identifier">b</span></code> and
<code class="computeroutput"> <span class="identifier">next</span></code> remain their values during
each context switch. This is possible due <code class="computeroutput"><span class="identifier">source</span></code>
has its own stack and the stack is exchanged by each context switch.
</p>
<h4>
<a name="context.ff.h2"></a>
<span><a name="context.ff.parameter_passing"></a></span><a class="link" href="ff.html#context.ff.parameter_passing">Parameter
passing</a>
</h4>
<p>
Data can be transferred between two fibers via global pointers, calling wrappers
(like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>) or lambda captures.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f1</span><span class="special">{[&amp;</span><span class="identifier">i</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">&amp;&amp;</span> <span class="identifier">f2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside f1,i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">i</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f2</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}};</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f1</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">c1</span><span class="special">,</span><span class="identifier">i</span><span class="special">==</span><span class="number">1</span>
<span class="identifier">i</span><span class="special">==</span><span class="number">2</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>
enters the lambda in fiber represented by <code class="computeroutput"><span class="identifier">f1</span></code>
with lambda capture reference <code class="computeroutput"><span class="identifier">i</span><span class="special">=</span><span class="number">1</span></code>. The expression
<code class="computeroutput"><span class="identifier">f2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>
resumes the fiber <code class="computeroutput"><span class="identifier">f2</span></code>. On return
of <code class="computeroutput"><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>,
the variable <code class="computeroutput"><span class="identifier">i</span></code> has the value
of <code class="computeroutput"><span class="identifier">i</span><span class="special">+</span><span class="number">1</span></code>.
</p>
<h4>
<a name="context.ff.h3"></a>
<span><a name="context.ff.exception_handling"></a></span><a class="link" href="ff.html#context.ff.exception_handling">Exception
handling</a>
</h4>
<p>
If the function executed inside a <span class="emphasis"><em>context-function</em></span> emits
an exception, the application is terminated by calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span><span class="special">()</span></code>. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>
can be used to transfer exceptions between different fibers.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Do not jump from inside a catch block and then re-throw the exception in
another fiber.
</p></td></tr>
</table></div>
<a name="ff_ontop"></a><h4>
<a name="context.ff.h4"></a>
<span><a name="context.ff.executing_function_on_top_of_a_fiber"></a></span><a class="link" href="ff.html#context.ff.executing_function_on_top_of_a_fiber">Executing
function on top of a fiber</a>
</h4>
<p>
Sometimes it is useful to execute a new function on top of a resumed fiber.
For this purpose <span class="emphasis"><em>continuation::resume_with()</em></span> has to be
used. The function passed as argument must accept a rvalue reference to <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> and return <code class="computeroutput"><span class="keyword">void</span></code>.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">data</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f1</span><span class="special">{[&amp;</span><span class="identifier">data</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">&amp;&amp;</span> <span class="identifier">f2</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f2</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f2</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f2</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f2</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered third time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f2</span><span class="special">);</span>
<span class="special">}};</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f1</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f1</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">([&amp;</span><span class="identifier">data</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">&amp;&amp;</span> <span class="identifier">f2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: entered: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">=-</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f2</span><span class="special">);</span>
<span class="special">});</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned third time"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">0</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">2</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">3</span>
<span class="identifier">f2</span><span class="special">:</span> <span class="identifier">entered</span><span class="special">:</span> <span class="number">4</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">third</span> <span class="identifier">time</span><span class="special">:</span> <span class="special">-</span><span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">third</span> <span class="identifier">time</span>
</pre>
<p>
The expression <code class="computeroutput"><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">(...)</span></code>
executes a lambda on top of fiber <code class="computeroutput"><span class="identifier">f1</span></code>,
e.g. an additional stack frame is allocated on top of the stack. This lambda
assigns <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
to <code class="computeroutput"><span class="identifier">data</span></code> and returns to the
second invocation of <code class="computeroutput"><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>.
</p>
<p>
Another option is to execute a function on top of the fiber that throws an
exception.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">struct</span> <span class="identifier">my_exception</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span> <span class="special">{</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f</span><span class="special">;</span>
<span class="identifier">my_exception</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">&amp;&amp;</span> <span class="identifier">f_</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">what</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">{</span> <span class="identifier">what</span> <span class="special">},</span>
<span class="identifier">f</span><span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f_</span><span class="special">)</span> <span class="special">}</span> <span class="special">{</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f</span><span class="special">{[](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">-&gt;</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"entered"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">try</span> <span class="special">{</span>
<span class="identifier">f</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">my_exception</span> <span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"my_exception: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ex</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ex</span><span class="special">.</span><span class="identifier">f</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="special">{};</span>
<span class="special">});</span>
<span class="identifier">f</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">f</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">).</span><span class="identifier">resume_with</span><span class="special">([](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">-&gt;</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">my_exception</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">),</span><span class="string">"abc"</span><span class="special">);</span>
<span class="keyword">return</span> <span class="special">{};</span>
<span class="special">});</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">entered</span>
<span class="identifier">my_exception</span><span class="special">:</span> <span class="identifier">abc</span>
</pre>
<p>
In this exception <code class="computeroutput"><span class="identifier">my_exception</span></code>
is throw from a function invoked on-top of fiber <code class="computeroutput"><span class="identifier">f</span></code>
and catched inside the <code class="computeroutput"><span class="keyword">for</span></code>-loop.
</p>
<h4>
<a name="context.ff.h5"></a>
<span><a name="context.ff.stack_unwinding"></a></span><a class="link" href="ff.html#context.ff.stack_unwinding">Stack
unwinding</a>
</h4>
<p>
On construction of <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> a stack
is allocated. If the <span class="emphasis"><em>context-function</em></span> returns the stack
will be destructed. If the <span class="emphasis"><em>context-function</em></span> has not yet
returned and the destructor of an valid <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>
instance (e.g. <span class="emphasis"><em>fiber::operator bool()</em></span> returns <code class="computeroutput"><span class="keyword">true</span></code>) is called, the stack will be destructed
too.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Code executed by <span class="emphasis"><em>context-function</em></span> must not prevent the
propagation ofs the <span class="emphasis"><em>detail::forced_unwind</em></span> exception.
Absorbing that exception will cause stack unwinding to fail. Thus, any code
that catches all exceptions must re-throw any pending <span class="emphasis"><em>detail::forced_unwind</em></span>
exception.
</p></td></tr>
</table></div>
<a name="ff_prealloc"></a><h4>
<a name="context.ff.h6"></a>
<span><a name="context.ff.allocating_control_structures_on_top_of_stack"></a></span><a class="link" href="ff.html#context.ff.allocating_control_structures_on_top_of_stack">Allocating
control structures on top of stack</a>
</h4>
<p>
Allocating control structures on top of the stack requires to allocated the
<span class="emphasis"><em>stack_context</em></span> and create the control structure with placement
new before <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> is created.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The user is responsible for destructing the control structure at the top
of the stack.
</p></td></tr>
</table></div>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="comment">// stack-allocator used for (de-)allocating stack</span>
<span class="identifier">fixedsize_stack</span> <span class="identifier">salloc</span><span class="special">(</span><span class="number">4048</span><span class="special">);</span>
<span class="comment">// allocate stack space</span>
<span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">(</span><span class="identifier">salloc</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">());</span>
<span class="comment">// reserve space for control structure on top of the stack</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">=</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span><span class="special">)-</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">=</span><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">-</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="comment">// placement new creates control structure on reserved space</span>
<span class="identifier">my_control_structure</span> <span class="special">*</span> <span class="identifier">cs</span><span class="special">=</span><span class="keyword">new</span><span class="special">(</span><span class="identifier">sp</span><span class="special">)</span><span class="identifier">my_control_structure</span><span class="special">(</span><span class="identifier">sp</span><span class="special">,</span><span class="identifier">size</span><span class="special">,</span><span class="identifier">sctx</span><span class="special">,</span><span class="identifier">salloc</span><span class="special">);</span>
<span class="special">...</span>
<span class="comment">// destructing the control structure</span>
<span class="identifier">cs</span><span class="special">-&gt;~</span><span class="identifier">my_control_structure</span><span class="special">();</span>
<span class="special">...</span>
<span class="keyword">struct</span> <span class="identifier">my_control_structure</span> <span class="special">{</span>
<span class="comment">// captured fiber</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAllocator</span> <span class="special">&gt;</span>
<span class="identifier">my_control_structure</span><span class="special">(</span><span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span><span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">,</span><span class="identifier">StackAllocator</span> <span class="identifier">salloc</span><span class="special">)</span> <span class="special">:</span>
<span class="comment">// create captured fiber</span>
<span class="identifier">f</span><span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg</span><span class="special">,</span><span class="identifier">preallocated</span><span class="special">(</span><span class="identifier">sp</span><span class="special">,</span><span class="identifier">size</span><span class="special">,</span><span class="identifier">sctx</span><span class="special">),</span><span class="identifier">salloc</span><span class="special">,</span><span class="identifier">entry_func</span><span class="special">}</span> <span class="special">{</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<h4>
<a name="context.ff.h7"></a>
<span><a name="context.ff.inverting_the_control_flow"></a></span><a class="link" href="ff.html#context.ff.inverting_the_control_flow">Inverting
the control flow</a>
</h4>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="comment">/*
* grammar:
* P ---&gt; E '\0'
* E ---&gt; T {('+'|'-') T}
* T ---&gt; S {('*'|'/') S}
* S ---&gt; digit | '(' E ')'
*/</span>
<span class="keyword">class</span> <span class="identifier">Parser</span><span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">next</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">char</span><span class="special">)&gt;</span> <span class="identifier">cb</span><span class="special">;</span>
<span class="keyword">char</span> <span class="identifier">pull</span><span class="special">(){</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;::</span><span class="identifier">to_char_type</span><span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">scan</span><span class="special">(){</span>
<span class="keyword">do</span><span class="special">{</span>
<span class="identifier">next</span><span class="special">=</span><span class="identifier">pull</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">isspace</span><span class="special">(</span><span class="identifier">next</span><span class="special">));</span>
<span class="special">}</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">Parser</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is_</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">char</span><span class="special">)&gt;</span> <span class="identifier">cb_</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">next</span><span class="special">(),</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">is_</span><span class="special">),</span> <span class="identifier">cb</span><span class="special">(</span><span class="identifier">cb_</span><span class="special">)</span>
<span class="special">{}</span>
<span class="keyword">void</span> <span class="identifier">run</span><span class="special">()</span> <span class="special">{</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">E</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">void</span> <span class="identifier">E</span><span class="special">(){</span>
<span class="identifier">T</span><span class="special">();</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'+'</span><span class="special">||</span><span class="identifier">next</span><span class="special">==</span><span class="char">'-'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">T</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">T</span><span class="special">(){</span>
<span class="identifier">S</span><span class="special">();</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'*'</span><span class="special">||</span><span class="identifier">next</span><span class="special">==</span><span class="char">'/'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">S</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">S</span><span class="special">(){</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">isdigit</span><span class="special">(</span><span class="identifier">next</span><span class="special">)){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">else</span> <span class="keyword">if</span><span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'('</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">E</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">')'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="special">}</span><span class="keyword">else</span><span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"parsing failed"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">else</span><span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"parsing failed"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="string">"1+1"</span><span class="special">);</span>
<span class="comment">// user-code pulls parsed data from parser</span>
<span class="comment">// invert control flow</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">done</span><span class="special">=</span><span class="keyword">false</span><span class="special">;</span>
<span class="comment">// execute parser in new fiber</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">source</span><span class="special">{[&amp;</span><span class="identifier">is</span><span class="special">,&amp;</span><span class="identifier">c</span><span class="special">,&amp;</span><span class="identifier">done</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">){</span>
<span class="comment">// create parser with callback function</span>
<span class="identifier">Parser</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span>
<span class="special">[&amp;</span><span class="identifier">sink</span><span class="special">,&amp;</span><span class="identifier">c</span><span class="special">](</span><span class="keyword">char</span> <span class="identifier">c_</span><span class="special">){</span>
<span class="comment">// resume main fiber</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c_</span><span class="special">;</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">});</span>
<span class="comment">// start recursive parsing</span>
<span class="identifier">p</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="comment">// signal termination</span>
<span class="identifier">done</span><span class="special">=</span><span class="keyword">true</span><span class="special">;</span>
<span class="comment">// resume main fiber</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">}};</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">source</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">while</span><span class="special">(!</span><span class="identifier">done</span><span class="special">){</span>
<span class="identifier">printf</span><span class="special">(</span><span class="string">"Parsed: %c\n"</span><span class="special">,</span><span class="identifier">c</span><span class="special">);</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">Move</span><span class="special">(</span><span class="identifier">source</span><span class="special">).</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="special">+</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
</pre>
<p>
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using <a class="link" href="ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> the
control flow can be inverted, e.g. the user-code pulls parsed symbols from
the parser - instead to get pushed from the parser (via callback).
</p>
<p>
The data (character) is transferred between the two fibers.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,506 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class fiber</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../ff.html" title="Context switching with fibers">
<link rel="prev" href="implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">
<link rel="next" href="../cc.html" title="Context switching with call/cc">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../ff.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../cc.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.ff.class__fiber_"></a><a class="link" href="class__fiber_.html" title="Class fiber">Class <code class="computeroutput"><span class="identifier">fiber</span></code></a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">fiber</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">fiber</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="special">&amp;&amp;</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="special">~</span><span class="identifier">fiber</span><span class="special">();</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
<span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
<span class="identifier">fiber</span> <span class="identifier">resume</span><span class="special">()</span> <span class="special">&amp;&amp;;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span> <span class="identifier">resume_with</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">)</span> <span class="special">&amp;&amp;;</span>
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">traitsT</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<h5>
<a name="ff_constructor1_bridgehead"></a>
<span><a name="ff_constructor1"></a></span>
<a class="link" href="class__fiber_.html#ff_constructor1">Constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Creates a invalid fiber.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_constructor2_bridgehead"></a>
<span><a name="ff_constructor2"></a></span>
<a class="link" href="class__fiber_.html#ff_constructor2">Constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="special">&amp;&amp;</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Creates a new fiber and prepares the context to execute <code class="computeroutput"><span class="identifier">fn</span></code>. <code class="computeroutput"><span class="identifier">fixedsize_stack</span></code>
is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
The constructor with argument type <code class="computeroutput"><span class="identifier">preallocated</span></code>,
is used to create a user defined data <a class="link" href="../ff.html#ff_prealloc">(for
instance additional control structures)</a> on top of the stack.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_destructor%20destructor_bridgehead"></a>
<span><a name="ff_destructor%20destructor"></a></span>
<a class="link" href="class__fiber_.html#ff_destructor%20destructor">Destructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="special">~</span><span class="identifier">fiber</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Destructs the associated stack if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is a valid fiber, e.g. <span class="emphasis"><em>fiber::operator
bool()</em></span> returns <code class="computeroutput"><span class="keyword">true</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_move%20constructor_bridgehead"></a>
<span><a name="ff_move%20constructor"></a></span>
<a class="link" href="class__fiber_.html#ff_move%20constructor">Move
constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span><span class="special">(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves underlying capture fiber to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_move%20assignment_bridgehead"></a>
<span><a name="ff_move%20assignment"></a></span>
<a class="link" href="class__fiber_.html#ff_move%20assignment">Move assignment
operator</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves the state of <code class="computeroutput"><span class="identifier">other</span></code>
to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
using move semantics.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_call_bridgehead"></a>
<span><a name="ff_operator_call"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_call">Member function
<code class="computeroutput">operator()</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span> <span class="identifier">resume</span><span class="special">()</span> <span class="special">&amp;&amp;;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span> <span class="identifier">resume_with</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">)</span> <span class="special">&amp;&amp;;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Captures current fiber and resumes <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>. The function <code class="computeroutput"><span class="identifier">resume_with</span></code>,
is used to execute function <code class="computeroutput"><span class="identifier">fn</span></code>
in the execution context of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> (e.g. the stack frame of <code class="computeroutput"><span class="identifier">fn</span></code> is allocated on stack of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>).
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The fiber representing the fiber that has been suspended.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
Because <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
gets invalidated, <code class="computeroutput"><span class="identifier">resume</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">resume_with</span><span class="special">()</span></code> are rvalue-ref qualified and bind
only to rvalues.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
Function <code class="computeroutput"><span class="identifier">fn</span></code> needs to
return <code class="computeroutput"><span class="identifier">fiber</span></code>.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned fiber indicates if the suspended fiber has terminated
(return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_bool_bridgehead"></a>
<span><a name="ff_operator_bool"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_bool">Member function
<code class="computeroutput">operator bool</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
points to a captured fiber.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_not_bridgehead"></a>
<span><a name="ff_operator_not"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_not">Member function <code class="computeroutput">operator!</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
does not point to a captured fiber.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_equal_bridgehead"></a>
<span><a name="ff_operator_equal"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_equal">Member function
<code class="computeroutput">operator==</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
and <code class="computeroutput"><span class="identifier">other</span></code> represent
the same fiber, <code class="computeroutput"><span class="keyword">false</span></code>
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_notequal_bridgehead"></a>
<span><a name="ff_operator_notequal"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_notequal">Member
function <code class="computeroutput">operator!=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput">! (other == * this)</code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_less_bridgehead"></a>
<span><a name="ff_operator_less"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_less">Member function
<code class="computeroutput">operator&lt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="identifier">other</span></code>
is true and the implementation-defined total order of <code class="computeroutput"><span class="identifier">fiber</span></code> values places <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
before <code class="computeroutput"><span class="identifier">other</span></code>, false
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_greater_bridgehead"></a>
<span><a name="ff_operator_greater"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_greater">Member
function <code class="computeroutput">operator&gt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_lesseq_bridgehead"></a>
<span><a name="ff_operator_lesseq"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_lesseq">Member function
<code class="computeroutput">operator&lt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(</span><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff_operator_greatereq_bridgehead"></a>
<span><a name="ff_operator_greatereq"></a></span>
<a class="link" href="class__fiber_.html#ff_operator_greatereq">Member
function <code class="computeroutput">operator&gt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(*</span>
<span class="keyword">this</span> <span class="special">&lt;</span>
<span class="identifier">other</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="ff__bridgehead"></a>
<span><a name="ff_"></a></span>
<a class="link" href="class__fiber_.html#ff_">Non-member function <code class="computeroutput">operator&lt;&lt;()</code></a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">traitsT</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Writes the representation of <code class="computeroutput"><span class="identifier">other</span></code>
to stream <code class="computeroutput"><span class="identifier">os</span></code>.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">os</span></code>
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../ff.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../cc.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,109 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Implementations: fcontext_t, ucontext_t and WinFiber</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../ff.html" title="Context switching with fibers">
<link rel="prev" href="../ff.html" title="Context switching with fibers">
<link rel="next" href="class__fiber_.html" title="Class fiber">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../ff.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../ff.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="class__fiber_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber"></a><a name="implementation"></a><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">Implementations:
fcontext_t, ucontext_t and WinFiber</a>
</h3></div></div></div>
<h5>
<a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h0"></a>
<span><a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</a>
</h5>
<p>
The implementation uses <span class="emphasis"><em>fcontext_t</em></span> per default. fcontext_t
is based on assembler and not available for all platforms. It provides a
much better performance than <span class="emphasis"><em>ucontext_t</em></span> (the context
switch takes two magnitudes of order less CPU cycles; see section <a class="link" href="../performance.html#performance"><span class="emphasis"><em>performance</em></span></a>)
and <span class="emphasis"><em>WinFiber</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Because the TIB (thread information block on Windows) is not fully described
in the MSDN, it might be possible that not all required TIB-parts are swapped.
Using WinFiber implementation migh be an alternative.
</p></td></tr>
</table></div>
<h5>
<a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h1"></a>
<span><a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</a>
</h5>
<p>
As an alternative, <a href="https://en.wikipedia.org/wiki/Setcontext" target="_top"><span class="emphasis"><em>ucontext_t</em></span></a>
can be used by compiling with <code class="computeroutput"><span class="identifier">BOOST_USE_UCONTEXT</span></code>
and b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">ucontext</span></code>.
<span class="emphasis"><em>ucontext_t</em></span> might be available on a broader range of
POSIX-platforms but has some <a class="link" href="../rationale/other_apis_.html#ucontext"><span class="emphasis"><em>disadvantages</em></span></a>
(for instance deprecated since POSIX.1-2003, not C99 conform).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<a class="link" href="../ff.html#ff"><span class="emphasis"><em>fiber</em></span></a> supports <a class="link" href="../stack/segmented.html#segmented"><span class="emphasis"><em>Segmented
stacks</em></span></a> only with <span class="emphasis"><em>ucontext_t</em></span> as its
implementation.
</p></td></tr>
</table></div>
<h5>
<a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h2"></a>
<span><a name="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</a>
</h5>
<p>
With <code class="computeroutput"><span class="identifier">BOOST_USE_WINFIB</span></code> and
b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">winfib</span></code>
Win32-Fibers are used as implementation for <a class="link" href="../ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The first call of <a class="link" href="../ff.html#ff"><span class="emphasis"><em>fiber</em></span></a>
converts the thread into a Windows fiber by invoking <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code>. If desired, <code class="computeroutput"><span class="identifier">ConvertFiberToThread</span><span class="special">()</span></code> has to be called by the user explicitly
in order to release resources allocated by <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code> (e.g. after using boost.context).
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../ff.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../ff.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="class__fiber_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,512 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Context switching with fibers</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="requirements.html" title="Requirements">
<link rel="next" href="fib/implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="fib/implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.fib"></a><a name="fib"></a><a class="link" href="fib.html" title="Context switching with fibers">Context switching with fibers</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="fib/implementations__fcontext_t__ucontext_t_and_winfiber.html">Implementations:
fcontext_t, ucontext_t and WinFiber</a></span></dt>
<dt><span class="section"><a href="fib/class__fiber_.html">Class <code class="computeroutput"><span class="identifier">fiber</span></code></a></span></dt>
</dl></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
__fiber__ is the reference implementation of C++ proposal <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0534r3.pdf" target="_top">P0876R0:
fibers without scheduler</a>.
</p></td></tr>
</table></div>
<p>
A fiber represents the state of the control flow of a program at a given point
in time. Fibers can be suspended and resumed later in order to change the control
flow of a program.
</p>
<p>
Modern micro-processors are registers machines; the content of processor registers
represent a fiber of the executed program at a given point in time. Operating
systems simulate parallel execution of programs on a single processor by switching
between programs (context switch) by preserving and restoring the fiber, e.g.
the content of all registers.
</p>
<h4>
<a name="context.fib.h0"></a>
<span><a name="context.fib.__fiber__"></a></span><a class="link" href="fib.html#context.fib.__fiber__">__fiber__</a>
</h4>
<p>
__fiber__ captures the current fiber (the rest of the computation; code after
__fiber__) and triggers a context switch. The context switch is achieved by
preserving certain registers (including instruction and stack pointer), defined
by the calling convention of the ABI, of the current fiber and restoring those
registers of the resumed fiber. The control flow of the resumed fiber continues.
The current fiber is suspended and passed as argument to the resumed fiber.
</p>
<p>
__fiber__ expects a <span class="emphasis"><em>context-function</em></span> with signature <code class="computeroutput"><span class="char">'fiber(fiber &amp;&amp; f)'</span></code>. The parameter <code class="computeroutput"><span class="identifier">f</span></code> represents the current fiber from which
this fiber was resumed (e.g. that has called __fiber__).
</p>
<p>
On return the <span class="emphasis"><em>context-function</em></span> of the current fiber has
to specify an <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> to
which the execution control is transferred after termination of the current
fiber.
</p>
<p>
If an instance with valid state goes out of scope and the <span class="emphasis"><em>context-function</em></span>
has not yet returned, the stack is traversed in order to access the control
structure (address stored at the first stack frame) and fiber's stack is deallocated
via the <span class="emphasis"><em>StackAllocator</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<a class="link" href="stack/segmented.html#segmented"><span class="emphasis"><em>Segmented stacks</em></span></a> are
supported by __fiber__ using <a class="link" href="fib/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>ucontext_t</em></span></a>.
</p></td></tr>
</table></div>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> represents a fiber;
it contains the content of preserved registers and manages the associated stack
(allocation/deallocation). <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
is a one-shot fiber - it can be used only once, after calling <span class="emphasis"><em>continuation::resume()</em></span>
or <span class="emphasis"><em>continuation::resume_with()</em></span> it is invalidated.
</p>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> is only move-constructible
and move-assignable.
</p>
<p>
As a first-class object <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
can be applied to and returned from a function, assigned to a variable or stored
in a container.
</p>
<p>
A fiber is continued by calling <code class="computeroutput"><span class="identifier">resume</span><span class="special">()</span></code>/<code class="computeroutput"><span class="identifier">resume_with</span><span class="special">()</span></code>.
</p>
<h4>
<a name="context.fib.h1"></a>
<span><a name="context.fib.usage"></a></span><a class="link" href="fib.html#context.fib.usage">Usage</a>
</h4>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">source</span><span class="special">{[&amp;</span><span class="identifier">a</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">){</span>
<span class="identifier">a</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">b</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">for</span><span class="special">(;;){</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">sink</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">int</span> <span class="identifier">next</span><span class="special">=</span><span class="identifier">a</span><span class="special">+</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">=</span><span class="identifier">b</span><span class="special">;</span>
<span class="identifier">b</span><span class="special">=</span><span class="identifier">next</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">}};</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">j</span><span class="special">=</span><span class="number">0</span><span class="special">;</span><span class="identifier">j</span><span class="special">&lt;</span><span class="number">10</span><span class="special">;++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">source</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span>
</pre>
<p>
This simple example demonstrates the basic usage of __fiber__ as a <span class="emphasis"><em>generator</em></span>.
The fiber <code class="computeroutput"><span class="identifier">sink</span></code> represents the
<span class="emphasis"><em>main</em></span>-fiber (function <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code>). <code class="computeroutput"><span class="identifier">sink</span></code>
is captured (current-fiber) by invoking __fiber__ and passed as parameter to
the lambda.
</p>
<p>
Because the state is invalidated (one-shot fiber) by each call of <span class="emphasis"><em>continuation::resume()</em></span>,
the new state of the <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>,
returned by <span class="emphasis"><em>continuation::resume()</em></span>, needs to be assigned
to <code class="computeroutput"><span class="identifier">sink</span></code> after each call.
</p>
<p>
The lambda that calculates the Fibonacci numbers is executed inside the fiber
represented by <code class="computeroutput"><span class="identifier">source</span></code>. Calculated
Fibonacci numbers are transferred between the two fibers via variable <code class="computeroutput"><span class="identifier">a</span></code> (lambda capture reference).
</p>
<p>
The locale variables <code class="computeroutput"><span class="identifier">b</span></code> and
<code class="computeroutput"> <span class="identifier">next</span></code> remain their values during
each context switch. This is possible due <code class="computeroutput"><span class="identifier">source</span></code>
has its own stack and the stack is exchanged by each context switch.
</p>
<h4>
<a name="context.fib.h2"></a>
<span><a name="context.fib.parameter_passing"></a></span><a class="link" href="fib.html#context.fib.parameter_passing">Parameter
passing</a>
</h4>
<p>
Data can be transferred between two fibers via global pointers, calling wrappers
(like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>) or lambda captures.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f1</span><span class="special">{[&amp;</span><span class="identifier">i</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside f1,i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">i</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">f2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}};</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i==%d\n"</span><span class="special">,</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">c1</span><span class="special">,</span><span class="identifier">i</span><span class="special">==</span><span class="number">1</span>
<span class="identifier">i</span><span class="special">==</span><span class="number">2</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">callcc</span><span class="special">(&lt;</span><span class="identifier">lambda</span><span class="special">&gt;)</span></code>
enters the lambda in fiber represented by <code class="computeroutput"><span class="identifier">c1</span></code>
with lambda capture reference <code class="computeroutput"><span class="identifier">i</span><span class="special">=</span><span class="number">1</span></code>. The expression
<code class="computeroutput"><span class="identifier">c2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>
resumes the fiber <code class="computeroutput"><span class="identifier">c2</span></code>. On return
of <code class="computeroutput"><span class="identifier">callcc</span><span class="special">(&lt;</span><span class="identifier">lambda</span><span class="special">&gt;)</span></code>,
the variable <code class="computeroutput"><span class="identifier">i</span></code> has the value
of <code class="computeroutput"><span class="identifier">i</span><span class="special">+</span><span class="number">1</span></code>.
</p>
<h4>
<a name="context.fib.h3"></a>
<span><a name="context.fib.exception_handling"></a></span><a class="link" href="fib.html#context.fib.exception_handling">Exception
handling</a>
</h4>
<p>
If the function executed inside a <span class="emphasis"><em>context-function</em></span> emits
an exception, the application is terminated by calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span><span class="special">()</span></code>. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>
can be used to transfer exceptions between different fibers.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Do not jump from inside a catch block and then re-throw the exception in
another fiber.
</p></td></tr>
</table></div>
<a name="cc_ontop"></a><h4>
<a name="context.fib.h4"></a>
<span><a name="context.fib.executing_function_on_top_of_a_fiber"></a></span><a class="link" href="fib.html#context.fib.executing_function_on_top_of_a_fiber">Executing
function on top of a fiber</a>
</h4>
<p>
Sometimes it is useful to execute a new function on top of a resumed fiber.
For this purpose <span class="emphasis"><em>continuation::resume_with()</em></span> has to be
used. The function passed as argument must accept a rvalue reference to <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> and return <code class="computeroutput"><span class="keyword">void</span></code>.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">data</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f1</span><span class="special">{[&amp;</span><span class="identifier">data</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f2</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f2</span><span class="special">=</span><span class="identifier">f2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f2</span><span class="special">=</span><span class="identifier">f2</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered third time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f2</span><span class="special">);</span>
<span class="special">}};</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">+=</span><span class="number">1</span><span class="special">;</span>
<span class="identifier">f1</span><span class="special">=</span><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">([&amp;</span><span class="identifier">data</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: entered: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">data</span><span class="special">=-</span><span class="number">1</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">f2</span><span class="special">);</span>
<span class="special">});</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned third time"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">0</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">2</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">3</span>
<span class="identifier">f2</span><span class="special">:</span> <span class="identifier">entered</span><span class="special">:</span> <span class="number">4</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">third</span> <span class="identifier">time</span><span class="special">:</span> <span class="special">-</span><span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">third</span> <span class="identifier">time</span>
</pre>
<p>
The expression <code class="computeroutput"><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">(...)</span></code>
executes a lambda on top of fiber <code class="computeroutput"><span class="identifier">f1</span></code>,
e.g. an additional stack frame is allocated on top of the stack. This lambda
assigns <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
to <code class="computeroutput"><span class="identifier">data</span></code> and returns to the
second invocation of <code class="computeroutput"><span class="identifier">f1</span><span class="special">.</span><span class="identifier">resume</span><span class="special">()</span></code>.
</p>
<p>
Another option is to execute a function on top of the fiber that throws an
exception.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="keyword">struct</span> <span class="identifier">my_exception</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span> <span class="special">{</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f</span><span class="special">;</span>
<span class="identifier">my_exception</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f_</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">what</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">{</span> <span class="identifier">what</span> <span class="special">},</span>
<span class="identifier">f</span><span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">f_</span><span class="special">)</span> <span class="special">}</span> <span class="special">{</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f</span><span class="special">{[](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">-&gt;</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"entered"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">try</span> <span class="special">{</span>
<span class="identifier">f</span><span class="special">=</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">my_exception</span> <span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"my_exception: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ex</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ex</span><span class="special">.</span><span class="identifier">f</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="special">{};</span>
<span class="special">});</span>
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">resume_with</span><span class="special">([](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">-&gt;</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">my_exception</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">),</span><span class="string">"abc"</span><span class="special">);</span>
<span class="keyword">return</span> <span class="special">{};</span>
<span class="special">});</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">entered</span>
<span class="identifier">my_exception</span><span class="special">:</span> <span class="identifier">abc</span>
</pre>
<p>
In this exception <code class="computeroutput"><span class="identifier">my_exception</span></code>
is throw from a function invoked on-top of fiber <code class="computeroutput"><span class="identifier">c</span></code>
and catched inside the <code class="computeroutput"><span class="keyword">for</span></code>-loop.
</p>
<h4>
<a name="context.fib.h5"></a>
<span><a name="context.fib.stack_unwinding"></a></span><a class="link" href="fib.html#context.fib.stack_unwinding">Stack
unwinding</a>
</h4>
<p>
On construction of <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
a stack is allocated. If the <span class="emphasis"><em>context-function</em></span> returns
the stack will be destructed. If the <span class="emphasis"><em>context-function</em></span>
has not yet returned and the destructor of an valid <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
instance (e.g. <span class="emphasis"><em>fiber::operator bool()</em></span> returns <code class="computeroutput"><span class="keyword">true</span></code>) is called, the stack will be destructed
too.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Code executed by <span class="emphasis"><em>context-function</em></span> must not prevent the
propagation ofs the <span class="emphasis"><em>detail::forced_unwind</em></span> exception.
Absorbing that exception will cause stack unwinding to fail. Thus, any code
that catches all exceptions must re-throw any pending <span class="emphasis"><em>detail::forced_unwind</em></span>
exception.
</p></td></tr>
</table></div>
<a name="cc_prealloc"></a><h4>
<a name="context.fib.h6"></a>
<span><a name="context.fib.allocating_control_structures_on_top_of_stack"></a></span><a class="link" href="fib.html#context.fib.allocating_control_structures_on_top_of_stack">Allocating
control structures on top of stack</a>
</h4>
<p>
Allocating control structures on top of the stack requires to allocated the
<span class="emphasis"><em>stack_context</em></span> and create the control structure with placement
new before <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a> is created.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The user is responsible for destructing the control structure at the top
of the stack.
</p></td></tr>
</table></div>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="comment">// stack-allocator used for (de-)allocating stack</span>
<span class="identifier">fixedsize_stack</span> <span class="identifier">salloc</span><span class="special">(</span><span class="number">4048</span><span class="special">);</span>
<span class="comment">// allocate stack space</span>
<span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">(</span><span class="identifier">salloc</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">());</span>
<span class="comment">// reserve space for control structure on top of the stack</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">=</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span><span class="special">)-</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">=</span><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">-</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_control_structure</span><span class="special">);</span>
<span class="comment">// placement new creates control structure on reserved space</span>
<span class="identifier">my_control_structure</span> <span class="special">*</span> <span class="identifier">cs</span><span class="special">=</span><span class="keyword">new</span><span class="special">(</span><span class="identifier">sp</span><span class="special">)</span><span class="identifier">my_control_structure</span><span class="special">(</span><span class="identifier">sp</span><span class="special">,</span><span class="identifier">size</span><span class="special">,</span><span class="identifier">sctx</span><span class="special">,</span><span class="identifier">salloc</span><span class="special">);</span>
<span class="special">...</span>
<span class="comment">// destructing the control structure</span>
<span class="identifier">cs</span><span class="special">-&gt;~</span><span class="identifier">my_control_structure</span><span class="special">();</span>
<span class="special">...</span>
<span class="keyword">struct</span> <span class="identifier">my_control_structure</span> <span class="special">{</span>
<span class="comment">// captured fiber</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAllocator</span> <span class="special">&gt;</span>
<span class="identifier">my_control_structure</span><span class="special">(</span><span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span><span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">,</span><span class="identifier">StackAllocator</span> <span class="identifier">salloc</span><span class="special">)</span> <span class="special">:</span>
<span class="comment">// create captured fiber</span>
<span class="identifier">f</span><span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg</span><span class="special">,</span><span class="identifier">preallocated</span><span class="special">(</span><span class="identifier">sp</span><span class="special">,</span><span class="identifier">size</span><span class="special">,</span><span class="identifier">sctx</span><span class="special">),</span><span class="identifier">salloc</span><span class="special">,</span><span class="identifier">entry_func</span><span class="special">}</span> <span class="special">{</span>
<span class="special">}</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
<h4>
<a name="context.fib.h7"></a>
<span><a name="context.fib.inverting_the_control_flow"></a></span><a class="link" href="fib.html#context.fib.inverting_the_control_flow">Inverting
the control flow</a>
</h4>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">ctx</span><span class="special">=</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">;</span>
<span class="comment">/*
* grammar:
* P ---&gt; E '\0'
* E ---&gt; T {('+'|'-') T}
* T ---&gt; S {('*'|'/') S}
* S ---&gt; digit | '(' E ')'
*/</span>
<span class="keyword">class</span> <span class="identifier">Parser</span><span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">next</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">char</span><span class="special">)&gt;</span> <span class="identifier">cb</span><span class="special">;</span>
<span class="keyword">char</span> <span class="identifier">pull</span><span class="special">(){</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;::</span><span class="identifier">to_char_type</span><span class="special">(</span><span class="identifier">is</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">scan</span><span class="special">(){</span>
<span class="keyword">do</span><span class="special">{</span>
<span class="identifier">next</span><span class="special">=</span><span class="identifier">pull</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">while</span><span class="special">(</span><span class="identifier">isspace</span><span class="special">(</span><span class="identifier">next</span><span class="special">));</span>
<span class="special">}</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">Parser</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is_</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">char</span><span class="special">)&gt;</span> <span class="identifier">cb_</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">next</span><span class="special">(),</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">is_</span><span class="special">),</span> <span class="identifier">cb</span><span class="special">(</span><span class="identifier">cb_</span><span class="special">)</span>
<span class="special">{}</span>
<span class="keyword">void</span> <span class="identifier">run</span><span class="special">()</span> <span class="special">{</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">E</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">void</span> <span class="identifier">E</span><span class="special">(){</span>
<span class="identifier">T</span><span class="special">();</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'+'</span><span class="special">||</span><span class="identifier">next</span><span class="special">==</span><span class="char">'-'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">T</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">T</span><span class="special">(){</span>
<span class="identifier">S</span><span class="special">();</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'*'</span><span class="special">||</span><span class="identifier">next</span><span class="special">==</span><span class="char">'/'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">S</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">S</span><span class="special">(){</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">isdigit</span><span class="special">(</span><span class="identifier">next</span><span class="special">)){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">else</span> <span class="keyword">if</span><span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">'('</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="identifier">E</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">next</span><span class="special">==</span><span class="char">')'</span><span class="special">){</span>
<span class="identifier">cb</span><span class="special">(</span><span class="identifier">next</span><span class="special">);</span>
<span class="identifier">scan</span><span class="special">();</span>
<span class="special">}</span><span class="keyword">else</span><span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"parsing failed"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">else</span><span class="special">{</span>
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"parsing failed"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="string">"1+1"</span><span class="special">);</span>
<span class="comment">// user-code pulls parsed data from parser</span>
<span class="comment">// invert control flow</span>
<span class="keyword">char</span> <span class="identifier">c</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">done</span><span class="special">=</span><span class="keyword">false</span><span class="special">;</span>
<span class="comment">// execute parser in new fiber</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">source</span><span class="special">{[&amp;</span><span class="identifier">is</span><span class="special">,&amp;</span><span class="identifier">c</span><span class="special">,&amp;</span><span class="identifier">done</span><span class="special">](</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">sink</span><span class="special">){</span>
<span class="comment">// create parser with callback function</span>
<span class="identifier">Parser</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span>
<span class="special">[&amp;</span><span class="identifier">sink</span><span class="special">,&amp;</span><span class="identifier">c</span><span class="special">](</span><span class="keyword">char</span> <span class="identifier">c_</span><span class="special">){</span>
<span class="comment">// resume main fiber</span>
<span class="identifier">c</span><span class="special">=</span><span class="identifier">c_</span><span class="special">;</span>
<span class="identifier">sink</span><span class="special">=</span><span class="identifier">sink</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">});</span>
<span class="comment">// start recursive parsing</span>
<span class="identifier">p</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="comment">// signal termination</span>
<span class="identifier">done</span><span class="special">=</span><span class="keyword">true</span><span class="special">;</span>
<span class="comment">// resume main fiber</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">}};</span>
<span class="identifier">source</span> <span class="special">=</span> <span class="identifier">source</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">while</span><span class="special">(!</span><span class="identifier">done</span><span class="special">){</span>
<span class="identifier">printf</span><span class="special">(</span><span class="string">"Parsed: %c\n"</span><span class="special">,</span><span class="identifier">c</span><span class="special">);</span>
<span class="identifier">source</span><span class="special">=</span><span class="identifier">source</span><span class="special">.</span><span class="identifier">resume</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="special">+</span>
<span class="identifier">Parsed</span><span class="special">:</span> <span class="number">1</span>
</pre>
<p>
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using __fiber__ the control flow can be inverted, e.g. the user-code
pulls parsed symbols from the parser - instead to get pushed from the parser
(via callback).
</p>
<p>
The data (character) is transferred between the two fibers.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="fib/implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,467 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class fiber</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../fib.html" title="Context switching with fibers">
<link rel="prev" href="implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">
<link rel="next" href="../cc.html" title="Context switching with call/cc">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../fib.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../cc.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.fib.class__fiber_"></a><a class="link" href="class__fiber_.html" title="Class fiber">Class <code class="computeroutput"><span class="identifier">fiber</span></code></a>
</h3></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">fiber</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">fiber</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
<span class="special">~</span><span class="identifier">fiber</span><span class="special">();</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="identifier">fiber</span><span class="special">(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
<span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
<span class="identifier">fiber</span> <span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span> <span class="identifier">resume_with</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">traitsT</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<h5>
<a name="fib_constructor_bridgehead"></a>
<span><a name="fib_constructor"></a></span>
<a class="link" href="class__fiber_.html#fib_constructor">Constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Creates a invalid fiber.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_destructor%20destructor_bridgehead"></a>
<span><a name="fib_destructor%20destructor"></a></span>
<a class="link" href="class__fiber_.html#fib_destructor%20destructor">Destructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="special">~</span><span class="identifier">fiber</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Destructs the associated stack if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is a valid fiber, e.g. <span class="emphasis"><em>fiber::operator
bool()</em></span> returns <code class="computeroutput"><span class="keyword">true</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_move%20constructor_bridgehead"></a>
<span><a name="fib_move%20constructor"></a></span>
<a class="link" href="class__fiber_.html#fib_move%20constructor">Move
constructor</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span><span class="special">(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves underlying capture fiber to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_move%20assignment_bridgehead"></a>
<span><a name="fib_move%20assignment"></a></span>
<a class="link" href="class__fiber_.html#fib_move%20assignment">Move
assignment operator</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">fiber</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Moves the state of <code class="computeroutput"><span class="identifier">other</span></code>
to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
using move semantics.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_call_bridgehead"></a>
<span><a name="fib_operator_call"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_call">Member function
<code class="computeroutput">operator()</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="identifier">fiber</span> <span class="identifier">resume</span><span class="special">();</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">&gt;</span>
<span class="identifier">fiber</span> <span class="identifier">resume_with</span><span class="special">(</span><span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Captures current fiber and resumes <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>. The function <code class="computeroutput"><span class="identifier">resume_with</span></code>,
is used to execute function <code class="computeroutput"><span class="identifier">fn</span></code>
in the execution context of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> (e.g. the stack frame of <code class="computeroutput"><span class="identifier">fn</span></code> is allocated on stack of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>).
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
The fiber representing the fiber that has been suspended.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
Function <code class="computeroutput"><span class="identifier">fn</span></code> needs to
return <code class="computeroutput"><span class="identifier">fiber</span></code>.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned fiber indicates if the suspended fiber has terminated
(return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_bool_bridgehead"></a>
<span><a name="fib_operator_bool"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_bool">Member function
<code class="computeroutput">operator bool</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
points to a captured fiber.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_not_bridgehead"></a>
<span><a name="fib_operator_not"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_not">Member function
<code class="computeroutput">operator!</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
does not point to a captured fiber.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_equal_bridgehead"></a>
<span><a name="fib_operator_equal"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_equal">Member function
<code class="computeroutput">operator==</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
and <code class="computeroutput"><span class="identifier">other</span></code> represent
the same fiber, <code class="computeroutput"><span class="keyword">false</span></code>
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_notequal_bridgehead"></a>
<span><a name="fib_operator_notequal"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_notequal">Member
function <code class="computeroutput">operator!=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput">! (other == * this)</code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_less_bridgehead"></a>
<span><a name="fib_operator_less"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_less">Member function
<code class="computeroutput">operator&lt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="identifier">other</span></code>
is true and the implementation-defined total order of <code class="computeroutput"><span class="identifier">fiber</span></code> values places <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
before <code class="computeroutput"><span class="identifier">other</span></code>, false
otherwise.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_greater_bridgehead"></a>
<span><a name="fib_operator_greater"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_greater">Member
function <code class="computeroutput">operator&gt;</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_lesseq_bridgehead"></a>
<span><a name="fib_operator_lesseq"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_lesseq">Member
function <code class="computeroutput">operator&lt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(</span><span class="identifier">other</span> <span class="special">&lt;</span>
<span class="special">*</span> <span class="keyword">this</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_operator_greatereq_bridgehead"></a>
<span><a name="fib_operator_greatereq"></a></span>
<a class="link" href="class__fiber_.html#fib_operator_greatereq">Member
function <code class="computeroutput">operator&gt;=</code>()</a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;=(</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="special">(*</span>
<span class="keyword">this</span> <span class="special">&lt;</span>
<span class="identifier">other</span><span class="special">)</span></code>
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<p>
</p>
<h5>
<a name="fib_bridgehead"></a>
<span><a name="fib"></a></span>
<a class="link" href="../fib.html#fib">Non-member function <code class="computeroutput">operator&lt;&lt;()</code></a>
</h5>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">charT</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">traitsT</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span>
<span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span><span class="identifier">traitsT</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span><span class="identifier">fiber</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Writes the representation of <code class="computeroutput"><span class="identifier">other</span></code>
to stream <code class="computeroutput"><span class="identifier">os</span></code>.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">os</span></code>
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementations__fcontext_t__ucontext_t_and_winfiber.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../fib.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../cc.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,108 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Implementations: fcontext_t, ucontext_t and WinFiber</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../fib.html" title="Context switching with fibers">
<link rel="prev" href="../fib.html" title="Context switching with fibers">
<link rel="next" href="class__fiber_.html" title="Class fiber">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../fib.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../fib.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="class__fiber_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber"></a><a name="implementation"></a><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html" title="Implementations: fcontext_t, ucontext_t and WinFiber">Implementations:
fcontext_t, ucontext_t and WinFiber</a>
</h3></div></div></div>
<h5>
<a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.h0"></a>
<span><a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</a>
</h5>
<p>
The implementation uses <span class="emphasis"><em>fcontext_t</em></span> per default. fcontext_t
is based on assembler and not available for all platforms. It provides a
much better performance than <span class="emphasis"><em>ucontext_t</em></span> (the context
switch takes two magnitudes of order less CPU cycles; see section <a class="link" href="../performance.html#performance"><span class="emphasis"><em>performance</em></span></a>)
and <span class="emphasis"><em>WinFiber</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Because the TIB (thread information block on Windows) is not fully described
in the MSDN, it might be possible that not all required TIB-parts are swapped.
Using WinFiber implementation migh be an alternative.
</p></td></tr>
</table></div>
<h5>
<a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.h1"></a>
<span><a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</a>
</h5>
<p>
As an alternative, <a href="https://en.wikipedia.org/wiki/Setcontext" target="_top"><span class="emphasis"><em>ucontext_t</em></span></a>
can be used by compiling with <code class="computeroutput"><span class="identifier">BOOST_USE_UCONTEXT</span></code>
and b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">ucontext</span></code>.
<span class="emphasis"><em>ucontext_t</em></span> might be available on a broader range of
POSIX-platforms but has some <a class="link" href="../rationale/other_apis_.html#ucontext"><span class="emphasis"><em>disadvantages</em></span></a>
(for instance deprecated since POSIX.1-2003, not C99 conform).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
__fiber__ supports <a class="link" href="../stack/segmented.html#segmented"><span class="emphasis"><em>Segmented stacks</em></span></a>
only with <span class="emphasis"><em>ucontext_t</em></span> as its implementation.
</p></td></tr>
</table></div>
<h5>
<a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.h2"></a>
<span><a name="context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"></a></span><a class="link" href="implementations__fcontext_t__ucontext_t_and_winfiber.html#context.fib.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</a>
</h5>
<p>
With <code class="computeroutput"><span class="identifier">BOOST_USE_WINFIB</span></code> and
b2 property <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">winfib</span></code>
Win32-Fibers are used as implementation for __fiber__.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The first call of __fiber__ converts the thread into a Windows fiber by
invoking <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code>. If desired, <code class="computeroutput"><span class="identifier">ConvertFiberToThread</span><span class="special">()</span></code> has to be called by the user explicitly
in order to release resources allocated by <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code> (e.g. after using boost.context).
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../fib.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../fib.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="class__fiber_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Overview</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="next" href="requirements.html" title="Requirements">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="requirements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.overview"></a><a class="link" href="overview.html" title="Overview">Overview</a>
</h2></div></div></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span> is a foundational library that
provides a sort of cooperative multitasking on a single thread. By providing
an abstraction of the current execution state in the current thread, including
the stack (with local variables) and stack pointer, all registers and CPU flags,
and the instruction pointer, a execution context represents a specific point
in the application's execution path. This is useful for building higher-level
abstractions, like <span class="emphasis"><em>coroutines</em></span>, <span class="emphasis"><em>cooperative threads
(userland threads)</em></span> or an equivalent to <a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx" target="_top">C#
keyword <span class="emphasis"><em>yield</em></span></a> in C++.
</p>
<p>
<a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>/<a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
provides the means to suspend the current execution path and to transfer execution
control, thereby permitting another context to run on the current thread. This
state full transfer mechanism enables a context to suspend execution from within
nested functions and, later, to resume from where it was suspended. While the
execution path represented by a <a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
only runs on a single thread, it can be migrated to another thread at any given
time.
</p>
<p>
A <a href="http://en.wikipedia.org/wiki/Context_switch" target="_top">context switch</a>
between threads requires system calls (involving the OS kernel), which can
cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring control
vias <a class="link" href="cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>/<a class="link" href="cc.html#cc"><span class="emphasis"><em>continuation</em></span></a>
requires only few CPU cycles because it does not involve system calls as it
is done within a single thread.
</p>
<p>
All functions and classes are contained in the namespace <span class="emphasis"><em>boost::context</em></span>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This library requires C++11!
</p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Windows using fcontext_t: turn off global program optimization (/GL) and
change /EHsc (compiler assumes that functions declared as extern "C"
never throw a C++ exception) to /EHs (tells compiler assumes that functions
declared as extern "C" may throw an exception).
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="requirements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Performance</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="struct__preallocated_.html" title="Struct preallocated">
<link rel="next" href="architectures.html" title="Architectures">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="struct__preallocated_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="architectures.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.performance"></a><a name="performance"></a><a class="link" href="performance.html" title="Performance">Performance</a>
</h2></div></div></div>
<p>
Performance measurements were taken using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">highresolution_clock</span></code>,
with overhead corrections. The code was compiled with gcc-6.3.1, using build
options: variant = release, optimization = speed. Tests were executed on dual
Intel XEON E5 2620v4 2.2GHz, 16C/32T, 64GB RAM, running Linux (x86_64).
</p>
<div class="table">
<a name="context.performance.performance_of_context_switch"></a><p class="title"><b>Table&#160;1.1.&#160;Performance of context switch</b></p>
<div class="table-contents"><table class="table" summary="Performance of context switch">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
callcc()/continuation (fcontext_t)
</p>
</th>
<th>
<p>
callcc()/continuation (ucontext_t)
</p>
</th>
<th>
<p>
callcc()/continuation (Windows-Fiber)
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
9 ns / 19 CPU cycles
</p>
</td>
<td>
<p>
547 ns / 1130 CPU cycles
</p>
</td>
<td>
<p>
49 ns / 98 CPU cycles
</p>
</td>
</tr></tbody>
</table></div>
</div>
<br class="table-break">
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="struct__preallocated_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="architectures.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,86 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Rationale</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="architectures/crosscompiling.html" title="Cross compiling">
<link rel="next" href="rationale/other_apis_.html" title="Other APIs">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="architectures/crosscompiling.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rationale/other_apis_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.rationale"></a><a class="link" href="rationale.html" title="Rationale">Rationale</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="rationale/other_apis_.html">Other APIs </a></span></dt>
<dt><span class="section"><a href="rationale/x86_and_floating_point_env.html">x86 and
floating-point env</a></span></dt>
</dl></div>
<h4>
<a name="context.rationale.h0"></a>
<span><a name="context.rationale.no_inline_assembler"></a></span><a class="link" href="rationale.html#context.rationale.no_inline_assembler">No
inline-assembler</a>
</h4>
<p>
Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support
inline assembler. <sup>[<a name="context.rationale.f0" href="#ftn.context.rationale.f0" class="footnote">1</a>]</sup>. Inlined assembler generates code bloating which is not welcome
on embedded systems.
</p>
<h4>
<a name="context.rationale.h1"></a>
<span><a name="context.rationale.fcontext_t"></a></span><a class="link" href="rationale.html#context.rationale.fcontext_t">fcontext_t</a>
</h4>
<p>
<span class="bold"><strong>Boost.Context</strong></span> provides the low level API fcontext_t
which is implemented in assembler to provide context swapping operations. fcontext_t
is the part to port to new platforms.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Context switches do not preserve the signal mask on UNIX systems.
</p></td></tr>
</table></div>
<p>
<span class="emphasis"><em>fcontext_t</em></span> is an opaque pointer.
</p>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.f0" href="#context.rationale.f0" class="para">1</a>] </sup>
<a href="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx" target="_top">MSDN article
'Inline Assembler'</a>
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="architectures/crosscompiling.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rationale/other_apis_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Other APIs</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../rationale.html" title="Rationale">
<link rel="prev" href="../rationale.html" title="Rationale">
<link rel="next" href="x86_and_floating_point_env.html" title="x86 and floating-point env">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../rationale.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="x86_and_floating_point_env.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.rationale.other_apis_"></a><a class="link" href="other_apis_.html" title="Other APIs">Other APIs </a>
</h3></div></div></div>
<h5>
<a name="context.rationale.other_apis_.h0"></a>
<span><a name="context.rationale.other_apis_.setjmp___longjmp__"></a></span><a class="link" href="other_apis_.html#context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</a>
</h5>
<p>
C99 defines <code class="computeroutput"><span class="identifier">setjmp</span><span class="special">()</span></code>/<code class="computeroutput"><span class="identifier">longjmp</span><span class="special">()</span></code>
to provide non-local jumps but it does not require that <span class="emphasis"><em>longjmp()</em></span>
preserves the current stack frame. Therefore, jumping into a function which
was exited via a call to <span class="emphasis"><em>longjmp()</em></span> is undefined <sup>[<a name="context.rationale.other_apis_.f0" href="#ftn.context.rationale.other_apis_.f0" class="footnote">2</a>]</sup>.
</p>
<a name="ucontext"></a><h5>
<a name="context.rationale.other_apis_.h1"></a>
<span><a name="context.rationale.other_apis_.ucontext_t"></a></span><a class="link" href="other_apis_.html#context.rationale.other_apis_.ucontext_t">ucontext_t</a>
</h5>
<p>
Since POSIX.1-2004 <code class="computeroutput"><span class="identifier">ucontext_t</span></code>
is deprecated and was removed in POSIX.1-2008! The function signature of
<code class="computeroutput"><span class="identifier">makecontext</span><span class="special">()</span></code>
is:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">makecontext</span><span class="special">(</span><span class="identifier">ucontext_t</span> <span class="special">*</span><span class="identifier">ucp</span><span class="special">,</span> <span class="keyword">void</span> <span class="special">(*</span><span class="identifier">func</span><span class="special">)(),</span> <span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="special">...);</span>
</pre>
<p>
The third argument of <code class="computeroutput"><span class="identifier">makecontext</span><span class="special">()</span></code> specifies the number of integer arguments
that follow which will require function pointer cast if <code class="computeroutput"><span class="identifier">func</span></code>
will accept those arguments which is undefined in C99 <sup>[<a name="context.rationale.other_apis_.f1" href="#ftn.context.rationale.other_apis_.f1" class="footnote">3</a>]</sup>.
</p>
<p>
The arguments in the var-arg list are required to be integers, passing pointers
in var-arg list is not guaranteed to work, especially it will fail for architectures
where pointers are larger than integers.
</p>
<p>
<code class="computeroutput"><span class="identifier">ucontext_t</span></code> preserves signal
mask between context switches which involves system calls consuming a lot
of CPU cycles (ucontext_t is slower; a context switch takes <a class="link" href="../performance.html#performance"><span class="emphasis"><em>two
magnitutes of order more CPU cycles</em></span></a> more than <span class="emphasis"><em>fcontext_t</em></span>).
</p>
<h5>
<a name="context.rationale.other_apis_.h2"></a>
<span><a name="context.rationale.other_apis_.windows_fibers"></a></span><a class="link" href="other_apis_.html#context.rationale.other_apis_.windows_fibers">Windows
fibers</a>
</h5>
<p>
A drawback of Windows Fiber API is that <code class="computeroutput"><span class="identifier">CreateFiber</span><span class="special">()</span></code> does not accept a pointer to user allocated
stack space preventing the reuse of stacks for other context instances. Because
the Windows Fiber API requires to call <code class="computeroutput"><span class="identifier">ConvertThreadToFiber</span><span class="special">()</span></code> if <code class="computeroutput"><span class="identifier">SwitchFiber</span><span class="special">()</span></code> is called for a thread which has not been
converted to a fiber. For the same reason <code class="computeroutput"><span class="identifier">ConvertFiberToThread</span><span class="special">()</span></code> must be called after return from <code class="computeroutput"><span class="identifier">SwitchFiber</span><span class="special">()</span></code>
if the thread was forced to be converted to a fiber before (which is inefficient).
</p>
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">is_a_fiber</span><span class="special">()</span> <span class="special">)</span>
<span class="special">{</span>
<span class="identifier">ConvertThreadToFiber</span><span class="special">(</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">SwitchToFiber</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">);</span>
<span class="identifier">ConvertFiberToThread</span><span class="special">();</span>
<span class="special">}</span>
</pre>
<p>
If the condition <code class="computeroutput"><span class="identifier">_WIN32_WINNT</span> <span class="special">&gt;=</span> <span class="identifier">_WIN32_WINNT_VISTA</span></code>
is met function <code class="computeroutput"><span class="identifier">IsThreadAFiber</span><span class="special">()</span></code> is provided in order to detect if the current
thread was already converted. Unfortunately Windows XP + SP 2/3 defines
<code class="computeroutput"><span class="identifier">_WIN32_WINNT</span> <span class="special">&gt;=</span>
<span class="identifier">_WIN32_WINNT_VISTA</span></code> without providing
<code class="computeroutput"><span class="identifier">IsThreadAFiber</span><span class="special">()</span></code>.
</p>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.other_apis_.f0" href="#context.rationale.other_apis_.f0" class="para">2</a>] </sup>
ISO/IEC 9899:1999, 2005, 7.13.2.1:2
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.other_apis_.f1" href="#context.rationale.other_apis_.f1" class="para">3</a>] </sup>
ISO/IEC 9899:1999, 2005, J.2
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../rationale.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="x86_and_floating_point_env.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,124 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>x86 and floating-point env</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../rationale.html" title="Rationale">
<link rel="prev" href="other_apis_.html" title="Other APIs">
<link rel="next" href="../reference.html" title="Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="other_apis_.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.rationale.x86_and_floating_point_env"></a><a class="link" href="x86_and_floating_point_env.html" title="x86 and floating-point env">x86 and
floating-point env</a>
</h3></div></div></div>
<h5>
<a name="context.rationale.x86_and_floating_point_env.h0"></a>
<span><a name="context.rationale.x86_and_floating_point_env.i386"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.i386">i386</a>
</h5>
<p>
"The FpCsr and the MxCsr register must be saved and restored before
any call or return by any procedure that needs to modify them ..."
<sup>[<a name="context.rationale.x86_and_floating_point_env.f0" href="#ftn.context.rationale.x86_and_floating_point_env.f0" class="footnote">4</a>]</sup>.
</p>
<h5>
<a name="context.rationale.x86_and_floating_point_env.h1"></a>
<span><a name="context.rationale.x86_and_floating_point_env.x86_64"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.x86_64">x86_64</a>
</h5>
<h5>
<a name="context.rationale.x86_and_floating_point_env.h2"></a>
<span><a name="context.rationale.x86_and_floating_point_env.windows"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.windows">Windows</a>
</h5>
<p>
MxCsr - "A callee that modifies any of the non-volatile fields within
MxCsr must restore them before returning to its caller. Furthermore, a caller
that has modified any of these fields must restore them to their standard
values before invoking a callee ..." <sup>[<a name="context.rationale.x86_and_floating_point_env.f1" href="#ftn.context.rationale.x86_and_floating_point_env.f1" class="footnote">5</a>]</sup>.
</p>
<p>
FpCsr - "A callee that modifies any of the fields within FpCsr must
restore them before returning to its caller. Furthermore, a caller that has
modified any of these fields must restore them to their standard values before
invoking a callee ..." <sup>[<a name="context.rationale.x86_and_floating_point_env.f2" href="#ftn.context.rationale.x86_and_floating_point_env.f2" class="footnote">6</a>]</sup>.
</p>
<p>
"The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved
across context switches. There is no explicit calling convention for these
registers." <sup>[<a name="context.rationale.x86_and_floating_point_env.f3" href="#ftn.context.rationale.x86_and_floating_point_env.f3" class="footnote">7</a>]</sup>.
</p>
<p>
"The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
<sup>[<a name="context.rationale.x86_and_floating_point_env.f4" href="#ftn.context.rationale.x86_and_floating_point_env.f4" class="footnote">8</a>]</sup>.
</p>
<p>
"XMM6-XMM15 must be preserved" <sup>[<a name="context.rationale.x86_and_floating_point_env.f5" href="#ftn.context.rationale.x86_and_floating_point_env.f5" class="footnote">9</a>]</sup>
</p>
<h5>
<a name="context.rationale.x86_and_floating_point_env.h3"></a>
<span><a name="context.rationale.x86_and_floating_point_env.sysv"></a></span><a class="link" href="x86_and_floating_point_env.html#context.rationale.x86_and_floating_point_env.sysv">SysV</a>
</h5>
<p>
"The control bits of the MxCsr register are callee-saved (preserved
across calls), while the status bits are caller-saved (not preserved). The
x87 status word register is caller-saved, whereas the x87 control word (FpCsr)
is callee-saved." <sup>[<a name="context.rationale.x86_and_floating_point_env.f6" href="#ftn.context.rationale.x86_and_floating_point_env.f6" class="footnote">10</a>]</sup>.
</p>
<div class="footnotes">
<br><hr width="100" align="left">
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f0" href="#context.rationale.x86_and_floating_point_env.f0" class="para">4</a>] </sup>
'Calling Conventions', Agner Fog
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f1" href="#context.rationale.x86_and_floating_point_env.f1" class="para">5</a>] </sup>
<a href="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx" target="_top">MSDN
article 'MxCsr'</a>
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f2" href="#context.rationale.x86_and_floating_point_env.f2" class="para">6</a>] </sup>
<a href="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx" target="_top">MSDN
article 'FpCsr'</a>
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f3" href="#context.rationale.x86_and_floating_point_env.f3" class="para">7</a>] </sup>
<a href="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx" target="_top">MSDN
article 'Legacy Floating-Point Support'</a>
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f4" href="#context.rationale.x86_and_floating_point_env.f4" class="para">8</a>] </sup>
'Calling Conventions', Agner Fog
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f5" href="#context.rationale.x86_and_floating_point_env.f5" class="para">9</a>] </sup>
<a href="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx" target="_top">MSDN
article 'Register Usage'</a>
</p></div>
<div class="footnote"><p><sup>[<a name="ftn.context.rationale.x86_and_floating_point_env.f6" href="#context.rationale.x86_and_floating_point_env.f6" class="para">10</a>] </sup>
SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4,
3.2.1
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="other_apis_.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../rationale.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,104 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Reference</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="rationale/x86_and_floating_point_env.html" title="x86 and floating-point env">
<link rel="next" href="acknowledgements.html" title="Acknowledgments">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="rationale/x86_and_floating_point_env.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.reference"></a><a class="link" href="reference.html" title="Reference">Reference</a>
</h2></div></div></div>
<h4>
<a name="context.reference.h0"></a>
<span><a name="context.reference.arm"></a></span><a class="link" href="reference.html#context.reference.arm">ARM</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
AAPCS ABI: Procedure Call Standard for the ARM Architecture
</li>
<li class="listitem">
AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
</li>
</ul></div>
<h4>
<a name="context.reference.h1"></a>
<span><a name="context.reference.mips"></a></span><a class="link" href="reference.html#context.reference.mips">MIPS</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
</li></ul></div>
<h4>
<a name="context.reference.h2"></a>
<span><a name="context.reference.powerpc32"></a></span><a class="link" href="reference.html#context.reference.powerpc32">PowerPC32</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
</li></ul></div>
<h4>
<a name="context.reference.h3"></a>
<span><a name="context.reference.powerpc64"></a></span><a class="link" href="reference.html#context.reference.powerpc64">PowerPC64</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
SYSV ABI: PowerPC User Instruction Set Architecture, Book I
</li></ul></div>
<h4>
<a name="context.reference.h4"></a>
<span><a name="context.reference.x86_32"></a></span><a class="link" href="reference.html#context.reference.x86_32">X86-32</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture
Processor Supplement
</li>
<li class="listitem">
MS PE: <a href="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx" target="_top">Calling
Conventions</a>
</li>
</ul></div>
<h4>
<a name="context.reference.h5"></a>
<span><a name="context.reference.x86_64"></a></span><a class="link" href="reference.html#context.reference.x86_64">X86-64</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor
Supplement
</li>
<li class="listitem">
MS PE: <a href="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx" target="_top">x64
Software Conventions</a>
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="rationale/x86_and_floating_point_env.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,112 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Requirements</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="overview.html" title="Overview">
<link rel="next" href="ff.html" title="Context switching with fibers">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="overview.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ff.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.requirements"></a><a class="link" href="requirements.html" title="Requirements">Requirements</a>
</h2></div></div></div>
<p>
If <span class="bold"><strong>Boost.Context</strong></span> uses fcontext_t (the default)
as its implementation, it must be built for the particular compiler(s) and
CPU architecture(s) being targeted. Using <a class="link" href="ff/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>fcontext_t</em></span></a>,
<span class="bold"><strong>Boost.Context</strong></span> includes assembly code and,
therefore, requires GNU as and GNU preprocessor for supported POSIX systems,
MASM for Windows/x86 systems and ARMasm for Windows/arm systems.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit.
</p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Please note that <code class="computeroutput"><span class="identifier">address</span><span class="special">-</span><span class="identifier">model</span><span class="special">=</span><span class="number">64</span></code> must be
given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit
code will be generated.
</p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
For cross-compiling the lib you must specify certain additional properties
at bjam command line: <code class="computeroutput"><span class="identifier">target</span><span class="special">-</span><span class="identifier">os</span></code>, <code class="computeroutput"><span class="identifier">abi</span></code>, <code class="computeroutput"><span class="identifier">binary</span><span class="special">-</span><span class="identifier">format</span></code>,
<code class="computeroutput"><span class="identifier">architecture</span></code> and <code class="computeroutput"><span class="identifier">address</span><span class="special">-</span><span class="identifier">model</span></code>.
</p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must
be specified at bjam command line.
</p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Windows using fcontext_t: turn off global program optimization (/GL) and
change /EHsc (compiler assumes that functions declared as extern "C"
never throw a C++ exception) to /EHs (tells compiler assumes that functions
declared as extern "C" may throw an exception).
</p></td></tr>
</table></div>
<p>
Because this library uses C++11 extensively, it requires a compatible compiler.
Known minimum working versions are as follows: Microsoft Visual Studio 2015
(msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other
compilers may work, if they support the following language features: auto declarations,
constexpr, defaulted functions, final, hdr thread, hdr tuple, lambdas, noexcept,
nullptr, rvalue references, template aliases. thread local, variadic templates.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="overview.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="ff.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,177 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Stack allocation</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="cc/class__continuation_.html" title="Class continuation">
<link rel="next" href="stack/protected_fixedsize.html" title="Class protected_fixedsize">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cc/class__continuation_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack/protected_fixedsize.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.stack"></a><a name="stack"></a><a class="link" href="stack.html" title="Stack allocation">Stack allocation</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="stack/protected_fixedsize.html">Class <span class="emphasis"><em>protected_fixedsize</em></span></a></span></dt>
<dt><span class="section"><a href="stack/pooled_fixedsize.html">Class <span class="emphasis"><em>pooled_fixedsize_stack</em></span></a></span></dt>
<dt><span class="section"><a href="stack/fixedsize.html">Class <span class="emphasis"><em>fixedsize_stack</em></span></a></span></dt>
<dt><span class="section"><a href="stack/segmented.html">Class
<span class="emphasis"><em>segmented_stack</em></span></a></span></dt>
<dt><span class="section"><a href="stack/stack_traits.html">Class <span class="emphasis"><em>stack_traits</em></span></a></span></dt>
<dt><span class="section"><a href="stack/stack_context.html">Class <span class="emphasis"><em>stack_context</em></span></a></span></dt>
<dt><span class="section"><a href="stack/valgrind.html">Support for valgrind</a></span></dt>
<dt><span class="section"><a href="stack/sanitizers.html">Support for sanitizers</a></span></dt>
</dl></div>
<p>
The memory used by the stack is allocated/deallocated via a <span class="emphasis"><em>StackAllocator</em></span>
which is required to model a <span class="emphasis"><em>stack-allocator concept</em></span>.
</p>
<h4>
<a name="context.stack.h0"></a>
<span><a name="context.stack._emphasis_stack_allocator_concept__emphasis_"></a></span><a class="link" href="stack.html#context.stack._emphasis_stack_allocator_concept__emphasis_"><span class="emphasis"><em>stack-allocator
concept</em></span></a>
</h4>
<p>
A <span class="emphasis"><em>StackAllocator</em></span> must satisfy the <span class="emphasis"><em>stack-allocator
concept</em></span> requirements shown in the following table, in which <code class="computeroutput"><span class="identifier">a</span></code> is an object of a <span class="emphasis"><em>StackAllocator</em></span>
type, <code class="computeroutput"><span class="identifier">sctx</span></code> is a <code class="computeroutput"><span class="identifier">stack_context</span></code>, and <code class="computeroutput"><span class="identifier">size</span></code>
is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>:
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
expression
</p>
</th>
<th>
<p>
return type
</p>
</th>
<th>
<p>
notes
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">a</span><span class="special">(</span><span class="identifier">size</span><span class="special">)</span></code>
</p>
</td>
<td>
</td>
<td>
<p>
creates a stack allocator
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">()</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">stack_context</span></code>
</p>
</td>
<td>
<p>
creates a stack
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">deallocate</span><span class="special">(</span>
<span class="identifier">sctx</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="keyword">void</span></code>
</p>
</td>
<td>
<p>
deallocates the stack created by <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">allocate</span><span class="special">()</span></code>
</p>
</td>
</tr>
</tbody>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
The implementation of <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code> might include logic to protect against
exceeding the context's available stack size rather than leaving it as undefined
behaviour.
</p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Calling <code class="computeroutput"><span class="identifier">deallocate</span><span class="special">()</span></code>
with a <code class="computeroutput"><span class="identifier">stack_context</span></code> not
set by <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code>
results in undefined behaviour.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Depending on the architecture <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code> stores an address from the top of the stack
(growing downwards) or the bottom of the stack (growing upwards).
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cc/class__continuation_.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack/protected_fixedsize.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,109 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class fixedsize_stack</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="pooled_fixedsize.html" title="Class pooled_fixedsize_stack">
<link rel="next" href="segmented.html" title="Class segmented_stack">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="pooled_fixedsize.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="segmented.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.fixedsize"></a><a class="link" href="fixedsize.html" title="Class fixedsize_stack">Class <span class="emphasis"><em>fixedsize_stack</em></span></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span> provides the class <span class="emphasis"><em>fixedsize_stack</em></span>
which models the <span class="emphasis"><em>stack-allocator concept</em></span>. In contrast
to <span class="emphasis"><em>protected_fixedsize_stack</em></span> it does not append a guard
page at the end of each stack. The memory is simply managed by <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">malloc</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">free</span><span class="special">()</span></code>.
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">fixedsize_stack</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">basic_fixedsize_stack</span> <span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">traitT</span> <span class="identifier">traits_type</span><span class="special">;</span>
<span class="identifier">basic_fixesize_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">());</span>
<span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
<span class="special">}</span>
<span class="keyword">typedef</span> <span class="identifier">basic_fixedsize_stack</span><span class="special">&lt;</span> <span class="identifier">stack_traits</span> <span class="special">&gt;</span> <span class="identifier">fixedsize_stack</span><span class="special">;</span>
</pre>
<h5>
<a name="context.stack.fixedsize.h0"></a>
<span><a name="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="fixedsize.html#context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&lt;=</span> <span class="identifier">size</span></code>
and <code class="computeroutput"><span class="special">!</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">&amp;&amp;</span>
<span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Allocates memory of at least <code class="computeroutput"><span class="identifier">size</span></code>
Bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
(the stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.fixedsize.h1"></a>
<span><a name="context.stack.fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="fixedsize.html#context.stack.fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
<span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span></code> and <code class="computeroutput"><span class="special">!</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span>
<span class="special">&amp;&amp;</span> <span class="special">(</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&gt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Deallocates the stack space.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="pooled_fixedsize.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="segmented.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,137 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class pooled_fixedsize_stack</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="protected_fixedsize.html" title="Class protected_fixedsize">
<link rel="next" href="fixedsize.html" title="Class fixedsize_stack">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="protected_fixedsize.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="fixedsize.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.pooled_fixedsize"></a><a class="link" href="pooled_fixedsize.html" title="Class pooled_fixedsize_stack">Class <span class="emphasis"><em>pooled_fixedsize_stack</em></span></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span> provides the class <span class="emphasis"><em>pooled_fixedsize_stack</em></span>
which models the <span class="emphasis"><em>stack-allocator concept</em></span>. In contrast
to <span class="emphasis"><em>protected_fixedsize_stack</em></span> it does not append a guard
page at the end of each stack. The memory is managed internally by <a href="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">pool</span><span class="special">&lt;&gt;</span></code></a>.
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">pooled_fixedsize_stack</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">basic_pooled_fixedsize_stack</span> <span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">traitT</span> <span class="identifier">traits_type</span><span class="special">;</span>
<span class="identifier">basic_pooled_fixedsize_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">stack_size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">next_size</span> <span class="special">=</span> <span class="number">32</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">max_size</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
<span class="special">}</span>
<span class="keyword">typedef</span> <span class="identifier">basic_pooled_fixedsize_stack</span><span class="special">&lt;</span> <span class="identifier">stack_traits</span> <span class="special">&gt;</span> <span class="identifier">pooled_fixedsize_stack</span><span class="special">;</span>
</pre>
<h5>
<a name="context.stack.pooled_fixedsize.h0"></a>
<span><a name="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="identifier">basic_pooled_fixedsize_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
<span class="identifier">stack_size</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">next_size</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">max_size</span><span class="special">)</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">&amp;&amp;</span>
<span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="identifier">stack_size</span><span class="special">)</span></code>
and <code class="computeroutput"><span class="number">0</span> <span class="special">&lt;</span>
<span class="identifier">nest_size</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Allocates memory of at least <code class="computeroutput"><span class="identifier">stack_size</span></code>
Bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
(the stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack. Argument <code class="computeroutput"><span class="identifier">next_size</span></code>
determines the number of stacks to request from the system the first
time that <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
needs to allocate system memory. The third argument <code class="computeroutput"><span class="identifier">max_size</span></code>
controls how many memory might be allocated for stacks - a value of
zero means no uper limit.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.pooled_fixedsize.h1"></a>
<span><a name="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="special">!</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">&amp;&amp;</span>
<span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="identifier">stack_size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Allocates memory of at least <code class="computeroutput"><span class="identifier">stack_size</span></code>
Bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
(the stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.pooled_fixedsize.h2"></a>
<span><a name="context.stack.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#context.stack.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
<span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="special">!</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span>
<span class="special">&amp;&amp;</span> <span class="special">(</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&gt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Deallocates the stack space.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="protected_fixedsize.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="fixedsize.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,132 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class protected_fixedsize</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="../stack.html" title="Stack allocation">
<link rel="next" href="pooled_fixedsize.html" title="Class pooled_fixedsize_stack">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../stack.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="pooled_fixedsize.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.protected_fixedsize"></a><a class="link" href="protected_fixedsize.html" title="Class protected_fixedsize">Class <span class="emphasis"><em>protected_fixedsize</em></span></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span> provides the class <span class="emphasis"><em>protected_fixedsize_stack</em></span>
which models the <span class="emphasis"><em>stack-allocator concept</em></span>. It appends
a guard page at the end of each stack to protect against exceeding the stack.
If the guard page is accessed (read or write operation) a segmentation fault/access
violation is generated by the operating system.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
Using <span class="emphasis"><em>protected_fixedsize_stack</em></span> is expensive. That
is, launching a new coroutine with a new stack is expensive; the allocated
stack is just as efficient to use as any other stack.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The appended <code class="computeroutput"><span class="identifier">guard</span> <span class="identifier">page</span></code>
is <span class="bold"><strong>not</strong></span> mapped to physical memory, only
virtual addresses are used.
</p></td></tr>
</table></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">protected_fixedsize</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">basic_protected_fixedsize</span> <span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">traitT</span> <span class="identifier">traits_type</span><span class="special">;</span>
<span class="identifier">basic_protected_fixesize</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">());</span>
<span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
<span class="special">}</span>
<span class="keyword">typedef</span> <span class="identifier">basic_protected_fixedsize</span><span class="special">&lt;</span> <span class="identifier">stack_traits</span> <span class="special">&gt;</span> <span class="identifier">protected_fixedsize</span>
</pre>
<h5>
<a name="context.stack.protected_fixedsize.h0"></a>
<span><a name="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="protected_fixedsize.html#context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&lt;=</span> <span class="identifier">size</span></code>
and <code class="computeroutput"><span class="special">!</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">&amp;&amp;</span>
<span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Allocates memory of at least <code class="computeroutput"><span class="identifier">size</span></code>
Bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
(the stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.protected_fixedsize.h1"></a>
<span><a name="context.stack.protected_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="protected_fixedsize.html#context.stack.protected_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
<span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span></code> and <code class="computeroutput"><span class="special">!</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span>
<span class="special">&amp;&amp;</span> <span class="special">(</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&gt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Deallocates the stack space.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../stack.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="pooled_fixedsize.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,49 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Support for sanitizers</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="valgrind.html" title="Support for valgrind">
<link rel="next" href="../struct__preallocated_.html" title="Struct preallocated">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="valgrind.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../struct__preallocated_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.sanitizers"></a><a class="link" href="sanitizers.html" title="Support for sanitizers">Support for sanitizers</a>
</h3></div></div></div>
<p>
Sanitizers (GCC/Clang) are confused by the stack switches. The library is
required to be compiled with property (b2 command-line) <code class="computeroutput"><span class="identifier">context</span><span class="special">-</span><span class="identifier">impl</span><span class="special">=</span><span class="identifier">ucontext</span></code> and compilers santizer options.
Users must define <code class="computeroutput"><span class="identifier">BOOST_USE_ASAN</span></code>
before including any Boost.Context headers when linking against Boost binaries.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="valgrind.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../struct__preallocated_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,151 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class segmented_stack</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="fixedsize.html" title="Class fixedsize_stack">
<link rel="next" href="stack_traits.html" title="Class stack_traits">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="fixedsize.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack_traits.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.segmented"></a><a name="segmented"></a><a class="link" href="segmented.html" title="Class segmented_stack">Class
<span class="emphasis"><em>segmented_stack</em></span></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span> supports usage of a <a class="link" href="segmented.html#segmented"><span class="emphasis"><em>segmented_stack</em></span></a>, e. g. the
size of the stack grows on demand. The coroutine is created with a minimal
stack size and will be increased as required. Class <a class="link" href="segmented.html#segmented"><span class="emphasis"><em>segmented_stack</em></span></a>
models the <span class="emphasis"><em>stack-allocator concept</em></span>. In contrast to
<span class="emphasis"><em>protected_fixedsize_stack</em></span> and <span class="emphasis"><em>fixedsize_stack</em></span>
it creates a stack which grows on demand.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Segmented stacks are currently only supported by <span class="bold"><strong>gcc</strong></span>
from version <span class="bold"><strong>4.7</strong></span> <span class="bold"><strong>clang</strong></span>
from version <span class="bold"><strong>3.4</strong></span> onwards. In order to
use a <span class="emphasis"><em>segmented_stack</em></span> <span class="bold"><strong>Boost.Context</strong></span>
must be built with property <code class="computeroutput"><span class="identifier">segmented</span><span class="special">-</span><span class="identifier">stacks</span></code>,
e.g. <span class="bold"><strong>toolset=gcc segmented-stacks=on</strong></span> and
applying <code class="computeroutput"><span class="identifier">BOOST_USE_SEGMENTED_STACKS</span></code>
at b2/bjam command line.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Segmented stacks can only be used with <a class="link" href="../cc.html#cc"><span class="emphasis"><em>callcc()</em></span></a>
(using <a class="link" href="../ff/implementations__fcontext_t__ucontext_t_and_winfiber.html#implementation"><span class="emphasis"><em>ucontext_t</em></span></a>)
</p></td></tr>
</table></div>
<p>
.
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">segmented_stack</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">traitsT</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">basic_segmented_stack</span> <span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">traitT</span> <span class="identifier">traits_type</span><span class="special">;</span>
<span class="identifier">basic_segmented_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">());</span>
<span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
<span class="special">}</span>
<span class="keyword">typedef</span> <span class="identifier">basic_segmented_stack</span><span class="special">&lt;</span> <span class="identifier">stack_traits</span> <span class="special">&gt;</span> <span class="identifier">segmented_stack</span><span class="special">;</span>
</pre>
<h5>
<a name="context.stack.segmented.h0"></a>
<span><a name="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="segmented.html#context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&lt;=</span> <span class="identifier">size</span></code>
and <code class="computeroutput"><span class="special">!</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">&amp;&amp;</span>
<span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Allocates memory of at least <code class="computeroutput"><span class="identifier">size</span></code>
Bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
(the stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.segmented.h1"></a>
<span><a name="context.stack.segmented._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="segmented.html#context.stack.segmented._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
<span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span></code> and <code class="computeroutput"><span class="special">!</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span>
<span class="special">&amp;&amp;</span> <span class="special">(</span>
<span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span>
<span class="special">&gt;=</span> <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
</p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Deallocates the stack space.
</p></dd>
</dl>
</div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
If the library is compiled for segmented stacks, <span class="emphasis"><em>segmented_stack</em></span>
is the only available stack allocator.
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="fixedsize.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack_traits.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,84 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class stack_context</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="stack_traits.html" title="Class stack_traits">
<link rel="next" href="valgrind.html" title="Support for valgrind">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stack_traits.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="valgrind.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.stack_context"></a><a class="link" href="stack_context.html" title="Class stack_context">Class <span class="emphasis"><em>stack_context</em></span></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Context</strong></span> provides the class <span class="emphasis"><em>stack_context</em></span>
which will contain the stack pointer and the size of the stack. In case of
a <a class="link" href="segmented.html#segmented"><span class="emphasis"><em>segmented_stack</em></span></a>,
<span class="emphasis"><em>stack_context</em></span> contains some extra control structures.
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">stack_context</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">;</span>
<span class="comment">// might contain additional control structures</span>
<span class="comment">// for segmented stacks</span>
<span class="special">}</span>
</pre>
<h5>
<a name="context.stack.stack_context.h0"></a>
<span><a name="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"></a></span><a class="link" href="stack_context.html#context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Value:</span></dt>
<dd><p>
Pointer to the beginning of the stack.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.stack_context.h1"></a>
<span><a name="context.stack.stack_context._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"></a></span><a class="link" href="stack_context.html#context.stack.stack_context._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>
<span class="identifier">size</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Value:</span></dt>
<dd><p>
Actual size of the stack.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stack_traits.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="valgrind.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,157 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class stack_traits</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="segmented.html" title="Class segmented_stack">
<link rel="next" href="stack_context.html" title="Class stack_context">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="segmented.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack_context.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.stack_traits"></a><a class="link" href="stack_traits.html" title="Class stack_traits">Class <span class="emphasis"><em>stack_traits</em></span></a>
</h3></div></div></div>
<p>
<span class="emphasis"><em>stack_traits</em></span> models a <span class="emphasis"><em>stack-traits</em></span>
providing a way to access certain properites defined by the enironment. Stack
allocators use <span class="emphasis"><em>stack-traits</em></span> to allocate stacks.
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">stack_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">stack_traits</span> <span class="special">{</span>
<span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">is_unbounded</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">page_size</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">default_size</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">minimum_size</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">maximum_size</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<h5>
<a name="context.stack.stack_traits.h0"></a>
<span><a name="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_unbounded__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_traits.html#context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_unbounded__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">is_unbounded</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
Returns <code class="computeroutput"><span class="keyword">true</span></code> if the environment
defines no limit for the size of a stack.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.stack_traits.h1"></a>
<span><a name="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_size__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_traits.html#context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_size__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">page_size</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
Returns the page size in bytes.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.stack_traits.h2"></a>
<span><a name="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_size__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_traits.html#context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_size__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">default_size</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
Returns a default stack size, which may be platform specific. If the
stack is unbounded then the present implementation returns the maximum
of <code class="computeroutput"><span class="number">64</span> <span class="identifier">kB</span></code>
and <code class="computeroutput"><span class="identifier">minimum_size</span><span class="special">()</span></code>.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.stack_traits.h3"></a>
<span><a name="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_size__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_traits.html#context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_size__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">minimum_size</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
Returns the minimum size in bytes of stack defined by the environment
(Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
<h5>
<a name="context.stack.stack_traits.h4"></a>
<span><a name="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_size__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="stack_traits.html#context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_size__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">maximum_size</span><span class="special">()</span></code></a>
</h5>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
<code class="computeroutput"><span class="identifier">is_unbounded</span><span class="special">()</span></code>
returns <code class="computeroutput"><span class="keyword">false</span></code>.
</p></dd>
<dt><span class="term">Returns:</span></dt>
<dd><p>
Returns the maximum size in bytes of stack defined by the environment.
</p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
Nothing.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="segmented.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stack_context.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,51 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Support for valgrind</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../stack.html" title="Stack allocation">
<link rel="prev" href="stack_context.html" title="Class stack_context">
<link rel="next" href="sanitizers.html" title="Support for sanitizers">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stack_context.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="sanitizers.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="context.stack.valgrind"></a><a class="link" href="valgrind.html" title="Support for valgrind">Support for valgrind</a>
</h3></div></div></div>
<p>
Running programs that switch stacks under valgrind causes problems. Property
(b2 command-line) <code class="computeroutput"><span class="identifier">valgrind</span><span class="special">=</span><span class="identifier">on</span></code> let
valgrind treat the memory regions as stack space which suppresses the errors.
Users must define <code class="computeroutput"><span class="identifier">BOOST_USE_VALGRIND</span></code>
before including any Boost.Context headers when linking against Boost binaries
compiled with <code class="computeroutput"><span class="identifier">valgrind</span><span class="special">=</span><span class="identifier">on</span></code>.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stack_context.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stack.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="sanitizers.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,66 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Struct preallocated</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Context">
<link rel="prev" href="stack/sanitizers.html" title="Support for sanitizers">
<link rel="next" href="performance.html" title="Performance">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stack/sanitizers.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="performance.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="context.struct__preallocated_"></a><a class="link" href="struct__preallocated_.html" title="Struct preallocated">Struct <code class="computeroutput"><span class="identifier">preallocated</span></code></a>
</h2></div></div></div>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">preallocated</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">;</span>
<span class="identifier">stack_context</span> <span class="identifier">sctx</span><span class="special">;</span>
<span class="identifier">preallocated</span><span class="special">(</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">,</span> <span class="identifier">std</span><span class="special">:</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">stack_allocator</span> <span class="identifier">sctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<h4>
<a name="context.struct__preallocated_.h0"></a>
<span><a name="context.struct__preallocated_.constructor"></a></span><a class="link" href="struct__preallocated_.html#context.struct__preallocated_.constructor">Constructor</a>
</h4>
<pre class="programlisting"><span class="identifier">preallocated</span><span class="special">(</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">sp</span><span class="special">,</span> <span class="identifier">std</span><span class="special">:</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">stack_allocator</span> <span class="identifier">sctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
Creates an object of preallocated.
</p></dd>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Oliver Kowalke<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="stack/sanitizers.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="performance.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,27 @@
index.html
context/overview.html
context/requirements.html
context/ff.html
context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html
context/ff/class__fiber_.html
context/cc.html
context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html
context/cc/class__continuation_.html
context/stack.html
context/stack/protected_fixedsize.html
context/stack/pooled_fixedsize.html
context/stack/fixedsize.html
context/stack/segmented.html
context/stack/stack_traits.html
context/stack/stack_context.html
context/stack/valgrind.html
context/stack/sanitizers.html
context/struct__preallocated_.html
context/performance.html
context/architectures.html
context/architectures/crosscompiling.html
context/rationale.html
context/rationale/other_apis_.html
context/rationale/x86_and_floating_point_env.html
context/reference.html
context/acknowledgements.html

View File

@@ -0,0 +1,87 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Chapter&#160;1.&#160;Context</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="index.html" title="Chapter&#160;1.&#160;Context">
<link rel="next" href="context/overview.html" title="Overview">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="context/overview.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
<div class="chapter">
<div class="titlepage"><div>
<div><h2 class="title">
<a name="context"></a>Chapter&#160;1.&#160;Context</h2></div>
<div><div class="author"><h3 class="author">
<span class="firstname">Oliver</span> <span class="surname">Kowalke</span>
</h3></div></div>
<div><p class="copyright">Copyright &#169; 2014 Oliver Kowalke</p></div>
<div><div class="legalnotice">
<a name="context.legal"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></div>
</div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="context/overview.html">Overview</a></span></dt>
<dt><span class="section"><a href="context/requirements.html">Requirements</a></span></dt>
<dt><span class="section"><a href="context/ff.html">Context switching with fibers</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="context/ff/implementations__fcontext_t__ucontext_t_and_winfiber.html">Implementations:
fcontext_t, ucontext_t and WinFiber</a></span></dt>
<dt><span class="section"><a href="context/ff/class__fiber_.html">Class <code class="computeroutput"><span class="identifier">fiber</span></code></a></span></dt>
</dl></dd>
<dt><span class="section"><a href="context/cc.html">Context switching with call/cc</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="context/cc/implementations__fcontext_t__ucontext_t_and_winfiber.html">Implementations:
fcontext_t, ucontext_t and WinFiber</a></span></dt>
<dt><span class="section"><a href="context/cc/class__continuation_.html">Class <code class="computeroutput"><span class="identifier">continuation</span></code></a></span></dt>
</dl></dd>
<dt><span class="section"><a href="context/stack.html">Stack allocation</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="context/stack/protected_fixedsize.html">Class <span class="emphasis"><em>protected_fixedsize</em></span></a></span></dt>
<dt><span class="section"><a href="context/stack/pooled_fixedsize.html">Class <span class="emphasis"><em>pooled_fixedsize_stack</em></span></a></span></dt>
<dt><span class="section"><a href="context/stack/fixedsize.html">Class <span class="emphasis"><em>fixedsize_stack</em></span></a></span></dt>
<dt><span class="section"><a href="context/stack/segmented.html">Class
<span class="emphasis"><em>segmented_stack</em></span></a></span></dt>
<dt><span class="section"><a href="context/stack/stack_traits.html">Class <span class="emphasis"><em>stack_traits</em></span></a></span></dt>
<dt><span class="section"><a href="context/stack/stack_context.html">Class <span class="emphasis"><em>stack_context</em></span></a></span></dt>
<dt><span class="section"><a href="context/stack/valgrind.html">Support for valgrind</a></span></dt>
<dt><span class="section"><a href="context/stack/sanitizers.html">Support for sanitizers</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="context/struct__preallocated_.html">Struct <code class="computeroutput"><span class="identifier">preallocated</span></code></a></span></dt>
<dt><span class="section"><a href="context/performance.html">Performance</a></span></dt>
<dt><span class="section"><a href="context/architectures.html">Architectures</a></span></dt>
<dd><dl><dt><span class="section"><a href="context/architectures/crosscompiling.html">Cross compiling</a></span></dt></dl></dd>
<dt><span class="section"><a href="context/rationale.html">Rationale</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="context/rationale/other_apis_.html">Other APIs </a></span></dt>
<dt><span class="section"><a href="context/rationale/x86_and_floating_point_env.html">x86 and
floating-point env</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="context/reference.html">Reference</a></span></dt>
<dt><span class="section"><a href="context/acknowledgements.html">Acknowledgments</a></span></dt>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: October 02, 2019 at 06:15:46 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="context/overview.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
</body>
</html>

View File

@@ -0,0 +1,41 @@
[/
Copyright Oliver Kowalke 2014.
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:overview Overview]
__boost_context__ is a foundational library that provides a sort of cooperative
multitasking on a single thread. By providing an abstraction of the current
execution state in the current thread, including the stack (with local
variables) and stack pointer, all registers and CPU flags, and the instruction
pointer, a execution context represents a specific point in the application's
execution path. This is useful for building higher-level abstractions, like
__coroutines__, __coop_threads__ or an equivalent to
[@http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx C# keyword __yield__]
in C++.
__cc__/__con__ provides the means to suspend the current execution path and to
transfer execution control, thereby permitting another context to run on the
current thread. This state full transfer mechanism enables a context to suspend
execution from within nested functions and, later, to resume from where it was
suspended. While the execution path represented by a __con__ only runs on a
single thread, it can be migrated to another thread at any given time.
A [@http://en.wikipedia.org/wiki/Context_switch context switch] between threads
requires system calls (involving the OS kernel), which can cost more than
thousand CPU cycles on x86 CPUs. By contrast, transferring control vias
__cc__/__con__ requires only few CPU cycles because it does not involve system
calls as it is done within a single thread.
All functions and classes are contained in the namespace __context_ns__.
[note This library requires C++11!]
[important Windows using fcontext_t: turn off global program optimization (/GL) and change /EHsc (compiler
assumes that functions declared as extern "C" never throw a C++ exception) to /EHs (tells
compiler assumes that functions declared as extern "C" may throw an exception).]
[endsect]

View File

@@ -0,0 +1,28 @@
[/
Copyright Oliver Kowalke 2014.
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
]
[#performance]
[section:performance Performance]
Performance measurements were taken using `std::chrono::highresolution_clock`,
with overhead corrections.
The code was compiled with gcc-6.3.1, using build options:
variant = release, optimization = speed.
Tests were executed on dual Intel XEON E5 2620v4 2.2GHz, 16C/32T, 64GB RAM,
running Linux (x86_64).
[table Performance of context switch
[[callcc()/continuation (fcontext_t)] [callcc()/continuation (ucontext_t)] [callcc()/continuation (Windows-Fiber)]]
[
[9 ns / 19 CPU cycles]
[547 ns / 1130 CPU cycles]
[49 ns / 98 CPU cycles]
]
]
[endsect]

View File

@@ -0,0 +1,27 @@
[/
Copyright Oliver Kowalke 2014.
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 Struct `preallocated`]
struct preallocated {
void * sp;
std::size_t size;
stack_context sctx;
preallocated( void * sp, std:size_t size, stack_allocator sctx) noexcept;
};
[heading Constructor]
preallocated( void * sp, std:size_t size, stack_allocator sctx) noexcept;
[variablelist
[[Effects:] [Creates an object of preallocated.]]
]
[endsect]

View File

@@ -0,0 +1,137 @@
[/
Copyright Oliver Kowalke 2014.
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:rationale Rationale]
[heading No inline-assembler]
Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not
support inline assembler.
[footnote [@http://msdn.microsoft.com/en-us/library/4ks26t93.aspx MSDN article
'Inline Assembler']].
Inlined assembler generates code bloating which is not welcome on embedded
systems.
[heading fcontext_t]
__boost_context__ provides the low level API fcontext_t which is
implemented in assembler to provide context swapping operations.
fcontext_t is the part to port to new platforms.
[note Context switches do not preserve the signal mask on UNIX systems.]
__fcontext__ is an opaque pointer.
[section Other APIs ]
[heading setjmp()/longjmp()]
C99 defines `setjmp()`/`longjmp()` to provide non-local jumps but it does not
require that ['longjmp()] preserves the current stack frame. Therefore, jumping
into a function which was exited via a call to ['longjmp()] is undefined
[footnote ISO/IEC 9899:1999, 2005, 7.13.2.1:2].
[#ucontext]
[heading ucontext_t]
Since POSIX.1-2004 `ucontext_t` is deprecated and was removed in POSIX.1-2008!
The function signature of `makecontext()` is:
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
The third argument of `makecontext()` specifies the number of integer arguments
that follow which will require function pointer cast if `func` will accept those
arguments which is undefined in C99
[footnote ISO/IEC 9899:1999, 2005, J.2].
The arguments in the var-arg list are required to be integers, passing pointers
in var-arg list is not guaranteed to work, especially it will fail for
architectures where pointers are larger than integers.
`ucontext_t` preserves signal mask between context switches which involves system
calls consuming a lot of CPU cycles (ucontext_t is slower; a context switch
takes [link performance ['two magnitutes of order more CPU cycles]] more than
__fcontext__).
[heading Windows fibers]
A drawback of Windows Fiber API is that `CreateFiber()` does not accept a
pointer to user allocated stack space preventing the reuse of stacks for other
context instances. Because the Windows Fiber API requires to call
`ConvertThreadToFiber()` if `SwitchFiber()` is called for a thread which has not
been converted to a fiber. For the same reason `ConvertFiberToThread()`
must be called after return from `SwitchFiber()` if the thread was forced to be
converted to a fiber before (which is inefficient).
if ( ! is_a_fiber() )
{
ConvertThreadToFiber( 0);
SwitchToFiber( ctx);
ConvertFiberToThread();
}
If the condition `_WIN32_WINNT >= _WIN32_WINNT_VISTA` is met function
`IsThreadAFiber()` is provided in order to detect if the current thread was
already converted. Unfortunately Windows XP + SP 2/3 defines
`_WIN32_WINNT >= _WIN32_WINNT_VISTA` without providing `IsThreadAFiber()`.
[endsect]
[section x86 and floating-point env]
[heading i386]
"The FpCsr and the MxCsr register must be saved and restored before any call or return
by any procedure that needs to modify them ..."
[footnote 'Calling Conventions', Agner Fog].
[heading x86_64]
[heading Windows]
MxCsr - "A callee that modifies any of the non-volatile fields within MxCsr must restore
them before returning to its caller. Furthermore, a caller that has modified any
of these fields must restore them to their standard values before invoking a callee ..."
[footnote [@http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx MSDN article
'MxCsr']].
FpCsr - "A callee that modifies any of the fields within FpCsr must restore them before
returning to its caller. Furthermore, a caller that has modified any of these
fields must restore them to their standard values before invoking a callee ..."
[footnote [@http://http://msdn.microsoft.com/en-us/library/ms235300.aspx MSDN article
'FpCsr']].
"The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across
context switches. There is no explicit calling convention for these registers."
[footnote [@http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx MSDN article
'Legacy Floating-Point Support']].
"The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
[footnote 'Calling Conventions', Agner Fog].
"XMM6-XMM15 must be preserved"
[footnote [@http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx MSDN
article 'Register Usage']]
[heading SysV]
"The control bits of the MxCsr register are callee-saved (preserved across calls),
while the status bits are caller-saved (not preserved). The x87 status word register is
caller-saved, whereas the x87 control word (FpCsr) is callee-saved."
[footnote SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, 3.2.1].
[endsect]
[endsect]

View File

@@ -0,0 +1,43 @@
[/
Copyright Oliver Kowalke 2014.
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:reference Reference]
[heading ARM]
* AAPCS ABI: Procedure Call Standard for the ARM Architecture
* AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
[heading MIPS]
* O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
[heading PowerPC32]
* SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
[heading PowerPC64]
* SYSV ABI: PowerPC User Instruction Set Architecture, Book I
[heading X86-32]
* SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture Processor Supplement
* MS PE: [@http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx Calling Conventions]
[heading X86-64]
* SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor Supplement
* MS PE: [@http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx x64 Software Conventions]
[endsect]

View File

@@ -0,0 +1,41 @@
[/
Copyright Oliver Kowalke 2014.
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:requirements Requirements]
If __boost_context__ uses fcontext_t (the default) as its implementation,
it must be built for the particular compiler(s) and CPU architecture(s)
being targeted.
Using [link implementation ['fcontext_t]], __boost_context__ includes assembly
code and, therefore, requires GNU as and GNU preprocessor for supported POSIX
systems, MASM for Windows/x86 systems and ARMasm for Windows/arm systems.
[note MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit.]
[important Please note that `address-model=64` must be given to bjam command
line on 64bit Windows for 64bit build; otherwise 32bit code will be generated.]
[important For cross-compiling the lib you must specify certain additional
properties at bjam command line: `target-os`, `abi`, `binary-format`,
`architecture` and `address-model`.]
[important Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must be specified at
bjam command line.]
[important Windows using fcontext_t: turn off global program optimization (/GL) and change /EHsc (compiler
assumes that functions declared as extern "C" never throw a C++ exception) to /EHs (tells
compiler assumes that functions declared as extern "C" may throw an exception).]
Because this library uses C++11 extensively, it requires a compatible compiler.
Known minimum working versions are as follows: Microsoft Visual Studio 2015
(msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other
compilers may work, if they support the following language features: auto
declarations, constexpr, defaulted functions, final, hdr thread, hdr tuple,
lambdas, noexcept, nullptr, rvalue references, template aliases. thread local,
variadic templates.
[endsect]

View File

@@ -0,0 +1,367 @@
[/
Copyright Oliver Kowalke 2014.
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
]
[#stack]
[section:stack Stack allocation]
The memory used by the stack is allocated/deallocated via a __stack_allocator__
which is required to model a __stack_allocator_concept__.
[heading __stack_allocator_concept__]
A __stack_allocator__ must satisfy the __stack_allocator_concept__ requirements
shown in the following table, in which `a` is an object of a
__stack_allocator__ type, `sctx` is a `stack_context`, and `size` is a `std::size_t`:
[table
[[expression][return type][notes]]
[
[`a(size)`]
[]
[creates a stack allocator]
]
[
[`a.allocate()`]
[`stack_context`]
[creates a stack]
]
[
[`a.deallocate( sctx)`]
[`void`]
[deallocates the stack created by `a.allocate()`]
]
]
[important The implementation of `allocate()` might include logic to protect
against exceeding the context's available stack size rather than leaving it as
undefined behaviour.]
[important Calling `deallocate()` with a `stack_context` not set by `allocate()`
results in undefined behaviour.]
[note Depending on the architecture `allocate()` stores an address from the
top of the stack (growing downwards) or the bottom of the stack (growing
upwards).]
[section:protected_fixedsize Class ['protected_fixedsize]]
__boost_context__ provides the class __protected_fixedsize__ which models
the __stack_allocator_concept__.
It appends a guard page at the end of each stack to protect against exceeding
the stack. If the guard page is accessed (read or write operation) a
segmentation fault/access violation is generated by the operating system.
[important Using __protected_fixedsize__ is expensive. That is, launching a
new coroutine with a new stack is expensive; the allocated stack is just as
efficient to use as any other stack.]
[note The appended `guard page` is [*not] mapped to physical memory, only
virtual addresses are used.]
#include <boost/context/protected_fixedsize.hpp>
template< typename traitsT >
struct basic_protected_fixedsize {
typedef traitT traits_type;
basic_protected_fixesize(std::size_t size = traits_type::default_size());
stack_context allocate();
void deallocate( stack_context &);
}
typedef basic_protected_fixedsize< stack_traits > protected_fixedsize
[heading `stack_context allocate()`]
[variablelist
[[Preconditions:] [`traits_type::minimum:size() <= size` and
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= size)`.]]
[[Effects:] [Allocates memory of at least `size` Bytes and stores a pointer
to the stack and its actual size in `sctx`. Depending
on the architecture (the stack grows downwards/upwards) the stored address is
the highest/lowest address of the stack.]]
]
[heading `void deallocate( stack_context & sctx)`]
[variablelist
[[Preconditions:] [`sctx.sp` is valid, `traits_type::minimum:size() <= sctx.size` and
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= sctx.size)`.]]
[[Effects:] [Deallocates the stack space.]]
]
[endsect]
[section:pooled_fixedsize Class ['pooled_fixedsize_stack]]
__boost_context__ provides the class __pooled_fixedsize__ which models
the __stack_allocator_concept__.
In contrast to __protected_fixedsize__ it does not append a guard page at the
end of each stack. The memory is managed internally by
[@http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html `boost::pool<>`].
#include <boost/context/pooled_fixedsize_stack.hpp>
template< typename traitsT >
struct basic_pooled_fixedsize_stack {
typedef traitT traits_type;
basic_pooled_fixedsize_stack(std::size_t stack_size = traits_type::default_size(), std::size_t next_size = 32, std::size_t max_size = 0);
stack_context allocate();
void deallocate( stack_context &);
}
typedef basic_pooled_fixedsize_stack< stack_traits > pooled_fixedsize_stack;
[heading `basic_pooled_fixedsize_stack(std::size_t stack_size, std::size_t next_size, std::size_t max_size)`]
[variablelist
[[Preconditions:] [`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= stack_size)`
and `0 < nest_size`.]]
[[Effects:] [Allocates memory of at least `stack_size` Bytes and stores a pointer to
the stack and its actual size in `sctx`. Depending on the architecture (the
stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack. Argument `next_size` determines the number of stacks to
request from the system the first time that `*this` needs to allocate system
memory. The third argument `max_size` controls how many memory might be
allocated for stacks - a value of zero means no uper limit.]]
]
[heading `stack_context allocate()`]
[variablelist
[[Preconditions:] [`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= stack_size)`.]]
[[Effects:] [Allocates memory of at least `stack_size` Bytes and stores a pointer to
the stack and its actual size in `sctx`. Depending on the architecture (the
stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.]]
]
[heading `void deallocate( stack_context & sctx)`]
[variablelist
[[Preconditions:] [`sctx.sp` is valid,
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= sctx.size)`.]]
[[Effects:] [Deallocates the stack space.]]
]
[endsect]
[section:fixedsize Class ['fixedsize_stack]]
__boost_context__ provides the class __fixedsize__ which models
the __stack_allocator_concept__.
In contrast to __protected_fixedsize__ it does not append a guard page at the
end of each stack. The memory is simply managed by `std::malloc()` and
`std::free()`.
#include <boost/context/fixedsize_stack.hpp>
template< typename traitsT >
struct basic_fixedsize_stack {
typedef traitT traits_type;
basic_fixesize_stack(std::size_t size = traits_type::default_size());
stack_context allocate();
void deallocate( stack_context &);
}
typedef basic_fixedsize_stack< stack_traits > fixedsize_stack;
[heading `stack_context allocate()`]
[variablelist
[[Preconditions:] [`traits_type::minimum:size() <= size` and
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= size)`.]]
[[Effects:] [Allocates memory of at least `size` Bytes and stores a pointer to
the stack and its actual size in `sctx`. Depending on the architecture (the
stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.]]
]
[heading `void deallocate( stack_context & sctx)`]
[variablelist
[[Preconditions:] [`sctx.sp` is valid, `traits_type::minimum:size() <= sctx.size` and
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= sctx.size)`.]]
[[Effects:] [Deallocates the stack space.]]
]
[endsect]
[#segmented]
[section:segmented Class ['segmented_stack]]
__boost_context__ supports usage of a __segmented__, e. g. the size of
the stack grows on demand. The coroutine is created with a minimal stack size
and will be increased as required.
Class __segmented__ models the __stack_allocator_concept__.
In contrast to __protected_fixedsize__ and __fixedsize__ it creates a
stack which grows on demand.
[note Segmented stacks are currently only supported by [*gcc] from version
[*4.7] [*clang] from version [*3.4] onwards. In order to use a
__segmented_stack__ __boost_context__ must be built with
property `segmented-stacks`, e.g. [*toolset=gcc segmented-stacks=on] and
applying `BOOST_USE_SEGMENTED_STACKS` at b2/bjam command line.]
[note Segmented stacks can only be used with __cc__ (using
[link implementation __ucontext__])].
#include <boost/context/segmented_stack.hpp>
template< typename traitsT >
struct basic_segmented_stack {
typedef traitT traits_type;
basic_segmented_stack(std::size_t size = traits_type::default_size());
stack_context allocate();
void deallocate( stack_context &);
}
typedef basic_segmented_stack< stack_traits > segmented_stack;
[heading `stack_context allocate()`]
[variablelist
[[Preconditions:] [`traits_type::minimum:size() <= size` and
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= size)`.]]
[[Effects:] [Allocates memory of at least `size` Bytes and stores a pointer to
the stack and its actual size in `sctx`. Depending on the architecture (the
stack grows downwards/upwards) the stored address is the highest/lowest
address of the stack.]]
]
[heading `void deallocate( stack_context & sctx)`]
[variablelist
[[Preconditions:] [`sctx.sp` is valid, `traits_type::minimum:size() <= sctx.size` and
`! traits_type::is_unbounded() && ( traits_type::maximum:size() >= sctx.size)`.]]
[[Effects:] [Deallocates the stack space.]]
]
[note If the library is compiled for segmented stacks, __segmented_stack__ is the only
available stack allocator.]
[endsect]
[section:stack_traits Class ['stack_traits]]
['stack_traits] models a __stack_traits__ providing a way to access certain
properites defined by the enironment. Stack allocators use __stack_traits__ to
allocate stacks.
#include <boost/context/stack_traits.hpp>
struct stack_traits {
static bool is_unbounded() noexcept;
static std::size_t page_size() noexcept;
static std::size_t default_size() noexcept;
static std::size_t minimum_size() noexcept;
static std::size_t maximum_size() noexcept;
}
[heading `static bool is_unbounded()`]
[variablelist
[[Returns:] [Returns `true` if the environment defines no limit for the size of
a stack.]]
[[Throws:] [Nothing.]]
]
[heading `static std::size_t page_size()`]
[variablelist
[[Returns:] [Returns the page size in bytes.]]
[[Throws:] [Nothing.]]
]
[heading `static std::size_t default_size()`]
[variablelist
[[Returns:] [Returns a default stack size, which may be platform specific.
If the stack is unbounded then the present implementation returns the maximum of
`64 kB` and `minimum_size()`.]]
[[Throws:] [Nothing.]]
]
[heading `static std::size_t minimum_size()`]
[variablelist
[[Returns:] [Returns the minimum size in bytes of stack defined by the
environment (Win32 4kB/Win64 8kB, defined by rlimit on POSIX).]]
[[Throws:] [Nothing.]]
]
[heading `static std::size_t maximum_size()`]
[variablelist
[[Preconditions:] [`is_unbounded()` returns `false`.]]
[[Returns:] [Returns the maximum size in bytes of stack defined by the
environment.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:stack_context Class ['stack_context]]
__boost_context__ provides the class __stack_context__ which will contain
the stack pointer and the size of the stack.
In case of a __segmented__, __stack_context__ contains some extra control
structures.
struct stack_context {
void * sp;
std::size_t size;
// might contain additional control structures
// for segmented stacks
}
[heading `void * sp`]
[variablelist
[[Value:] [Pointer to the beginning of the stack.]]
]
[heading `std::size_t size`]
[variablelist
[[Value:] [Actual size of the stack.]]
]
[endsect]
[section:valgrind Support for valgrind]
Running programs that switch stacks under valgrind causes problems.
Property (b2 command-line) `valgrind=on` let valgrind treat the memory regions
as stack space which suppresses the errors. Users must define `BOOST_USE_VALGRIND`
before including any Boost.Context headers when linking against Boost binaries
compiled with `valgrind=on`.
[endsect]
[section:sanitizers Support for sanitizers]
Sanitizers (GCC/Clang) are confused by the stack switches.
The library is required to be compiled with property (b2 command-line)
`context-impl=ucontext` and compilers santizer options.
Users must define `BOOST_USE_ASAN` before including any Boost.Context headers
when linking against Boost binaries.
[endsect]
[endsect]