mirror of
https://github.com/boostorg/context.git
synced 2026-01-19 04:02:17 +00:00
2990 lines
212 KiB
XML
2990 lines
212 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
|
<library id="context" name="Context" dirname="context" last-revision="$Date: 2016/01/12 19:06:39 $"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
<libraryinfo>
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Oliver</firstname> <surname>Kowalke</surname>
|
|
</author>
|
|
</authorgroup>
|
|
<copyright>
|
|
<year>2014</year> <holder>Oliver Kowalke</holder>
|
|
</copyright>
|
|
<legalnotice id="context.legal">
|
|
<para>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at <ulink url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
|
|
</para>
|
|
</legalnotice>
|
|
<librarypurpose>
|
|
C++ Library for swiching different user ctx
|
|
</librarypurpose>
|
|
<librarycategory name="category:text"></librarycategory>
|
|
</libraryinfo>
|
|
<title>Context</title>
|
|
<section id="context.overview">
|
|
<title><link linkend="context.overview">Overview</link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> 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 <emphasis>execution_context</emphasis> or <emphasis>captured_context</emphasis>
|
|
instance represents a specific point in the application's execution path. This
|
|
is useful for building higher-level abstractions, like <emphasis>coroutines</emphasis>,
|
|
<emphasis>cooperative threads (userland threads)</emphasis> or an equivalent
|
|
to <ulink url="http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx">C#
|
|
keyword <emphasis>yield</emphasis></ulink> in C++.
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> and <emphasis>captured_context</emphasis>
|
|
provide 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 <emphasis>execution_context</emphasis> or
|
|
<emphasis>captured_context</emphasis> only runs on a single thread, it can
|
|
be migrated to another thread at any given time.
|
|
</para>
|
|
<para>
|
|
A 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 among them requires only few CPU cycles because it does not involve
|
|
system calls as it is done within a single thread.
|
|
</para>
|
|
<para>
|
|
In order to use the classes and functions described here, you can either include
|
|
the specific headers specified by the descriptions of each class or function,
|
|
or include the master library header:
|
|
</para>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">all</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
|
|
</programlisting>
|
|
<para>
|
|
which includes all the other headers in turn.
|
|
</para>
|
|
<para>
|
|
All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>.
|
|
</para>
|
|
<important>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> requires C++11!
|
|
</para>
|
|
</important>
|
|
</section>
|
|
<section id="context.requirements">
|
|
<title><link linkend="context.requirements">Requirements</link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> must be built for the particular
|
|
compiler(s) and CPU architecture(s)s being targeted. <emphasis role="bold">Boost.Context</emphasis>
|
|
includes assembly code and, therefore, requires GNU as and GNU preprocesspr
|
|
for supported POSIX systems, MASM for Windows/x86 systems and ARMasm for Windows/arm
|
|
systems.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit.
|
|
</para>
|
|
</note>
|
|
<important>
|
|
<para>
|
|
Please note that <code><phrase role="identifier">address</phrase><phrase
|
|
role="special">-</phrase><phrase role="identifier">model</phrase><phrase
|
|
role="special">=</phrase><phrase role="number">64</phrase></code> must be
|
|
given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit
|
|
code will be generated.
|
|
</para>
|
|
</important>
|
|
<important>
|
|
<para>
|
|
For cross-compiling the lib you must specify certain additional properties
|
|
at bjam command line: <code><phrase role="identifier">target</phrase><phrase
|
|
role="special">-</phrase><phrase role="identifier">os</phrase></code>, <code><phrase
|
|
role="identifier">abi</phrase></code>, <code><phrase role="identifier">binary</phrase><phrase
|
|
role="special">-</phrase><phrase role="identifier">format</phrase></code>,
|
|
<code><phrase role="identifier">architecture</phrase></code> and <code><phrase
|
|
role="identifier">address</phrase><phrase role="special">-</phrase><phrase
|
|
role="identifier">model</phrase></code>.
|
|
</para>
|
|
</important>
|
|
<important>
|
|
<para>
|
|
For safe SEH the property 'asmflags=\safeseh' must be specified at bjam command
|
|
line.
|
|
</para>
|
|
</important>
|
|
</section>
|
|
<section id="context.econtext">
|
|
<title><anchor id="econtext"/><link linkend="context.econtext">Class execution_context</link></title>
|
|
<para>
|
|
Class <emphasis>execution_context</emphasis> encapsulates <emphasis>fcontext_t</emphasis>
|
|
and manages the context' stack (allocation/deallocation).
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> allocates the context stack (using its
|
|
<link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument)
|
|
and creates a control structure on top of it. This structure controls the life
|
|
time of the stack. Instances of <emphasis>execution_context</emphasis>, 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 <emphasis>StackAllocator</emphasis>.
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> is copy-constructible, move-constructible,
|
|
copy-assignable and move-assignable.
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> maintains a static, thread-local pointer
|
|
(smart pointer), accessed by <emphasis>execution_context::current()</emphasis>,
|
|
pointing to the active context. On each context switch the static thread-local
|
|
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 need
|
|
to call certain maintenance functions (__splitstack_getcontext() etc.) before
|
|
each context switch (each context switch exchanges the stack). Additionally
|
|
the destruction of <emphasis>execution_context</emphasis> and thus the stack
|
|
deallocation is faster compared to <link linkend="ccontext"><emphasis>captured_context</emphasis></link>.
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> expects a function/functor with signature
|
|
<code><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase
|
|
role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase
|
|
role="special">)</phrase></code> ( <code><phrase role="identifier">vp</phrase></code>
|
|
is the data passed at the first invocation of <link linkend="execution_context_operator_call"> <code>execution_context::operator()()</code></link>).
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.econtext.h0">
|
|
<phrase id="context.econtext.usage_of__emphasis_execution_context__emphasis_"/><link
|
|
linkend="context.econtext.usage_of__emphasis_execution_context__emphasis_">usage
|
|
of <emphasis>execution_context</emphasis></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</phrase><phrase role="special">;</phrase>
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">p</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">mctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase>
|
|
<phrase role="special">[</phrase><phrase role="identifier">n</phrase><phrase role="special">,&</phrase><phrase role="identifier">p</phrase><phrase role="special">,&</phrase><phrase role="identifier">mctx</phrase><phrase role="special">](</phrase><phrase role="keyword">void</phrase><phrase role="special">*)</phrase><phrase role="keyword">mutable</phrase><phrase role="special">{</phrase>
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
|
|
<phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">--></phrase><phrase role="number">0</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">yield</phrase><phrase role="special">(</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">auto</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">});</phrase>
|
|
<phrase role="keyword">for</phrase><phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">i</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">ctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special"><<</phrase><phrase role="identifier">p</phrase><phrase role="special"><<</phrase><phrase role="string">" "</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect3" id="context.econtext.h1">
|
|
<phrase id="context.econtext.inverting_the_control_flow"/><link linkend="context.econtext.inverting_the_control_flow">inverting
|
|
the control flow</link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="comment">/*
|
|
* grammar:
|
|
* P ---> E '\0'
|
|
* E ---> T {('+'|'-') T}
|
|
* T ---> S {('*'|'/') S}
|
|
* S ---> digit | '(' E ')'
|
|
*/</phrase>
|
|
<phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
|
|
<phrase role="comment">// implementation omitted; see examples directory</phrase>
|
|
<phrase role="special">};</phrase>
|
|
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">main</phrase><phrase role="special">()</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="comment">// create handle to main execution context</phrase>
|
|
<phrase role="keyword">auto</phrase> <phrase role="identifier">main_ctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
|
|
|
|
<phrase role="comment">// execute parser in new execution context</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">parser_ctx</phrase><phrase role="special">(</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">fixedsize_stack</phrase><phrase role="special">(</phrase><phrase role="number">4096</phrase><phrase role="special">),</phrase>
|
|
<phrase role="special">[&</phrase><phrase role="identifier">main_ctx</phrase><phrase role="special">,&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">,&</phrase><phrase role="identifier">except</phrase><phrase role="special">](</phrase><phrase role="keyword">void</phrase><phrase role="special">*){</phrase>
|
|
<phrase role="comment">// create parser with callback function</phrase>
|
|
<phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase> <phrase role="identifier">is</phrase><phrase role="special">,</phrase>
|
|
<phrase role="special">[&</phrase><phrase role="identifier">main_ctx</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">ch</phrase><phrase role="special">){</phrase>
|
|
<phrase role="comment">// resume main execution context</phrase>
|
|
<phrase role="identifier">main_ctx</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">ch</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">});</phrase>
|
|
<phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="comment">// start recursive parsing</phrase>
|
|
<phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase> <phrase role="special">...</phrase> <phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="comment">// store other exceptions in exception-pointer</phrase>
|
|
<phrase role="identifier">except</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="comment">// set termination flag</phrase>
|
|
<phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
|
|
<phrase role="comment">// resume main execution context</phrase>
|
|
<phrase role="identifier">main_ctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">});</phrase>
|
|
|
|
<phrase role="comment">// user-code pulls parsed data from parser</phrase>
|
|
<phrase role="comment">// invert control flow</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">parser_ctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="keyword">while</phrase><phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">done</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase><phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">vp</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="identifier">parser_ctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"main: done"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
|
|
<phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
|
|
<phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
|
|
</programlisting>
|
|
<para>
|
|
In this example a recursive descent parser uses a callback to emit a newly
|
|
passed symbol. Using <emphasis>execution_context</emphasis> 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).
|
|
</para>
|
|
<para>
|
|
The data (character) is transferred between the two <emphasis>execution_context</emphasis>.
|
|
</para>
|
|
<para>
|
|
If the code executed by <emphasis>execution_context</emphasis> emits an exception,
|
|
the application is terminated. <emphasis>std::exception_ptr</emphasis> can
|
|
be used to transfer exceptions between different execution contexts.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.econtext.h2">
|
|
<phrase id="context.econtext.allocating_control_structures_on_top_of_stack"/><link
|
|
linkend="context.econtext.allocating_control_structures_on_top_of_stack">allocating
|
|
control structures on top of stack</link>
|
|
</bridgehead>
|
|
<para>
|
|
Allocating control structures on top of the stack requires to allocated the
|
|
<emphasis>stack_context</emphasis> and create the control structure with placement
|
|
new before <emphasis>execution_context</emphasis> is created.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
The user is responsible for destructing the control structure at the top
|
|
of the stack.
|
|
</para>
|
|
</note>
|
|
<programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
|
|
<phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase> <phrase role="number">4048</phrase><phrase role="special">);</phrase>
|
|
<phrase role="comment">// allocate stack space</phrase>
|
|
<phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="comment">// reserve space for control structure on top of the stack</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
|
|
<phrase role="comment">// placement new creates control structure on reserved space</phrase>
|
|
<phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase> <phrase role="special">=</phrase> <phrase role="keyword">new</phrase> <phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">...</phrase>
|
|
<phrase role="comment">// destructing the control structure</phrase>
|
|
<phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">...</phrase>
|
|
<phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="comment">// execution context</phrase>
|
|
<phrase role="identifier">execution_context</phrase> <phrase role="identifier">ectx</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
|
|
<phrase role="comment">// create execution context</phrase>
|
|
<phrase role="identifier">ectx</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">),</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">entry_func</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">...</phrase>
|
|
<phrase role="special">};</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect3" id="context.econtext.h3">
|
|
<phrase id="context.econtext.exception_handling"/><link linkend="context.econtext.exception_handling">exception
|
|
handling</link>
|
|
</bridgehead>
|
|
<para>
|
|
If the function executed inside a <emphasis>execution_context</emphasis> emits
|
|
ans exception, the application is terminated by calling ['std::terminate().
|
|
<emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
|
|
between different execution contexts.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.econtext.h4">
|
|
<phrase id="context.econtext.parameter_passing"/><link linkend="context.econtext.parameter_passing">parameter
|
|
passing</link>
|
|
</bridgehead>
|
|
<para>
|
|
The void pointer argument passed to <emphasis>execution_context::operator()</emphasis>,
|
|
in one context, is passed as the last argument of the <emphasis>context-function</emphasis>
|
|
if the context is started for the first time. In all following invocations
|
|
of <emphasis>execution_context::operator()</emphasis> the void pointer passed
|
|
to <emphasis>execution_context::operator()</emphasis>, in one context, is returned
|
|
by <emphasis>execution_context::operator()</emphasis> in the other context.
|
|
</para>
|
|
<programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">private</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">caller_</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">callee_</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">X</phrase><phrase role="special">()</phrase> <phrase role="special">:</phrase>
|
|
<phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase>
|
|
<phrase role="identifier">caller_</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase>
|
|
<phrase role="identifier">callee_</phrase><phrase role="special">(</phrase> <phrase role="special">[=]</phrase> <phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">vp</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">str</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lexical_cast</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">caller_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">str</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">excptr_</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">})</phrase>
|
|
<phrase role="special">{}</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">ret</phrase> <phrase role="special">=</phrase> <phrase role="identifier">callee_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">ret</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">};</phrase>
|
|
|
|
<phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">x</phrase><phrase role="special">(</phrase> <phrase role="number">7</phrase><phrase role="special">)</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="number">7</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect3" id="context.econtext.h5">
|
|
<phrase id="context.econtext.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
|
|
linkend="context.econtext.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
|
|
<code><phrase role="identifier">execution_context</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
|
|
<phrase role="keyword">static</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase role="special">,</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">};</phrase>
|
|
</programlisting>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_current_bridgehead">
|
|
<phrase id="execution_context_current"/>
|
|
<link linkend="execution_context_current">Static
|
|
member function <code>current</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
Returns an instance of excution_context pointing to the active execution
|
|
context.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_constructor_bridgehead">
|
|
<phrase id="execution_context_constructor"/>
|
|
<link linkend="execution_context_constructor">Constructor</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Creates a new execution context and prepares the context to execute
|
|
<code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
|
|
is used as default stack allocator (stack size == fixedsize_stack::traits::default_size().
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
[[Effects:] [Creates a new execution context and prepares the context to execute
|
|
<code><phrase role="identifier">fn</phrase></code>. Used to store control structures
|
|
on top of the stack.]] ]
|
|
</para>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_copy constructor_bridgehead">
|
|
<phrase id="execution_context_copy constructor"/>
|
|
<link linkend="execution_context_copy
|
|
constructor">Copy constructor</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Copies <code><phrase role="identifier">other</phrase></code>, e.g. underlying
|
|
capture record is shared with <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_move constructor_bridgehead">
|
|
<phrase id="execution_context_move constructor"/>
|
|
<link linkend="execution_context_move
|
|
constructor">Move constructor</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Moves underlying capture record to <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_copy assignment_bridgehead">
|
|
<phrase id="execution_context_copy assignment"/>
|
|
<link linkend="execution_context_copy
|
|
assignment">Copy assignment operator</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Copies the state of <code><phrase role="identifier">other</phrase></code>
|
|
to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>,
|
|
state (capture record) is shared.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_move assignment_bridgehead">
|
|
<phrase id="execution_context_move assignment"/>
|
|
<link linkend="execution_context_move
|
|
assignment">Move assignment operator</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Moves the state of <code><phrase role="identifier">other</phrase></code>
|
|
to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
using move semantics.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_bool_bridgehead">
|
|
<phrase id="execution_context_operator_bool"/>
|
|
<link linkend="execution_context_operator_bool">Member
|
|
function <code>operator bool</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> points to a capture record.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_not_bridgehead">
|
|
<phrase id="execution_context_operator_not"/>
|
|
<link linkend="execution_context_operator_not">Member
|
|
function <code>operator!</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> does not point to a capture record.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_call_bridgehead">
|
|
<phrase id="execution_context_operator_call"/>
|
|
<link linkend="execution_context_operator_call">Member
|
|
function <code>operator()</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">data</phrase><phrase role="special">,</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
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><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>, which implies jumping to <code><phrase
|
|
role="special">*</phrase><phrase role="keyword">this</phrase></code>'s
|
|
context. The void pointer argument, <code><phrase role="identifier">vp</phrase></code>,
|
|
is passed to the current context to be returned by the most recent call
|
|
to <code><phrase role="identifier">execution_context</phrase><phrase
|
|
role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
|
|
role="special">()</phrase></code> in the same thread. <code><phrase role="identifier">fn</phrase></code>
|
|
is executed with arguments <code><phrase role="identifier">args</phrase></code>
|
|
on top of the stack of <code><phrase role="keyword">this</phrase></code>.
|
|
[[Note:
|
|
</para>
|
|
<para>
|
|
The behaviour is undefined if <code><phrase role="keyword">operator</phrase><phrase
|
|
role="special">()()</phrase></code> is called while <code><phrase role="identifier">execution_context</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">current</phrase><phrase
|
|
role="special">()</phrase></code> returns <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> (e.g. resuming an already running
|
|
context). If the top-level context function returns, <code><phrase role="identifier">std</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">exit</phrase><phrase
|
|
role="special">()</phrase></code> is called.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
The void pointer argument passed to the most recent call to <code><phrase
|
|
role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase
|
|
role="keyword">operator</phrase><phrase role="special">()</phrase></code>,
|
|
if any.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_equal_bridgehead">
|
|
<phrase id="execution_context_operator_equal"/>
|
|
<link linkend="execution_context_operator_equal">Member
|
|
function <code>operator==</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>
|
|
represent the same execution context, <code><phrase role="keyword">false</phrase></code>
|
|
otherwise.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_notequal_bridgehead">
|
|
<phrase id="execution_context_operator_notequal"/>
|
|
<link linkend="execution_context_operator_notequal">Member
|
|
function <code>operator!=</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code>! (other == * this)</code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_less_bridgehead">
|
|
<phrase id="execution_context_operator_less"/>
|
|
<link linkend="execution_context_operator_less">Member
|
|
function <code>operator<</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase
|
|
role="identifier">other</phrase></code> is true and the implementation-defined
|
|
total order of <code><phrase role="identifier">execution_context</phrase></code>
|
|
values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
before <code><phrase role="identifier">other</phrase></code>, false otherwise.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_greater_bridgehead">
|
|
<phrase id="execution_context_operator_greater"/>
|
|
<link linkend="execution_context_operator_greater">Member
|
|
function <code>operator></code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_lesseq_bridgehead">
|
|
<phrase id="execution_context_operator_lesseq"/>
|
|
<link linkend="execution_context_operator_lesseq">Member
|
|
function <code>operator<=</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
|
|
role="identifier">other</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
|
|
role="special">)</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_operator_greatereq_bridgehead">
|
|
<phrase id="execution_context_operator_greatereq"/>
|
|
<link linkend="execution_context_operator_greatereq">Member
|
|
function <code>operator>=</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
|
|
<phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="execution_context_bridgehead">
|
|
<phrase id="execution_context"/>
|
|
<link linkend="execution_context">Non-member function
|
|
<code>operator<<()</code></link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Efects:</term>
|
|
<listitem>
|
|
<para>
|
|
Writes the representation of <code><phrase role="identifier">other</phrase></code>
|
|
to stream <code><phrase role="identifier">os</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">os</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.ccontext">
|
|
<title><anchor id="ccontext"/><link linkend="context.ccontext">Class captured_context</link></title>
|
|
<para>
|
|
Class <emphasis>captured_context</emphasis> encapsulates <emphasis>fcontext_t</emphasis>
|
|
and manages the context' stack (allocation/deallocation).
|
|
</para>
|
|
<para>
|
|
<emphasis>captured_context</emphasis> allocates the context stack (using its
|
|
<emphasis>StackAllocator</emphasis> argument) and creates a control structure
|
|
on top of it. This structure controls the life time of the stack. The address
|
|
of the control structure is stored in the first frame of context' stack (e.g.
|
|
it can not accessed by instances of <emphasis>captured_context</emphasis> directly).
|
|
In contrast to <emphasis>execution_context</emphasis> the ownership of the
|
|
control structure is not shared A call of<emphasis>captured_context::operator()</emphasis>
|
|
enters the context represented by <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> and invalidates <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>. The context that has been suspended by
|
|
calling <emphasis>captured_context::operator()</emphasis> is passed to the
|
|
resumed context, e.g. as argument of the context-function if the context was
|
|
resumed the first time or returned by <emphasis>captured_context::operator()</emphasis>.
|
|
<emphasis>captured_context</emphasis> is only move-constructible and move-assignable.
|
|
If the last reference (<emphasis>captured_context</emphasis>) goes out of scope,
|
|
the control structure is destroyed and the stack gets deallocated via the
|
|
<emphasis>StackAllocator</emphasis>. <emphasis>captured_context</emphasis>
|
|
maintains a static, thread-local pointer (smart pointer), accessed by <emphasis>execution_context::current()</emphasis>,
|
|
pointing to the active context. On each context switch the static, thread-local
|
|
pointer is updated. This makes the context switch a little bit slower, but
|
|
enables faster context destruction (stack unwinding) compared to <emphasis>captured_context</emphasis>.
|
|
</para>
|
|
<para>
|
|
<emphasis>captured_context</emphasis> expects a function/functor with signature
|
|
<code><phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase>
|
|
<phrase role="identifier">captured_context</phrase> <phrase role="identifier">ctx</phrase><phrase
|
|
role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase>
|
|
<phrase role="identifier">vp</phrase><phrase role="special">)</phrase></code>.
|
|
The parameter <code><phrase role="identifier">ctx</phrase></code> represents
|
|
the context from which this context was resumed (e.g. that has called <emphasis>captured_context::operator()</emphasis>
|
|
on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>)
|
|
and <code><phrase role="identifier">vp</phrase></code> is the data passed to
|
|
<emphasis>captured_context::operator()</emphasis>. The function/functor has
|
|
to return the captured_context that has to be resumed, while this context terminates.
|
|
</para>
|
|
<important>
|
|
<para>
|
|
Segemnted stacks are not supported together with <emphasis>captured_context</emphasis>.
|
|
</para>
|
|
</important>
|
|
<bridgehead renderas="sect3" id="context.ccontext.h0">
|
|
<phrase id="context.ccontext.usage_of__emphasis_captured_context__emphasis_"/><link
|
|
linkend="context.ccontext.usage_of__emphasis_captured_context__emphasis_">usage
|
|
of <emphasis>captured_context</emphasis></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="comment">/*
|
|
* grammar:
|
|
* P ---> E '\0'
|
|
* E ---> T {('+'|'-') T}
|
|
* T ---> S {('*'|'/') S}
|
|
* S ---> digit | '(' E ')'
|
|
*/</phrase>
|
|
<phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
|
|
<phrase role="comment">// implementation omitted; see examples directory</phrase>
|
|
<phrase role="special">};</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="comment">// execute parser in new execution context</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">captured_context</phrase> <phrase role="identifier">pctx</phrase><phrase role="special">(</phrase>
|
|
<phrase role="special">[&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">,&</phrase><phrase role="identifier">except</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">captured_context</phrase> <phrase role="identifier">mctx</phrase><phrase role="special">,</phrase><phrase role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">ignored</phrase><phrase role="special">){</phrase>
|
|
<phrase role="comment">// create parser with callback function</phrase>
|
|
<phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase> <phrase role="identifier">is</phrase><phrase role="special">,</phrase>
|
|
<phrase role="special">[&</phrase><phrase role="identifier">mctx</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">ch</phrase><phrase role="special">){</phrase>
|
|
<phrase role="comment">// resume main execution context</phrase>
|
|
<phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">mctx</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">ch</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">mctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="special">});</phrase>
|
|
<phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="comment">// start recursive parsing</phrase>
|
|
<phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase> <phrase role="special">...</phrase> <phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="comment">// store other exceptions in exception-pointer</phrase>
|
|
<phrase role="identifier">except</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="comment">// set termination flag</phrase>
|
|
<phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
|
|
<phrase role="comment">// resume main execution context</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="identifier">mctx</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">});</phrase>
|
|
|
|
<phrase role="comment">// user-code pulls parsed data from parser</phrase>
|
|
<phrase role="comment">// invert control flow</phrase>
|
|
<phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">pctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="identifier">pctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="keyword">while</phrase><phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">done</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase><phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">vp</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">pctx</phrase><phrase role="special">,</phrase><phrase role="identifier">vp</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">pctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
|
|
<phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
|
|
<phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
|
|
</programlisting>
|
|
<para>
|
|
In this example a recursive descent parser uses a callback to emit a newly
|
|
passed symbol. Using <emphasis>captured_context</emphasis> 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).
|
|
</para>
|
|
<para>
|
|
The data (character) is transferred between the two <emphasis>captured_context</emphasis>.
|
|
</para>
|
|
<para>
|
|
If the code executed by <emphasis>captured_context</emphasis> emits an exception,
|
|
the application is terminated. <emphasis>std::exception_ptr</emphasis> can
|
|
be used to transfer exceptions between different execution contexts.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ccontext.h1">
|
|
<phrase id="context.ccontext.allocating_control_structures_on_top_of_stack"/><link
|
|
linkend="context.ccontext.allocating_control_structures_on_top_of_stack">allocating
|
|
control structures on top of stack</link>
|
|
</bridgehead>
|
|
<para>
|
|
Allocating control structures on top of the stack requires to allocated the
|
|
<emphasis>stack_context</emphasis> and create the control structure with placement
|
|
new before <emphasis>captured_context</emphasis> is created.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
The user is responsible for destructing the control structure at the top
|
|
of the stack.
|
|
</para>
|
|
</note>
|
|
<programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
|
|
<phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase> <phrase role="number">4048</phrase><phrase role="special">);</phrase>
|
|
<phrase role="comment">// allocate stack space</phrase>
|
|
<phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="comment">// reserve space for control structure on top of the stack</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
|
|
<phrase role="comment">// placement new creates control structure on reserved space</phrase>
|
|
<phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase> <phrase role="special">=</phrase> <phrase role="keyword">new</phrase> <phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">...</phrase>
|
|
<phrase role="comment">// destructing the control structure</phrase>
|
|
<phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">...</phrase>
|
|
<phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="comment">// captured context</phrase>
|
|
<phrase role="identifier">captured_context</phrase> <phrase role="identifier">cctx</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
|
|
<phrase role="comment">// create captured context</phrase>
|
|
<phrase role="identifier">cctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">),</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">entry_func</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">...</phrase>
|
|
<phrase role="special">};</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect3" id="context.ccontext.h2">
|
|
<phrase id="context.ccontext.exception_handling"/><link linkend="context.ccontext.exception_handling">exception
|
|
handling</link>
|
|
</bridgehead>
|
|
<para>
|
|
If the function executed inside a <emphasis>captured_context</emphasis> emits
|
|
ans exception, the application is terminated by calling ['std::terminate().
|
|
<emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
|
|
between different execution contexts.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ccontext.h3">
|
|
<phrase id="context.ccontext.parameter_passing"/><link linkend="context.ccontext.parameter_passing">parameter
|
|
passing</link>
|
|
</bridgehead>
|
|
<para>
|
|
The void pointer argument passed to <emphasis>captured_context::operator()</emphasis>,
|
|
in one context, is passed as the last argument of the <emphasis>context-function</emphasis>
|
|
if the context is started for the first time. In all following invocations
|
|
of <emphasis>captured_context::operator()</emphasis> the void pointer passed
|
|
to <emphasis>captured_context::operator()</emphasis>, in one context, is returned
|
|
by <emphasis>captured_context::operator()</emphasis> in the other context.
|
|
</para>
|
|
<programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">private</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">captured_context</phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">X</phrase><phrase role="special">()</phrase> <phrase role="special">:</phrase>
|
|
<phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase>
|
|
<phrase role="identifier">ctx_</phrase><phrase role="special">(</phrase> <phrase role="special">[=](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">captured_context</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase role="special">)-></phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">captured_context</phrase><phrase role="special">{</phrase>
|
|
<phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">vp</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">str</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lexical_cast</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">str</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">forced_unwind</phrase> <phrase role="keyword">const</phrase><phrase role="special">&)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">throw</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="identifier">excptr_</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">})</phrase>
|
|
<phrase role="special">{}</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">ctx_</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">ret</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">ret</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
<phrase role="special">};</phrase>
|
|
|
|
<phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">x</phrase><phrase role="special">(</phrase> <phrase role="number">7</phrase><phrase role="special">)</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="number">7</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect3" id="context.ccontext.h4">
|
|
<phrase id="context.ccontext.class__code__phrase_role__identifier__captured_context__phrase___code_"/><link
|
|
linkend="context.ccontext.class__code__phrase_role__identifier__captured_context__phrase___code_">Class
|
|
<code><phrase role="identifier">captured_context</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="special">~</phrase><phrase role="identifier">captured_context</phrase><phrase role="special">();</phrase>
|
|
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">captured_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">captured_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">captured_context</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">captured_context</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">captured_context</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">data</phrase><phrase role="special">,</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">};</phrase>
|
|
</programlisting>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_constructor_bridgehead">
|
|
<phrase id="captured_context_constructor"/>
|
|
<link linkend="captured_context_constructor">Constructor</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Creates a new execution context and prepares the context to execute
|
|
<code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
|
|
is used as default stack allocator (stack size == fixedsize_stack::traits::default_size().
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
[[Effects:] [Creates a new execution context and prepares the context to execute
|
|
<code><phrase role="identifier">fn</phrase></code>.]] ] [[Effects:] [Creates
|
|
a new execution context and prepares the context to execute <code><phrase role="identifier">fn</phrase></code>.
|
|
Used to store control structures on top of the stack.]] ]
|
|
</para>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_move constructor_bridgehead">
|
|
<phrase id="captured_context_move constructor"/>
|
|
<link linkend="captured_context_move
|
|
constructor">Move constructor</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">captured_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Moves underlying capture record to <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_move assignment_bridgehead">
|
|
<phrase id="captured_context_move assignment"/>
|
|
<link linkend="captured_context_move
|
|
assignment">Move assignment operator</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">captured_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Moves the state of <code><phrase role="identifier">other</phrase></code>
|
|
to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
using move semantics.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_bool_bridgehead">
|
|
<phrase id="captured_context_operator_bool"/>
|
|
<link linkend="captured_context_operator_bool">Member
|
|
function <code>operator bool</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> points to a capture record.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_not_bridgehead">
|
|
<phrase id="captured_context_operator_not"/>
|
|
<link linkend="captured_context_operator_not">Member
|
|
function <code>operator!</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> does not point to a capture record.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_call_bridgehead">
|
|
<phrase id="captured_context_operator_call"/>
|
|
<link linkend="captured_context_operator_call">Member
|
|
function <code>operator()</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">captured_context</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">captured_context</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">captured_context</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">data</phrase><phrase role="special">,</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
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><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>, which implies jumping to <code><phrase
|
|
role="special">*</phrase><phrase role="keyword">this</phrase></code>'s
|
|
context. The void pointer argument, <code><phrase role="identifier">vp</phrase></code>,
|
|
is passed to the current context to be returned by the most recent call
|
|
to <code><phrase role="identifier">captured_context</phrase><phrase role="special">::</phrase><phrase
|
|
role="keyword">operator</phrase><phrase role="special">()</phrase></code>
|
|
in the same thread. <code><phrase role="identifier">fn</phrase></code>
|
|
is executed with arguments <code><phrase role="identifier">args</phrase></code>
|
|
on top of the stack of <code><phrase role="keyword">this</phrase></code>.
|
|
[[Note:
|
|
</para>
|
|
<para>
|
|
The behaviour is undefined if <code><phrase role="keyword">operator</phrase><phrase
|
|
role="special">()()</phrase></code> is called while <code><phrase role="identifier">captured_context</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">current</phrase><phrase
|
|
role="special">()</phrase></code> returns <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> (e.g. resuming an already running
|
|
context). If the top-level context function returns, <code><phrase role="identifier">std</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">exit</phrase><phrase
|
|
role="special">()</phrase></code> is called.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
The tuple of void pointer argument passed to the most recent call to
|
|
<code><phrase role="identifier">captured_context</phrase><phrase role="special">::</phrase><phrase
|
|
role="keyword">operator</phrase><phrase role="special">()</phrase></code>,
|
|
if any and a captured_context representing the context that has been
|
|
suspended .
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_equal_bridgehead">
|
|
<phrase id="captured_context_operator_equal"/>
|
|
<link linkend="captured_context_operator_equal">Member
|
|
function <code>operator==</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>
|
|
represent the same execution context, <code><phrase role="keyword">false</phrase></code>
|
|
otherwise.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_notequal_bridgehead">
|
|
<phrase id="captured_context_operator_notequal"/>
|
|
<link linkend="captured_context_operator_notequal">Member
|
|
function <code>operator!=</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code>! (other == * this)</code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_less_bridgehead">
|
|
<phrase id="captured_context_operator_less"/>
|
|
<link linkend="captured_context_operator_less">Member
|
|
function <code>operator<</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase
|
|
role="identifier">other</phrase></code> is true and the implementation-defined
|
|
total order of <code><phrase role="identifier">captured_context</phrase></code>
|
|
values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
before <code><phrase role="identifier">other</phrase></code>, false otherwise.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_greater_bridgehead">
|
|
<phrase id="captured_context_operator_greater"/>
|
|
<link linkend="captured_context_operator_greater">Member
|
|
function <code>operator></code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_lesseq_bridgehead">
|
|
<phrase id="captured_context_operator_lesseq"/>
|
|
<link linkend="captured_context_operator_lesseq">Member
|
|
function <code>operator<=</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
|
|
role="identifier">other</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
|
|
role="special">)</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_operator_greatereq_bridgehead">
|
|
<phrase id="captured_context_operator_greatereq"/>
|
|
<link linkend="captured_context_operator_greatereq">Member
|
|
function <code>operator>=</code>()</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
|
|
<phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="captured_context_bridgehead">
|
|
<phrase id="captured_context"/>
|
|
<link linkend="captured_context">Non-member function
|
|
<code>operator<<()</code></link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">captured_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Efects:</term>
|
|
<listitem>
|
|
<para>
|
|
Writes the representation of <code><phrase role="identifier">other</phrase></code>
|
|
to stream <code><phrase role="identifier">os</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">os</phrase></code>
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.stack">
|
|
<title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title>
|
|
<para>
|
|
The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis>
|
|
which is required to model a <emphasis>stack-allocator concept</emphasis>.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.stack.h0">
|
|
<phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link
|
|
linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
|
|
concept</emphasis></link>
|
|
</bridgehead>
|
|
<para>
|
|
A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator
|
|
concept</emphasis> requirements shown in the following table, in which <code><phrase
|
|
role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis>
|
|
type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
|
|
role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
|
|
is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">size_t</phrase></code>:
|
|
</para>
|
|
<informaltable frame="all">
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
expression
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
return type
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
notes
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
<code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">)</phrase></code>
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
creates a stack allocator
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
<code><phrase role="identifier">stack_context</phrase></code>
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
creates a stack
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">deallocate</phrase><phrase role="special">(</phrase>
|
|
<phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
<code><phrase role="keyword">void</phrase></code>
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
|
|
role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
|
|
role="special">()</phrase></code>
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
<important>
|
|
<para>
|
|
The implementation of <code><phrase role="identifier">allocate</phrase><phrase
|
|
role="special">()</phrase></code> might include logic to protect against
|
|
exceeding the context's available stack size rather than leaving it as undefined
|
|
behaviour.
|
|
</para>
|
|
</important>
|
|
<important>
|
|
<para>
|
|
Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
|
|
with a <code><phrase role="identifier">stack_context</phrase></code> not
|
|
set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
|
|
results in undefined behaviour.
|
|
</para>
|
|
</important>
|
|
<note>
|
|
<para>
|
|
The stack is not required to be aligned; alignment takes place inside <emphasis>execution_context</emphasis>.
|
|
</para>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
|
|
role="special">()</phrase></code> stores an address from the top of the stack
|
|
(growing downwards) or the bottom of the stack (growing upwards).
|
|
</para>
|
|
</note>
|
|
<section id="context.stack.protected_fixedsize">
|
|
<title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis>
|
|
which models the <emphasis>stack-allocator concept</emphasis>. 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.
|
|
</para>
|
|
<important>
|
|
<para>
|
|
Using <emphasis>protected_fixedsize_stack</emphasis> 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.
|
|
</para>
|
|
</important>
|
|
<note>
|
|
<para>
|
|
The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
|
|
is <emphasis role="bold">not</emphasis> mapped to physical memory, only
|
|
virtual addresses are used.
|
|
</para>
|
|
</note>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">protected_fixedsize</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase>
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">basic_protected_fixesize</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
|
|
|
|
<phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
|
|
|
|
<phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">protected_fixedsize</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h0">
|
|
<phrase id="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
|
|
linkend="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
|
|
role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
|
|
role="special">()</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
|
|
and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special">&&</phrase>
|
|
<phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
|
|
role="special">:</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
|
|
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
|
|
Bytes and stores a pointer to the stack and its actual size in <code><phrase
|
|
role="identifier">sctx</phrase></code>. Depending on the architecture
|
|
(the stack grows downwards/upwards) the stored address is the highest/lowest
|
|
address of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h1">
|
|
<phrase id="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_"/><link
|
|
linkend="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><phrase
|
|
role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
|
|
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
|
|
<phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
|
|
role="special">)</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
|
|
role="special">:</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
|
|
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
|
|
<phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special">&&</phrase> <phrase role="special">(</phrase>
|
|
<phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
|
|
role="special">.</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">)</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Deallocates the stack space.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.stack.fixedsize">
|
|
<title><link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>fixedsize_stack</emphasis>
|
|
which models the <emphasis>stack-allocator concept</emphasis>. In contrast
|
|
to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
|
|
page at the end of each stack. The memory is simply managed by <code><phrase
|
|
role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">malloc</phrase><phrase
|
|
role="special">()</phrase></code> and <code><phrase role="identifier">std</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">free</phrase><phrase
|
|
role="special">()</phrase></code>.
|
|
</para>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">fixedsize_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">struct</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase>
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">basic_fixesize_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
|
|
|
|
<phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
|
|
|
|
<phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">fixedsize_stack</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect4" id="context.stack.fixedsize.h0">
|
|
<phrase id="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
|
|
linkend="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
|
|
role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
|
|
role="special">()</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
|
|
and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special">&&</phrase>
|
|
<phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
|
|
role="special">:</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
|
|
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
|
|
Bytes and stores a pointer to the stack and its actual size in <code><phrase
|
|
role="identifier">sctx</phrase></code>. Depending on the architecture
|
|
(the stack grows downwards/upwards) the stored address is the highest/lowest
|
|
address of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.fixedsize.h1">
|
|
<phrase id="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_"/><link
|
|
linkend="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><phrase
|
|
role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
|
|
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
|
|
<phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
|
|
role="special">)</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
|
|
role="special">:</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
|
|
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
|
|
<phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special">&&</phrase> <phrase role="special">(</phrase>
|
|
<phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
|
|
role="special">.</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">)</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Deallocates the stack space.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.stack.segmented">
|
|
<title><link linkend="context.stack.segmented">Class <emphasis>segmented_stack</emphasis></link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> supports usage of a <emphasis>segmented_stack</emphasis>,
|
|
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 <emphasis>segmented_stack</emphasis>
|
|
models the <emphasis>stack-allocator concept</emphasis>. In contrast to
|
|
<emphasis>protected_fixedsize_stack</emphasis> and <emphasis>fixedsize_stack</emphasis>
|
|
it creates a stack which grows on demand.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
|
|
from version <emphasis role="bold">4.7</emphasis> <emphasis role="bold">clang</emphasis>
|
|
from version <emphasis role="bold">3.4</emphasis> onwards. In order to
|
|
use a __segmented_stack__ <emphasis role="bold">Boost.Context</emphasis>
|
|
must be built with <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis>
|
|
at b2/bjam command-line. Applications must be compiled with compiler-flags
|
|
<emphasis role="bold">-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS</emphasis>.
|
|
</para>
|
|
</note>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">segmented_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">struct</phrase> <phrase role="identifier">basic_segmented_stack</phrase>
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">basic_segmented_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
|
|
|
|
<phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
|
|
|
|
<phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_segmented_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">segmented_stack</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect4" id="context.stack.segmented.h0">
|
|
<phrase id="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
|
|
linkend="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
|
|
role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
|
|
role="special">()</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
|
|
and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special">&&</phrase>
|
|
<phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
|
|
role="special">:</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
|
|
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
|
|
Bytes and stores a pointer to the stack and its actual size in <code><phrase
|
|
role="identifier">sctx</phrase></code>. Depending on the architecture
|
|
(the stack grows downwards/upwards) the stored address is the highest/lowest
|
|
address of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.segmented.h1">
|
|
<phrase id="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_"/><link
|
|
linkend="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><phrase
|
|
role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
|
|
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
|
|
<phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
|
|
role="special">)</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
|
|
role="special">:</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
|
|
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
|
|
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
|
|
<phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special">&&</phrase> <phrase role="special">(</phrase>
|
|
<phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
|
|
role="identifier">size</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
|
|
role="special">.</phrase><phrase role="identifier">size</phrase><phrase
|
|
role="special">)</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Deallocates the stack space.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<note>
|
|
<para>
|
|
If the library is compiled for segmented stacks, __segmented_stack__ is
|
|
the only available stack allocator.
|
|
</para>
|
|
</note>
|
|
</section>
|
|
<section id="context.stack.stack_traits">
|
|
<title><link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link></title>
|
|
<para>
|
|
<emphasis>stack_traits</emphasis> models a <emphasis>stack-traits</emphasis>
|
|
providing a way to access certain properites defined by the enironment. Stack
|
|
allocators use <emphasis>stack-traits</emphasis> to allocate stacks.
|
|
</para>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">stack_traits</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
|
|
|
|
<phrase role="keyword">struct</phrase> <phrase role="identifier">stack_traits</phrase>
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<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> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<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> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<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> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
|
|
<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> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">}</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_traits.h0">
|
|
<phrase id="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_"/><link
|
|
linkend="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><phrase
|
|
role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase
|
|
role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
Returns <code><phrase role="keyword">true</phrase></code> if the environment
|
|
defines no limit for the size of a stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_traits.h1">
|
|
<phrase id="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_"/><link
|
|
linkend="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><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></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
Returns the page size in bytes.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_traits.h2">
|
|
<phrase id="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_"/><link
|
|
linkend="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><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></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
Returns a default stack size, which may be platform specific. If the
|
|
stack is unbounded then the present implementation returns the maximum
|
|
of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code>
|
|
and <code><phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_traits.h3">
|
|
<phrase id="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_"/><link
|
|
linkend="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><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></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
Returns the minimum size in bytes of stack defined by the environment
|
|
(Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_traits.h4">
|
|
<phrase id="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_"/><link
|
|
linkend="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><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></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<code><phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code>
|
|
returns <code><phrase role="keyword">false</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
Returns the maximum size in bytes of stack defined by the environment.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.stack.stack_context">
|
|
<title><link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>stack_context</emphasis>
|
|
which will contain the stack pointer and the size of the stack. In case of
|
|
a <emphasis>segmented_stack</emphasis>, <emphasis>stack_context</emphasis>
|
|
contains some extra control structures.
|
|
</para>
|
|
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase>
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="comment">// might contain additional control structures</phrase>
|
|
<phrase role="comment">// for segmented stacks</phrase>
|
|
<phrase role="special">}</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_context.h0">
|
|
<phrase id="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link
|
|
linkend="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code><phrase
|
|
role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Value:</term>
|
|
<listitem>
|
|
<para>
|
|
Pointer to the beginning of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.stack_context.h1">
|
|
<phrase id="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_"/><link
|
|
linkend="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><phrase
|
|
role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
|
|
<phrase role="identifier">size</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Value:</term>
|
|
<listitem>
|
|
<para>
|
|
Actual size of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.stack.valgrind">
|
|
<title><link linkend="context.stack.valgrind">Support for valgrind</link></title>
|
|
<para>
|
|
Running programs that switch stacks under valgrind causes problems. Property
|
|
(b2 command-line) <code><phrase role="identifier">valgrind</phrase><phrase
|
|
role="special">=</phrase><phrase role="identifier">on</phrase></code> let
|
|
valgrind treat the memory regions as stack space which suppresses the errors.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="context.struct__preallocated_">
|
|
<title><link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link></title>
|
|
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">:</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_allocator</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">};</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect3" id="context.struct__preallocated_.h0">
|
|
<phrase id="context.struct__preallocated_.constructor"/><link linkend="context.struct__preallocated_.constructor">Constructor</link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">:</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_allocator</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Creates an object of preallocated.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</section>
|
|
<section id="context.performance">
|
|
<title><link linkend="context.performance">Performance</link></title>
|
|
<para>
|
|
Performance of <emphasis role="bold">Boost.Context</emphasis> was measured
|
|
on the platforms shown in the following table. Performance measurements were
|
|
taken using <code><phrase role="identifier">rdtsc</phrase></code> and <code><phrase
|
|
role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase
|
|
role="special">::</phrase><phrase role="identifier">high_resolution_clock</phrase></code>,
|
|
with overhead corrections, on x86 platforms. In each case, cache warm-up was
|
|
accounted for, and the one running thread was pinned to a single CPU. The code
|
|
was compiled using the build options, 'variant = release cxxflags = -DBOOST_DISABLE_ASSERTS'.
|
|
</para>
|
|
<table frame="all" id="context.performance.performance_of_context_switch">
|
|
<title>Performance of context switch</title>
|
|
<tgroup cols="4">
|
|
<thead>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
Platform
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
ucontext_t
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
execution_context
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
captured_context
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
x86_64 <footnote id="context.performance.f0">
|
|
<para>
|
|
Intel Core2 Q6700
|
|
</para>
|
|
</footnote>
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
547 ns / 1433 cycles
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
51 ns / 141 cycles
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
7 ns / 18 cycles
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</section>
|
|
<section id="context.architectures">
|
|
<title><link linkend="context.architectures">Architectures</link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> supports following architectures:
|
|
</para>
|
|
<table frame="all" id="context.architectures.supported_architectures___abi_binary_format__">
|
|
<title>Supported architectures (<ABI|binary format>)</title>
|
|
<tgroup cols="5">
|
|
<thead>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
Architecture
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
LINUX (UNIX)
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
Windows
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
MacOS X
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
iOS
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
arm
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
AAPCS|ELF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
AAPCS|PE
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
AAPCS|MACH-O
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
i386
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|ELF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
MS|PE
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|MACH-O
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
mips1
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
O32|ELF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
ppc32
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|ELF,XCOFF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|MACH-O
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
ppc64
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|ELF,XCOFF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|MACH-O
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
sparc
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
<para>
|
|
x86_64
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV,X32|ELF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
MS|PE
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
SYSV|MACH-O
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</para>
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<section id="context.architectures.crosscompiling">
|
|
<title><link linkend="context.architectures.crosscompiling">Cross compiling</link></title>
|
|
<para>
|
|
Cross compiling the library requires to specify the build properties <architecture>,
|
|
<address-model>, <binary-format> and <abi> at b2 command
|
|
line.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="context.rationale">
|
|
<title><link linkend="context.rationale">Rationale</link></title>
|
|
<bridgehead renderas="sect3" id="context.rationale.h0">
|
|
<phrase id="context.rationale.no_inline_assembler"/><link linkend="context.rationale.no_inline_assembler">No
|
|
inline-assembler</link>
|
|
</bridgehead>
|
|
<para>
|
|
Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support
|
|
inline assembler. <footnote id="context.rationale.f0">
|
|
<para>
|
|
<ulink url="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx">MSDN article
|
|
'Inline Assembler'</ulink>
|
|
</para>
|
|
</footnote>. Inlined assembler generates code bloating which is not welcome
|
|
on embedded systems.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.rationale.h1">
|
|
<phrase id="context.rationale.fcontext_t"/><link linkend="context.rationale.fcontext_t">fcontext_t</link>
|
|
</bridgehead>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> 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.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Context switches do not preserve the signal mask on UNIX systems.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
<emphasis>fcontext_t</emphasis> is an opaque pointer.
|
|
</para>
|
|
<section id="context.rationale.other_apis_">
|
|
<title><link linkend="context.rationale.other_apis_">Other APIs </link></title>
|
|
<bridgehead renderas="sect4" id="context.rationale.other_apis_.h0">
|
|
<phrase id="context.rationale.other_apis_.setjmp___longjmp__"/><link linkend="context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</link>
|
|
</bridgehead>
|
|
<para>
|
|
C99 defines <code><phrase role="identifier">setjmp</phrase><phrase role="special">()</phrase></code>/<code><phrase
|
|
role="identifier">longjmp</phrase><phrase role="special">()</phrase></code>
|
|
to provide non-local jumps but it does not require that <emphasis>longjmp()</emphasis>
|
|
preserves the current stack frame. Therefore, jumping into a function which
|
|
was exited via a call to <emphasis>longjmp()</emphasis> is undefined <footnote
|
|
id="context.rationale.other_apis_.f0">
|
|
<para>
|
|
ISO/IEC 9899:1999, 2005, 7.13.2.1:2
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<bridgehead renderas="sect4" id="context.rationale.other_apis_.h1">
|
|
<phrase id="context.rationale.other_apis_.ucontext_t"/><link linkend="context.rationale.other_apis_.ucontext_t">ucontext_t</link>
|
|
</bridgehead>
|
|
<para>
|
|
Since POSIX.1-2003 <code><phrase role="identifier">ucontext_t</phrase></code>
|
|
is deprecated and was removed in POSIX.1-2008! The function signature of
|
|
<code><phrase role="identifier">makecontext</phrase><phrase role="special">()</phrase></code>
|
|
is:
|
|
</para>
|
|
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">makecontext</phrase><phrase role="special">(</phrase><phrase role="identifier">ucontext_t</phrase> <phrase role="special">*</phrase><phrase role="identifier">ucp</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">(*</phrase><phrase role="identifier">func</phrase><phrase role="special">)(),</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">argc</phrase><phrase role="special">,</phrase> <phrase role="special">...);</phrase>
|
|
</programlisting>
|
|
<para>
|
|
The third argument of <code><phrase role="identifier">makecontext</phrase><phrase
|
|
role="special">()</phrase></code> specifies the number of integer arguments
|
|
that follow which will require function pointer cast if <code><phrase role="identifier">func</phrase></code>
|
|
will accept those arguments which is undefined in C99 <footnote id="context.rationale.other_apis_.f1">
|
|
<para>
|
|
ISO/IEC 9899:1999, 2005, J.2
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
<code><phrase role="identifier">ucontext_t</phrase></code> preserves signal
|
|
mask between context switches which involves system calls consuming a lot
|
|
of CPU cycles (ucontext_t is slower by perfomance_link[factor 13x] relative
|
|
to <code><phrase role="identifier">fcontext_t</phrase></code>).
|
|
</para>
|
|
<bridgehead renderas="sect4" id="context.rationale.other_apis_.h2">
|
|
<phrase id="context.rationale.other_apis_.windows_fibers"/><link linkend="context.rationale.other_apis_.windows_fibers">Windows
|
|
fibers</link>
|
|
</bridgehead>
|
|
<para>
|
|
A drawback of Windows Fiber API is that <code><phrase role="identifier">CreateFiber</phrase><phrase
|
|
role="special">()</phrase></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><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
|
|
role="special">()</phrase></code> if <code><phrase role="identifier">SwitchFiber</phrase><phrase
|
|
role="special">()</phrase></code> is called for a thread which has not been
|
|
converted to a fiber. For the same reason <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
|
|
role="special">()</phrase></code> must be called after return from <code><phrase
|
|
role="identifier">SwitchFiber</phrase><phrase role="special">()</phrase></code>
|
|
if the thread was forced to be converted to a fiber before (which is inefficient).
|
|
</para>
|
|
<programlisting><phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">is_a_fiber</phrase><phrase role="special">()</phrase> <phrase role="special">)</phrase>
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="identifier">ConvertThreadToFiber</phrase><phrase role="special">(</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">SwitchToFiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">ConvertFiberToThread</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">}</phrase>
|
|
</programlisting>
|
|
<para>
|
|
If the condition <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase
|
|
role="special">>=</phrase> <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code>
|
|
is met function <code><phrase role="identifier">IsThreadAFiber</phrase><phrase
|
|
role="special">()</phrase></code> is provided in order to detect if the current
|
|
thread was already converted. Unfortunately Windows XP + SP 2/3 defines
|
|
<code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase role="special">>=</phrase>
|
|
<phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code> without providing
|
|
<code><phrase role="identifier">IsThreadAFiber</phrase><phrase role="special">()</phrase></code>.
|
|
</para>
|
|
</section>
|
|
<section id="context.rationale.x86_and_floating_point_env">
|
|
<title><link linkend="context.rationale.x86_and_floating_point_env">x86 and
|
|
floating-point env</link></title>
|
|
<bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h0">
|
|
<phrase id="context.rationale.x86_and_floating_point_env.i386"/><link linkend="context.rationale.x86_and_floating_point_env.i386">i386</link>
|
|
</bridgehead>
|
|
<para>
|
|
"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 id="context.rationale.x86_and_floating_point_env.f0">
|
|
<para>
|
|
'Calling Conventions', Agner Fog
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h1">
|
|
<phrase id="context.rationale.x86_and_floating_point_env.x86_64"/><link linkend="context.rationale.x86_and_floating_point_env.x86_64">x86_64</link>
|
|
</bridgehead>
|
|
<bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h2">
|
|
<phrase id="context.rationale.x86_and_floating_point_env.windows"/><link
|
|
linkend="context.rationale.x86_and_floating_point_env.windows">Windows</link>
|
|
</bridgehead>
|
|
<para>
|
|
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 id="context.rationale.x86_and_floating_point_env.f1">
|
|
<para>
|
|
<ulink url="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx">MSDN
|
|
article 'MxCsr'</ulink>
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<para>
|
|
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 id="context.rationale.x86_and_floating_point_env.f2">
|
|
<para>
|
|
<ulink url="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx">MSDN
|
|
article 'FpCsr'</ulink>
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<para>
|
|
"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 id="context.rationale.x86_and_floating_point_env.f3">
|
|
<para>
|
|
<ulink url="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx">MSDN
|
|
article 'Legacy Floating-Point Support'</ulink>
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<para>
|
|
"The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
|
|
<footnote id="context.rationale.x86_and_floating_point_env.f4">
|
|
<para>
|
|
'Calling Conventions', Agner Fog
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
<para>
|
|
"XMM6-XMM15 must be preserved" <footnote id="context.rationale.x86_and_floating_point_env.f5">
|
|
<para>
|
|
<ulink url="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx">MSDN
|
|
article 'Register Usage'</ulink>
|
|
</para>
|
|
</footnote>
|
|
</para>
|
|
<bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h3">
|
|
<phrase id="context.rationale.x86_and_floating_point_env.sysv"/><link linkend="context.rationale.x86_and_floating_point_env.sysv">SysV</link>
|
|
</bridgehead>
|
|
<para>
|
|
"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 id="context.rationale.x86_and_floating_point_env.f6">
|
|
<para>
|
|
SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4,
|
|
3.2.1
|
|
</para>
|
|
</footnote>.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section id="context.reference">
|
|
<title><link linkend="context.reference">Reference</link></title>
|
|
<bridgehead renderas="sect3" id="context.reference.h0">
|
|
<phrase id="context.reference.arm"/><link linkend="context.reference.arm">ARM</link>
|
|
</bridgehead>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
AAPCS ABI: Procedure Call Standard for the ARM Architecture
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<bridgehead renderas="sect3" id="context.reference.h1">
|
|
<phrase id="context.reference.mips"/><link linkend="context.reference.mips">MIPS</link>
|
|
</bridgehead>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<bridgehead renderas="sect3" id="context.reference.h2">
|
|
<phrase id="context.reference.powerpc32"/><link linkend="context.reference.powerpc32">PowerPC32</link>
|
|
</bridgehead>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<bridgehead renderas="sect3" id="context.reference.h3">
|
|
<phrase id="context.reference.powerpc64"/><link linkend="context.reference.powerpc64">PowerPC64</link>
|
|
</bridgehead>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
SYSV ABI: PowerPC User Instruction Set Architecture, Book I
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<bridgehead renderas="sect3" id="context.reference.h4">
|
|
<phrase id="context.reference.x86_32"/><link linkend="context.reference.x86_32">X86-32</link>
|
|
</bridgehead>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture
|
|
Processor Supplement
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">Calling
|
|
Conventions</ulink>
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<bridgehead renderas="sect3" id="context.reference.h5">
|
|
<phrase id="context.reference.x86_64"/><link linkend="context.reference.x86_64">X86-64</link>
|
|
</bridgehead>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor
|
|
Supplement
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx">x64
|
|
Software Conventions</ulink>
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section id="context.acknowledgements">
|
|
<title><link linkend="context.acknowledgements">Acknowledgments</link></title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</section>
|
|
</library>
|