mirror of https://gitee.com/bigwinds/arangodb
3602 lines
269 KiB
XML
3602 lines
269 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/03/04 17:27:33 $"
|
|
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> 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> provides the means to suspend the current
|
|
execution path and to transfer execution control, thereby permitting another
|
|
context to run on the current thread. This state full transfer mechanism enables
|
|
a context to suspend execution from within nested functions and, later, to
|
|
resume from where it was suspended. While the execution path represented by
|
|
a <emphasis>execution_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.ecv2">
|
|
<title><anchor id="ecv2"/><link linkend="context.ecv2">Class execution_context
|
|
(version 2)</link></title>
|
|
<note>
|
|
<para>
|
|
This class is enabled per default.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
Class <emphasis>execution_context</emphasis> encapsulates context switching
|
|
and manages the associated 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 is responsible
|
|
for managing context' stack. The address of the control structure is stored
|
|
in the first frame of context' stack (e.g. it can not directly accessed from
|
|
within <emphasis>execution_context</emphasis>). In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis>
|
|
(v1)</link> the ownership of the control structure is not shared (no member
|
|
variable to control structure in <emphasis>execution_context</emphasis>).
|
|
<emphasis>execution_context</emphasis> keeps internally a state that is moved
|
|
by a call of <emphasis>execution_context::operator()</emphasis> (<code><phrase
|
|
role="special">*</phrase><phrase role="keyword">this</phrase></code> will be
|
|
invalidated), e.g. after a calling <emphasis>execution_context::operator()</emphasis>,
|
|
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
can not be used for an additional context switch.
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> is only move-constructible and move-assignable.
|
|
</para>
|
|
<para>
|
|
The moved state is assigned to a new instance of <emphasis>execution_context</emphasis>.
|
|
This object becomes the first argument of the context-function, if the context
|
|
was resumed the first time, or the first element in a tuple returned by <emphasis>execution_context::operator()</emphasis>
|
|
that has been called in the resumed context. In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis>
|
|
(v1)</link>, the context switch is faster because no global pointer etc. is
|
|
involved.
|
|
</para>
|
|
<important>
|
|
<para>
|
|
Segmented stacks are not supported by <emphasis>execution_context</emphasis>
|
|
(v2).
|
|
</para>
|
|
</important>
|
|
<para>
|
|
On return the context-function of the current context has to specify an <emphasis>execution_context</emphasis>
|
|
to which the execution control is transferred after termination of the current
|
|
context.
|
|
</para>
|
|
<para>
|
|
If an instance with valid state goes out of scope and the context-function
|
|
has not yet returned, the stack is traversed in order to access the control
|
|
structure (address stored at the first stack frame) and context' stack is deallocated
|
|
via the <emphasis>StackAllocator</emphasis>. The stack walking makes the destruction
|
|
of <emphasis>execution_context</emphasis> slow and should be prevented if possible.
|
|
</para>
|
|
<para>
|
|
<emphasis>execution_context</emphasis> expects a <emphasis>context-function</emphasis>
|
|
with signature <code><phrase role="identifier">execution_context</phrase><phrase
|
|
role="special">(</phrase><phrase role="identifier">execution_context</phrase>
|
|
<phrase role="identifier">ctx</phrase><phrase role="special">,</phrase> <phrase
|
|
role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase
|
|
role="identifier">args</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>execution_context::operator()</emphasis>
|
|
on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>)
|
|
and <code><phrase role="identifier">args</phrase></code> are the data passed
|
|
to <emphasis>execution_context::operator()</emphasis>. The return value represents
|
|
the execution_context that has to be resumed, after termiantion of this context.
|
|
</para>
|
|
<para>
|
|
Benefits of <link linkend="ecv2"><emphasis>execution_context</emphasis> (v2)</link>
|
|
over <link linkend="ecv1"><emphasis>execution_context</emphasis> (v1)</link>
|
|
are: faster context switch, type-safety of passed/returned arguments.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ecv2.h0">
|
|
<phrase id="context.ecv2.usage_of__emphasis_execution_context__emphasis_"/><link
|
|
linkend="context.ecv2.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="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase>
|
|
<phrase role="special">[</phrase><phrase role="identifier">n</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</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="keyword">auto</phrase> <phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">sink</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="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="keyword">return</phrase> <phrase role="identifier">sink</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="keyword">auto</phrase> <phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">source</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</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="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>
|
|
<para>
|
|
This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>
|
|
as a generator. The context <code><phrase role="identifier">sink</phrase></code>
|
|
represents the <emphasis>main</emphasis>-context (function <emphasis>main()</emphasis>
|
|
running). <code><phrase role="identifier">sink</phrase></code> is generated
|
|
by the framework (first element of lambda's parameter list). Because the state
|
|
is invalidated (== changed) by each call of <emphasis>execution_context::operator()</emphasis>,
|
|
the new state of the <emphasis>execution_context</emphasis>, returned by <emphasis>execution_context::operator()</emphasis>,
|
|
needs to be assigned to <code><phrase role="identifier">sink</phrase></code>
|
|
after each call.
|
|
</para>
|
|
<para>
|
|
The lambda that calculates the Fibonacci numbers is executed inside the context
|
|
represented by <code><phrase role="identifier">source</phrase></code>. Calculated
|
|
Fibonacci numbers are transferred between the two context' via expression
|
|
<emphasis>sink(a)</emphasis> (and returned by <emphasis>source()</emphasis>).
|
|
Note that this example represents a <emphasis>generator</emphasis> thus the
|
|
value transferred into the lambda via <emphasis>source()</emphasis> is not
|
|
used. Using <emphasis>boost::optional<></emphasis> as transferred type,
|
|
might also appropriate to express this fact.
|
|
</para>
|
|
<para>
|
|
The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
|
|
role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code>
|
|
remain their values during each context switch (<emphasis>yield(a)</emphasis>).
|
|
This is possible due <code><phrase role="identifier">source</phrase></code>
|
|
has its own stack and the stack is exchanged by each context switch.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ecv2.h1">
|
|
<phrase id="context.ecv2.parameter_passing"/><link linkend="context.ecv2.parameter_passing">parameter
|
|
passing</link>
|
|
</bridgehead>
|
|
<para>
|
|
With <code><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase
|
|
role="keyword">void</phrase><phrase role="special">></phrase></code> no
|
|
data will be transferred, only the context switch is executed.
|
|
</para>
|
|
<programlisting><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="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx1</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="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside ctx1\n"</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">();</phrase>
|
|
<phrase role="special">});</phrase>
|
|
<phrase role="identifier">ctx1</phrase><phrase role="special">();</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase>
|
|
</programlisting>
|
|
<para>
|
|
<code><phrase role="identifier">ctx1</phrase><phrase role="special">()</phrase></code>
|
|
resumes <code><phrase role="identifier">ctx1</phrase></code>, e.g. the lambda
|
|
passed at the constructor of <code><phrase role="identifier">ctx1</phrase></code>
|
|
is entered. Argument <code><phrase role="identifier">ctx2</phrase></code> represents
|
|
the context that has been suspended with the invocation of <code><phrase role="identifier">ctx1</phrase><phrase
|
|
role="special">()</phrase></code>. When the lambda returns <code><phrase role="identifier">ctx2</phrase></code>,
|
|
context <code><phrase role="identifier">ctx1</phrase></code> will be terminated
|
|
while the context represented by <code><phrase role="identifier">ctx2</phrase></code>
|
|
is resumed, hence the control of execution returns from <code><phrase role="identifier">ctx1</phrase><phrase
|
|
role="special">()</phrase></code>.
|
|
</para>
|
|
<para>
|
|
The arguments passed to <emphasis>execution_context::operator()</emphasis>,
|
|
in one context, is passed as the last arguments 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 arguments 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="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="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx1</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="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside ctx1, j == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</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="number">1</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">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase>
|
|
<phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">2</phrase>
|
|
</programlisting>
|
|
<para>
|
|
<code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase
|
|
role="identifier">i</phrase><phrase role="special">)</phrase></code> enters
|
|
the lambda in context <code><phrase role="identifier">ctx1</phrase></code>
|
|
with argument <code><phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase
|
|
role="number">1</phrase></code>. The expression <code><phrase role="identifier">ctx2</phrase><phrase
|
|
role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase
|
|
role="number">1</phrase><phrase role="special">)</phrase></code> resumes the
|
|
context represented by <code><phrase role="identifier">ctx2</phrase></code>
|
|
and transfers back an integer of <code><phrase role="identifier">j</phrase><phrase
|
|
role="special">+</phrase><phrase role="number">1</phrase></code>. On return
|
|
of <code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase
|
|
role="identifier">i</phrase><phrase role="special">)</phrase></code>, the variable
|
|
<code><phrase role="identifier">i</phrase></code> contains the value of <code><phrase
|
|
role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase></code>.
|
|
</para>
|
|
<para>
|
|
If more than one argument has to be transferred, the signature of the context-function
|
|
is simply extended.
|
|
</para>
|
|
<programlisting><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="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx1</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="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">){</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside ctx1, i == %d j == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase>
|
|
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase role="identifier">j</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">-</phrase><phrase role="identifier">j</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="number">2</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase> <phrase role="special">=</phrase> <phrase role="number">1</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">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">,</phrase><phrase role="identifier">j</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i == %d j == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">2</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase>
|
|
<phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">3</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase>
|
|
</programlisting>
|
|
<para>
|
|
For use-cases, that require to transfer data of different type in each direction,
|
|
<emphasis>boost::variant<></emphasis> could be used.
|
|
</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="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</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">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="identifier">excptr_</phrase><phrase role="special">(),</phrase>
|
|
<phrase role="identifier">ctx_</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="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</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">ctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</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">data</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="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">data</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="identifier">data</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">data</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="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">bad_cast</phrase> <phrase role="keyword">const</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="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</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">data</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="identifier">data</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">data</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="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">get</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">data</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>
|
|
<para>
|
|
In the case of unidirectional transfer of data, <emphasis>boost::optional<></emphasis>
|
|
or a pointer are appropriate.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ecv2.h2">
|
|
<phrase id="context.ecv2.exception_handling"/><link linkend="context.ecv2.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 <emphasis>std::terminate()</emphasis>.
|
|
<emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
|
|
between different execution contexts.
|
|
</para>
|
|
<important>
|
|
<para>
|
|
Do not jump from inside a catch block and then re-throw the exception in
|
|
another execution context.
|
|
</para>
|
|
</important>
|
|
<anchor id="ecv2_ontop"/>
|
|
<bridgehead renderas="sect3" id="context.ecv2.h3">
|
|
<phrase id="context.ecv2.executing_function_on_top_of_a_context"/><link linkend="context.ecv2.executing_function_on_top_of_a_context">Executing
|
|
function on top of a context</link>
|
|
</bridgehead>
|
|
<para>
|
|
Sometimes it is useful to execute a new function on top of a resumed context.
|
|
For this purpose <emphasis>execution_context::operator()</emphasis> with first
|
|
argument <code><phrase role="identifier">exec_ontop_arg</phrase></code> has
|
|
to be used. The function passed as argument must return a tuple of execution_context
|
|
and arguments.
|
|
</para>
|
|
<programlisting><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="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">f1</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="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</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">"f1: entered first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</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">"f1: entered second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</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">"f1: entered third time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</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="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</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">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="keyword">int</phrase><phrase role="special">>,</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">f2</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="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</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">"f2: entered: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</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="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">make_tuple</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">ctx</phrase><phrase role="special">),-</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
|
|
<phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</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">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</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">"f1: returned first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</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">"f1: returned second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase>
|
|
<phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">5</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase>
|
|
</programlisting>
|
|
<para>
|
|
The expression <code><phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase
|
|
role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase
|
|
role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">,</phrase><phrase
|
|
role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase
|
|
role="special">)</phrase></code> executes <code><phrase role="identifier">f2</phrase><phrase
|
|
role="special">()</phrase></code> on top of context <code><phrase role="identifier">ctx</phrase></code>,
|
|
e.g. an additional stack frame is allocated on top of the context stack (in
|
|
front of <code><phrase role="identifier">f1</phrase><phrase role="special">()</phrase></code>).
|
|
<code><phrase role="identifier">f2</phrase><phrase role="special">()</phrase></code>
|
|
returns argument <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
|
|
that will returned by the second invocation of <code><phrase role="identifier">ctx</phrase><phrase
|
|
role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase
|
|
role="number">1</phrase><phrase role="special">)</phrase></code> in <code><phrase
|
|
role="identifier">f1</phrase><phrase role="special">()</phrase></code>.
|
|
</para>
|
|
<para>
|
|
Another option is to execute a function on top of the context that throws an
|
|
exception.
|
|
</para>
|
|
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">interrupt</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="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">interrupt</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="keyword">void</phrase> <phrase role="special">></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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">forward</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="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="special">>(</phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="special">{</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="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">f1</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="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">)</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1()"</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">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</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">interrupt</phrase> <phrase role="special">&</phrase> <phrase role="identifier">e</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">"f1(): interrupted"</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">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">e</phrase><phrase role="special">.</phrase><phrase role="identifier">ctx</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="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="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">f2</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="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
|
|
<phrase role="keyword">throw</phrase> <phrase role="identifier">interrupt</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">ctx</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="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="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase>
|
|
<phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">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">exec_ontop_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">()</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">()</phrase>
|
|
<phrase role="identifier">f1</phrase><phrase role="special">():</phrase> <phrase role="identifier">interrupted</phrase>
|
|
</programlisting>
|
|
<para>
|
|
In this example <code><phrase role="identifier">f2</phrase><phrase role="special">()</phrase></code>
|
|
is used to interrupt the <code><phrase role="keyword">for</phrase></code>-loop
|
|
in <code><phrase role="identifier">f1</phrase><phrase role="special">()</phrase></code>.
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ecv2.h4">
|
|
<phrase id="context.ecv2.stack_destruction"/><link linkend="context.ecv2.stack_destruction">Stack
|
|
destruction</link>
|
|
</bridgehead>
|
|
<para>
|
|
On construction of <emphasis>execution_context</emphasis> a stack is allocated.
|
|
If the <emphasis>context-function</emphasis> returns the stack will be destructed.
|
|
If the <emphasis>context-function</emphasis> has not yet returned and the destructor
|
|
of an valid <emphasis>execution_context</emphasis> instance (e.g. <emphasis>execution_context::operator
|
|
bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>)
|
|
is called, the stack will be destructed too.
|
|
</para>
|
|
<anchor id="ecv2_prealloc"/>
|
|
<bridgehead renderas="sect3" id="context.ecv2.h5">
|
|
<phrase id="context.ecv2.allocating_control_structures_on_top_of_stack"/><link
|
|
linkend="context.ecv2.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">// captured context</phrase>
|
|
<phrase role="identifier">execution_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.ecv2.h6">
|
|
<phrase id="context.ecv2.inverting_the_control_flow"/><link linkend="context.ecv2.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="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">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">></phrase> <phrase role="identifier">source</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">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">></phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase><phrase role="keyword">char</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">sink</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">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">ch</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">sink</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">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="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">sink</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">source</phrase><phrase role="special">(</phrase><phrase role="char">'\0'</phrase><phrase role="special">);</phrase>
|
|
<phrase role="identifier">source</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="keyword">char</phrase> <phrase role="identifier">c</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="identifier">c</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">source</phrase><phrase role="special">,</phrase><phrase role="identifier">c</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase><phrase role="char">'\0'</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>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.ecv2.h7">
|
|
<phrase id="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
|
|
linkend="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
|
|
<code><phrase role="identifier">execution_context</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="special">{};</phrase>
|
|
<phrase role="keyword">const</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">{};</phrase>
|
|
|
|
<phrase role="keyword">template</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">class</phrase> <phrase role="identifier">execution_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">Params</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</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">Params</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</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">Params</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</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">Params</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">segemented_stack</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</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">Params</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">segmented</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">)=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</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">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="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="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">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="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">execution_context</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Args</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</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="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="ecv2_constructor_bridgehead">
|
|
<phrase id="ecv2_constructor"/>
|
|
<link linkend="ecv2_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">Params</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</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">Params</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</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">Params</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">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</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()).
|
|
The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
|
|
is used to create a user defined data <link linkend="ecv2_prealloc">(for
|
|
instance additional control structures)</link> on top of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv2_destructor destructor_bridgehead">
|
|
<phrase id="ecv2_destructor destructor"/>
|
|
<link linkend="ecv2_destructor
|
|
destructor">Destructor</link>
|
|
</bridgehead>
|
|
</para>
|
|
<programlisting><phrase role="special">~</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">();</phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code> is a valid context, e.g. <emphasis>execution_context::operator
|
|
bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv2_move constructor_bridgehead">
|
|
<phrase id="ecv2_move constructor"/>
|
|
<link linkend="ecv2_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="ecv2_move assignment_bridgehead">
|
|
<phrase id="ecv2_move assignment"/>
|
|
<link linkend="ecv2_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="ecv2_operator_bool_bridgehead">
|
|
<phrase id="ecv2_operator_bool"/>
|
|
<link linkend="ecv2_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="ecv2_operator_not_bridgehead">
|
|
<phrase id="ecv2_operator_not"/>
|
|
<link linkend="ecv2_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="ecv2_operator_call_bridgehead">
|
|
<phrase id="ecv2_operator_call"/>
|
|
<link linkend="ecv2_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">execution_context</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="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of generic execution_context template</phrase>
|
|
|
|
<phrase role="identifier">execution_context</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="comment">// member of execution_context< void ></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 arguments, <code><phrase role="special">...</phrase> <phrase
|
|
role="identifier">args</phrase></code>, are 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.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
The tuple of execution_context and returned arguments 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 and a execution_context representing
|
|
the context that has been suspended.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Note:</term>
|
|
<listitem>
|
|
<para>
|
|
The returned execution_context indicates if the suspended context has
|
|
terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
|
|
If the returned execution_context has terminated no data are transferred
|
|
in the returned tuple.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv2_operator_call_ontop_bridgehead">
|
|
<phrase id="ecv2_operator_call_ontop"/>
|
|
<link linkend="ecv2_operator_call_ontop">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">Fn</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">execution_context</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="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="identifier">args</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of generic execution_context</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="identifier">execution_context</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="comment">// member of execution_context< void ></phrase>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Same as <emphasis>execution_context::operator()</emphasis>. Additionally,
|
|
function <code><phrase role="identifier">fn</phrase></code> is executed
|
|
in the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
(e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code>
|
|
is allocated on stack of <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
The tuple of execution_context and returned arguments 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 and a execution_context representing
|
|
the context that has been suspended .
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Note:</term>
|
|
<listitem>
|
|
<para>
|
|
The tuple of execution_context and returned arguments from <code><phrase
|
|
role="identifier">fn</phrase></code> are passed as arguments to the context-function
|
|
of resumed context (if the context is entered the first time) or those
|
|
arguments are returned from <code><phrase role="identifier">execution_context</phrase><phrase
|
|
role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
|
|
role="special">()</phrase></code> within the resumed context.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Note:</term>
|
|
<listitem>
|
|
<para>
|
|
Function <code><phrase role="identifier">fn</phrase></code> needs to
|
|
return a tuple of execution_context and arguments (<link linkend="ecv2_ontop">see
|
|
description</link>).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Note:</term>
|
|
<listitem>
|
|
<para>
|
|
The context calling this function must not be destroyed before the arguments,
|
|
that will be returned from <code><phrase role="identifier">fn</phrase></code>,
|
|
are preserved at least in the stack frame of the resumed context.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Note:</term>
|
|
<listitem>
|
|
<para>
|
|
The returned execution_context indicates if the suspended context has
|
|
terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
|
|
If the returned execution_context has terminated no data are transferred
|
|
in the returned tuple.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv2_operator_equal_bridgehead">
|
|
<phrase id="ecv2_operator_equal"/>
|
|
<link linkend="ecv2_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="ecv2_operator_notequal_bridgehead">
|
|
<phrase id="ecv2_operator_notequal"/>
|
|
<link linkend="ecv2_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="ecv2_operator_less_bridgehead">
|
|
<phrase id="ecv2_operator_less"/>
|
|
<link linkend="ecv2_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="ecv2_operator_greater_bridgehead">
|
|
<phrase id="ecv2_operator_greater"/>
|
|
<link linkend="ecv2_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="ecv2_operator_lesseq_bridgehead">
|
|
<phrase id="ecv2_operator_lesseq"/>
|
|
<link linkend="ecv2_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="ecv2_operator_greatereq_bridgehead">
|
|
<phrase id="ecv2_operator_greatereq"/>
|
|
<link linkend="ecv2_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="ecv2__bridgehead">
|
|
<phrase id="ecv2_"/>
|
|
<link linkend="ecv2_">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.ecv1">
|
|
<title><anchor id="ecv1"/><link linkend="context.ecv1">Class execution_context
|
|
(version 1)</link></title>
|
|
<note>
|
|
<para>
|
|
This class is only enabled if property <emphasis>segmented-stacks=on</emphasis>
|
|
(enables segmented stacks) or compiler flag <emphasis>BOOST_EXECUTION_CONTEXT=1</emphasis>
|
|
is specified at b2-commandline.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
Class <emphasis>execution_context</emphasis> encapsulates context switching
|
|
and manages the associated 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 is responsible
|
|
for managing context' 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,
|
|
accessed by <emphasis>execution_context::current()</emphasis>, pointing to
|
|
the active context. On each context switch the pointer is updated. The usage
|
|
of this global pointer makes the context switch a little bit slower (due access
|
|
of thread local storage) but has some advantages. It allows to access the control
|
|
structure of the current active context from arbitrary code paths required
|
|
in order to support segmented stacks, which require to call certain maintenance
|
|
functions (like __splitstack_getcontext() etc.) before each context switch
|
|
(each context switch exchanges the stack).
|
|
</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="ecv1_operator_call"> <code>ecv1::operator()()</code></link>).
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ecv1.h0">
|
|
<phrase id="context.ecv1.usage_of__emphasis_execution_context__emphasis_"/><link
|
|
linkend="context.ecv1.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="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">sink</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="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">source</phrase><phrase role="special">(</phrase>
|
|
<phrase role="special">[</phrase><phrase role="identifier">n</phrase><phrase role="special">,&</phrase><phrase role="identifier">sink</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">sink</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special"><<*(</phrase><phrase role="keyword">int</phrase><phrase role="special">*)</phrase><phrase role="identifier">source</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>
|
|
<para>
|
|
This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>.
|
|
The context <code><phrase role="identifier">sink</phrase></code>, returned
|
|
by <emphasis>execution_context::current()</emphasis>, represents the <emphasis>main</emphasis>-context
|
|
(function <emphasis>main()</emphasis> running) and is one of the captured parameters
|
|
in the lambda expression. The lambda that calculates the Fibonacci numbers
|
|
is executed inside the context represented by <code><phrase role="identifier">source</phrase></code>.
|
|
Calculated Fibonacci numbers are transferred between the two context' via expression
|
|
<emphasis>sink(&a)</emphasis> (and returned by <emphasis>source()</emphasis>).
|
|
</para>
|
|
<para>
|
|
The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
|
|
role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code>
|
|
remain their values during each context switch (<emphasis>yield(a)</emphasis>).
|
|
This is possible because <code><phrase role="identifier">ctx</phrase></code>
|
|
owns a stack (exchanged by context switch).
|
|
</para>
|
|
<bridgehead renderas="sect3" id="context.ecv1.h1">
|
|
<phrase id="context.ecv1.inverting_the_control_flow"/><link linkend="context.ecv1.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="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="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">source</phrase><phrase role="special">(</phrase>
|
|
<phrase role="special">[&</phrase><phrase role="identifier">sink</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">sink</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">sink</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="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">sink</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">source</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="identifier">vp</phrase><phrase role="special">));</phrase>
|
|
<phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</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>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>
|
|
<anchor id="ecv1_prealloc"/>
|
|
<bridgehead renderas="sect3" id="context.ecv1.h2">
|
|
<phrase id="context.ecv1.allocating_control_structures_on_top_of_stack"/><link
|
|
linkend="context.ecv1.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.ecv1.h3">
|
|
<phrase id="context.ecv1.exception_handling"/><link linkend="context.ecv1.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 <emphasis>std::terminate()</emphasis>.
|
|
<emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
|
|
between different execution contexts.
|
|
</para>
|
|
<important>
|
|
<para>
|
|
Do not jump from inside a catch block and then re-throw the exception in
|
|
another execution context.
|
|
</para>
|
|
</important>
|
|
<bridgehead renderas="sect3" id="context.ecv1.h4">
|
|
<phrase id="context.ecv1.parameter_passing"/><link linkend="context.ecv1.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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">bad_cast</phrase> <phrase role="keyword">const</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.ecv1.h5">
|
|
<phrase id="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
|
|
linkend="context.ecv1.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">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="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">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="ecv1_current_bridgehead">
|
|
<phrase id="ecv1_current"/>
|
|
<link linkend="ecv1_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="ecv1_constructor_bridgehead">
|
|
<phrase id="ecv1_constructor"/>
|
|
<link linkend="ecv1_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()).
|
|
The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
|
|
is used to create a user defined data <link linkend="ecv1_prealloc">(for
|
|
instance additional control structures)</link> on top of the stack.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv1_copy constructor_bridgehead">
|
|
<phrase id="ecv1_copy constructor"/>
|
|
<link linkend="ecv1_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
|
|
control structure 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="ecv1_move constructor_bridgehead">
|
|
<phrase id="ecv1_move constructor"/>
|
|
<link linkend="ecv1_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 control structure 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="ecv1_copy assignment_bridgehead">
|
|
<phrase id="ecv1_copy assignment"/>
|
|
<link linkend="ecv1_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>,
|
|
control structure is shared.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv1_move assignment_bridgehead">
|
|
<phrase id="ecv1_move assignment"/>
|
|
<link linkend="ecv1_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 control structure 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="ecv1_operator_bool_bridgehead">
|
|
<phrase id="ecv1_operator_bool"/>
|
|
<link linkend="ecv1_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 control structure.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv1_operator_not_bridgehead">
|
|
<phrase id="ecv1_operator_not"/>
|
|
<link linkend="ecv1_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 control structure.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Throws:</term>
|
|
<listitem>
|
|
<para>
|
|
Nothing.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv1_operator_call_bridgehead">
|
|
<phrase id="ecv1_operator_call"/>
|
|
<link linkend="ecv1_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>
|
|
</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>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Note:</term>
|
|
<listitem>
|
|
<para>
|
|
The behaviour is undefined if <code><phrase role="keyword">operator</phrase><phrase
|
|
role="special">()()</phrase></code> is called while <emphasis>execution_context::current()</emphasis>
|
|
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 <emphasis>execution_context::operator()</emphasis>,
|
|
if any.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv1_operator_call_ontop_bridgehead">
|
|
<phrase id="ecv1_operator_call_ontop"/>
|
|
<link linkend="ecv1_operator_call_ontop">Member
|
|
function <code>operator(exec_ontop_arg_t)</code>()</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">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="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>
|
|
</programlisting>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Same as <emphasis>execution_context::operator()</emphasis>. Additionally,
|
|
function <code><phrase role="identifier">fn</phrase></code> is executed
|
|
with arguments <code><phrase role="identifier">vp</phrase></code> in
|
|
the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
(e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code>
|
|
is allocated on stack of <code><phrase role="special">*</phrase><phrase
|
|
role="keyword">this</phrase></code>).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Returns:</term>
|
|
<listitem>
|
|
<para>
|
|
The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>,
|
|
if any.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
<bridgehead renderas="sect4" id="ecv1_operator_equal_bridgehead">
|
|
<phrase id="ecv1_operator_equal"/>
|
|
<link linkend="ecv1_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="ecv1_operator_notequal_bridgehead">
|
|
<phrase id="ecv1_operator_notequal"/>
|
|
<link linkend="ecv1_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="ecv1_operator_less_bridgehead">
|
|
<phrase id="ecv1_operator_less"/>
|
|
<link linkend="ecv1_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="ecv1_operator_greater_bridgehead">
|
|
<phrase id="ecv1_operator_greater"/>
|
|
<link linkend="ecv1_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="ecv1_operator_lesseq_bridgehead">
|
|
<phrase id="ecv1_operator_lesseq"/>
|
|
<link linkend="ecv1_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="ecv1_operator_greatereq_bridgehead">
|
|
<phrase id="ecv1_operator_greatereq"/>
|
|
<link linkend="ecv1_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="ecv1__bridgehead">
|
|
<phrase id="ecv1_"/>
|
|
<link linkend="ecv1_">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.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.pooled_fixedsize">
|
|
<title><link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link></title>
|
|
<para>
|
|
<emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>pooled_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 managed internally by <ulink
|
|
url="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html"><code><phrase
|
|
role="identifier">boost</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">pool</phrase><phrase role="special"><></phrase></code></ulink>.
|
|
</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">pooled_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_pooled_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_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">stack_size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">(),</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase> <phrase role="special">=</phrase> <phrase role="number">32</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase> <phrase role="special">=</phrase> <phrase role="number">0</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_pooled_fixedsize_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">pooled_fixedsize_stack</phrase><phrase role="special">;</phrase>
|
|
</programlisting>
|
|
<bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h0">
|
|
<phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"/><link
|
|
linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"><code><phrase
|
|
role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase
|
|
role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
|
|
<phrase role="identifier">stack_size</phrase><phrase role="special">,</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
|
|
role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase><phrase
|
|
role="special">)</phrase></code></link>
|
|
</bridgehead>
|
|
<variablelist>
|
|
<title></title>
|
|
<varlistentry>
|
|
<term>Preconditions:</term>
|
|
<listitem>
|
|
<para>
|
|
<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">stack_size</phrase><phrase role="special">)</phrase></code>
|
|
and <code><phrase role="number">0</phrase> <phrase role="special"><</phrase>
|
|
<phrase role="identifier">nest_size</phrase></code>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Effects:</term>
|
|
<listitem>
|
|
<para>
|
|
Allocates memory of at least <code><phrase role="identifier">stack_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. Argument <code><phrase role="identifier">next_size</phrase></code>
|
|
determines the number of stacks to request from the system the first
|
|
time that <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
|
|
needs to allocate system memory. The third argument <code><phrase role="identifier">max_size</phrase></code>
|
|
controls how many memory might be allocated for stacks - a value of
|
|
zero means no uper limit.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h1">
|
|
<phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
|
|
linkend="context.stack.pooled_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="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">stack_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">stack_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.pooled_fixedsize.h2">
|
|
<phrase id="context.stack.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
|
|
linkend="context.stack.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><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="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 property <code><phrase role="identifier">segmented</phrase><phrase
|
|
role="special">-</phrase><phrase role="identifier">stacks</phrase></code>,
|
|
e.g. <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis> at
|
|
b2/bjam command line.
|
|
</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 (v1)
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
execution_context (v2)
|
|
</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 (aarch32)
|
|
</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>
|
|
arm (aarch64)
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
AAPCS|ELF
|
|
</para>
|
|
</entry>
|
|
<entry>
|
|
<para>
|
|
-
|
|
</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>
|