1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
3 <library id="context" name="Context" dirname="context" last-revision="$Date: 2016/11/27 06:34:58 $"
4 xmlns:xi="http://www.w3.org/2001/XInclude">
8 <firstname>Oliver</firstname> <surname>Kowalke</surname>
12 <year>2014</year> <holder>Oliver Kowalke</holder>
14 <legalnotice id="context.legal">
16 Distributed under the Boost Software License, Version 1.0. (See accompanying
17 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>)
21 C++ Library for swiching different user ctx
23 <librarycategory name="category:text"></librarycategory>
25 <title>Context</title>
26 <section id="context.overview">
27 <title><link linkend="context.overview">Overview</link></title>
29 <emphasis role="bold">Boost.Context</emphasis> is a foundational library that
30 provides a sort of cooperative multitasking on a single thread. By providing
31 an abstraction of the current execution state in the current thread, including
32 the stack (with local variables) and stack pointer, all registers and CPU flags,
33 and the instruction pointer, a <emphasis>execution_context</emphasis> represents
34 a specific point in the application's execution path. This is useful for building
35 higher-level abstractions, like <emphasis>coroutines</emphasis>, <emphasis>cooperative
36 threads (userland threads)</emphasis> or an equivalent to <ulink url="http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx">C#
37 keyword <emphasis>yield</emphasis></ulink> in C++.
40 <emphasis>execution_context</emphasis> provides the means to suspend the current
41 execution path and to transfer execution control, thereby permitting another
42 context to run on the current thread. This state full transfer mechanism enables
43 a context to suspend execution from within nested functions and, later, to
44 resume from where it was suspended. While the execution path represented by
45 a <emphasis>execution_context</emphasis> only runs on a single thread, it can
46 be migrated to another thread at any given time.
49 A context switch between threads requires system calls (involving the OS kernel),
50 which can cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring
51 control among them requires only few CPU cycles because it does not involve
52 system calls as it is done within a single thread.
55 In order to use the classes and functions described here, you can either include
56 the specific headers specified by the descriptions of each class or function,
57 or include the master library header:
59 <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>
62 which includes all the other headers in turn.
65 All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>.
69 This library requires C++11!
73 <section id="context.requirements">
74 <title><link linkend="context.requirements">Requirements</link></title>
76 <emphasis role="bold">Boost.Context</emphasis> must be built for the particular
77 compiler(s) and CPU architecture(s)s being targeted. <emphasis role="bold">Boost.Context</emphasis>
78 includes assembly code and, therefore, requires GNU as and GNU preprocesspr
79 for supported POSIX systems, MASM for Windows/x86 systems and ARMasm for Windows/arm
84 MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit.
89 Please note that <code><phrase role="identifier">address</phrase><phrase
90 role="special">-</phrase><phrase role="identifier">model</phrase><phrase
91 role="special">=</phrase><phrase role="number">64</phrase></code> must be
92 given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit
93 code will be generated.
98 For cross-compiling the lib you must specify certain additional properties
99 at bjam command line: <code><phrase role="identifier">target</phrase><phrase
100 role="special">-</phrase><phrase role="identifier">os</phrase></code>, <code><phrase
101 role="identifier">abi</phrase></code>, <code><phrase role="identifier">binary</phrase><phrase
102 role="special">-</phrase><phrase role="identifier">format</phrase></code>,
103 <code><phrase role="identifier">architecture</phrase></code> and <code><phrase
104 role="identifier">address</phrase><phrase role="special">-</phrase><phrase
105 role="identifier">model</phrase></code>.
110 For safe SEH the property 'asmflags=\safeseh' must be specified at bjam command
115 <section id="context.ecv2">
116 <title><anchor id="ecv2"/><link linkend="context.ecv2">Class execution_context
117 (version 2)</link></title>
120 This class is enabled per default.
124 Class <emphasis>execution_context</emphasis> encapsulates context switching
125 and manages the associated context' stack (allocation/deallocation).
128 <emphasis>execution_context</emphasis> allocates the context stack (using its
129 <link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument)
130 and creates a control structure on top of it. This structure is responsible
131 for managing context' stack. The address of the control structure is stored
132 in the first frame of context' stack (e.g. it can not directly accessed from
133 within <emphasis>execution_context</emphasis>). In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis>
134 (v1)</link> the ownership of the control structure is not shared (no member
135 variable to control structure in <emphasis>execution_context</emphasis>).
136 <emphasis>execution_context</emphasis> keeps internally a state that is moved
137 by a call of <emphasis>execution_context::operator()</emphasis> (<code><phrase
138 role="special">*</phrase><phrase role="keyword">this</phrase></code> will be
139 invalidated), e.g. after a calling <emphasis>execution_context::operator()</emphasis>,
140 <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
141 can not be used for an additional context switch.
144 <emphasis>execution_context</emphasis> is only move-constructible and move-assignable.
147 The moved state is assigned to a new instance of <emphasis>execution_context</emphasis>.
148 This object becomes the first argument of the context-function, if the context
149 was resumed the first time, or the first element in a tuple returned by <emphasis>execution_context::operator()</emphasis>
150 that has been called in the resumed context. In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis>
151 (v1)</link>, the context switch is faster because no global pointer etc. is
156 Segmented stacks are not supported by <emphasis>execution_context</emphasis>
161 On return the context-function of the current context has to specify an <emphasis>execution_context</emphasis>
162 to which the execution control is transferred after termination of the current
166 If an instance with valid state goes out of scope and the context-function
167 has not yet returned, the stack is traversed in order to access the control
168 structure (address stored at the first stack frame) and context' stack is deallocated
169 via the <emphasis>StackAllocator</emphasis>. The stack walking makes the destruction
170 of <emphasis>execution_context</emphasis> slow and should be prevented if possible.
173 <emphasis>execution_context</emphasis> expects a <emphasis>context-function</emphasis>
174 with signature <code><phrase role="identifier">execution_context</phrase><phrase
175 role="special">(</phrase><phrase role="identifier">execution_context</phrase>
176 <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase> <phrase
177 role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase
178 role="identifier">args</phrase><phrase role="special">)</phrase></code>. The
179 parameter <code><phrase role="identifier">ctx</phrase></code> represents the
180 context from which this context was resumed (e.g. that has called <emphasis>execution_context::operator()</emphasis>
181 on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>)
182 and <code><phrase role="identifier">args</phrase></code> are the data passed
183 to <emphasis>execution_context::operator()</emphasis>. The return value represents
184 the execution_context that has to be resumed, after termiantion of this context.
187 Benefits of <link linkend="ecv2"><emphasis>execution_context</emphasis> (v2)</link>
188 over <link linkend="ecv1"><emphasis>execution_context</emphasis> (v1)</link>
189 are: faster context switch, type-safety of passed/returned arguments.
191 <bridgehead renderas="sect3" id="context.ecv2.h0">
192 <phrase id="context.ecv2.usage_of__emphasis_execution_context__emphasis_"/><link
193 linkend="context.ecv2.usage_of__emphasis_execution_context__emphasis_">usage
194 of <emphasis>execution_context</emphasis></link>
196 <programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</phrase><phrase role="special">;</phrase>
197 <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>
198 <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="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>
199 <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
200 <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
201 <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>
202 <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>
203 <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>
204 <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>
205 <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
206 <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
207 <phrase role="special">}</phrase>
208 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
209 <phrase role="special">});</phrase>
210 <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>
211 <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>
212 <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>
213 <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>
214 <phrase role="special">}</phrase>
216 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
217 <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>
220 This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>
221 as a generator. The context <code><phrase role="identifier">sink</phrase></code>
222 represents the <emphasis>main</emphasis>-context (function <emphasis>main()</emphasis>
223 running). <code><phrase role="identifier">sink</phrase></code> is generated
224 by the framework (first element of lambda's parameter list). Because the state
225 is invalidated (== changed) by each call of <emphasis>execution_context::operator()</emphasis>,
226 the new state of the <emphasis>execution_context</emphasis>, returned by <emphasis>execution_context::operator()</emphasis>,
227 needs to be assigned to <code><phrase role="identifier">sink</phrase></code>
231 The lambda that calculates the Fibonacci numbers is executed inside the context
232 represented by <code><phrase role="identifier">source</phrase></code>. Calculated
233 Fibonacci numbers are transferred between the two context' via expression
234 <emphasis>sink(a)</emphasis> (and returned by <emphasis>source()</emphasis>).
235 Note that this example represents a <emphasis>generator</emphasis> thus the
236 value transferred into the lambda via <emphasis>source()</emphasis> is not
237 used. Using <emphasis>boost::optional<></emphasis> as transferred type,
238 might also appropriate to express this fact.
241 The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
242 role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code>
243 remain their values during each context switch (<emphasis>yield(a)</emphasis>).
244 This is possible due <code><phrase role="identifier">source</phrase></code>
245 has its own stack and the stack is exchanged by each context switch.
247 <bridgehead renderas="sect3" id="context.ecv2.h1">
248 <phrase id="context.ecv2.parameter_passing"/><link linkend="context.ecv2.parameter_passing">parameter
252 With <code><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase
253 role="keyword">void</phrase><phrase role="special">></phrase></code> no
254 data will be transferred, only the context switch is executed.
256 <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="special">&&</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">){</phrase>
257 <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>
258 <phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">();</phrase>
259 <phrase role="special">});</phrase>
260 <phrase role="identifier">ctx1</phrase><phrase role="special">();</phrase>
262 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
263 <phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase>
266 <code><phrase role="identifier">ctx1</phrase><phrase role="special">()</phrase></code>
267 resumes <code><phrase role="identifier">ctx1</phrase></code>, e.g. the lambda
268 passed at the constructor of <code><phrase role="identifier">ctx1</phrase></code>
269 is entered. Argument <code><phrase role="identifier">ctx2</phrase></code> represents
270 the context that has been suspended with the invocation of <code><phrase role="identifier">ctx1</phrase><phrase
271 role="special">()</phrase></code>. When the lambda returns <code><phrase role="identifier">ctx2</phrase></code>,
272 context <code><phrase role="identifier">ctx1</phrase></code> will be terminated
273 while the context represented by <code><phrase role="identifier">ctx2</phrase></code>
274 is resumed, hence the control of execution returns from <code><phrase role="identifier">ctx1</phrase><phrase
275 role="special">()</phrase></code>.
278 The arguments passed to <emphasis>execution_context::operator()</emphasis>,
279 in one context, is passed as the last arguments of the <emphasis>context-function</emphasis>
280 if the context is started for the first time. In all following invocations
281 of <emphasis>execution_context::operator()</emphasis> the arguments passed
282 to <emphasis>execution_context::operator()</emphasis>, in one context, is returned
283 by <emphasis>execution_context::operator()</emphasis> in the other context.
285 <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="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>
286 <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>
287 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase><phrase role="identifier">j</phrase><phrase role="special">)=</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>
288 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx2</phrase><phrase role="special">);</phrase>
289 <phrase role="special">});</phrase>
290 <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
291 <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">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
292 <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>
294 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
295 <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>
296 <phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">2</phrase>
299 <code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase
300 role="identifier">i</phrase><phrase role="special">)</phrase></code> enters
301 the lambda in context <code><phrase role="identifier">ctx1</phrase></code>
302 with argument <code><phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase
303 role="number">1</phrase></code>. The expression <code><phrase role="identifier">ctx2</phrase><phrase
304 role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase
305 role="number">1</phrase><phrase role="special">)</phrase></code> resumes the
306 context represented by <code><phrase role="identifier">ctx2</phrase></code>
307 and transfers back an integer of <code><phrase role="identifier">j</phrase><phrase
308 role="special">+</phrase><phrase role="number">1</phrase></code>. On return
309 of <code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase
310 role="identifier">i</phrase><phrase role="special">)</phrase></code>, the variable
311 <code><phrase role="identifier">i</phrase></code> contains the value of <code><phrase
312 role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase></code>.
315 If more than one argument has to be transferred, the signature of the context-function
318 <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="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>
319 <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>
320 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</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">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>
321 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx2</phrase><phrase role="special">);</phrase>
322 <phrase role="special">});</phrase>
323 <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>
324 <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="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>
325 <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>
327 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
328 <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="special">,</phrase><phrase role="identifier">j</phrase><phrase role="special">==</phrase><phrase role="number">1</phrase>
329 <phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">3</phrase><phrase role="special">,</phrase><phrase role="identifier">j</phrase><phrase role="special">==</phrase><phrase role="number">1</phrase>
332 For use-cases, that require to transfer data of different type in each direction,
333 <emphasis>boost::variant<></emphasis> could be used.
335 <programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase><phrase role="special">{</phrase>
336 <phrase role="keyword">private</phrase><phrase role="special">:</phrase>
337 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase>
338 <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>
340 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
341 <phrase role="identifier">X</phrase><phrase role="special">():</phrase>
342 <phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase>
343 <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">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="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>
344 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
345 <phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase>
346 <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>
347 <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>
348 <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>
349 <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>
350 <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>
351 <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>
352 <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>
353 <phrase role="special">}</phrase>
354 <phrase role="keyword">return</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>
355 <phrase role="special">})</phrase>
356 <phrase role="special">{}</phrase>
358 <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>
359 <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>
360 <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>
361 <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>
362 <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>
363 <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase>
364 <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>
365 <phrase role="special">}</phrase>
366 <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>
367 <phrase role="special">}</phrase>
368 <phrase role="special">};</phrase>
370 <phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
371 <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>
373 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
374 <phrase role="number">7</phrase>
377 In the case of unidirectional transfer of data, <emphasis>boost::optional<></emphasis>
378 or a pointer are appropriate.
380 <bridgehead renderas="sect3" id="context.ecv2.h2">
381 <phrase id="context.ecv2.exception_handling"/><link linkend="context.ecv2.exception_handling">exception
385 If the function executed inside a <emphasis>execution_context</emphasis> emits
386 ans exception, the application is terminated by calling <emphasis>std::terminate()</emphasis>.
387 <emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
388 between different execution contexts.
392 Do not jump from inside a catch block and then re-throw the exception in
393 another execution context.
396 <anchor id="ecv2_ontop"/>
397 <bridgehead renderas="sect3" id="context.ecv2.h3">
398 <phrase id="context.ecv2.executing_function_on_top_of_a_context"/><link linkend="context.ecv2.executing_function_on_top_of_a_context">Executing
399 function on top of a context</link>
402 Sometimes it is useful to execute a new function on top of a resumed context.
403 For this purpose <emphasis>execution_context::operator()</emphasis> with first
404 argument <code><phrase role="identifier">exec_ontop_arg</phrase></code> has
405 to be used. The function passed as argument must return a tuple of execution_context
408 <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="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>
409 <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>
410 <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="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>
411 <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>
412 <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="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>
413 <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>
414 <phrase role="keyword">return</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>
415 <phrase role="special">}</phrase>
417 <phrase role="keyword">int</phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
418 <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>
419 <phrase role="keyword">return</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
420 <phrase role="special">}</phrase>
422 <phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
423 <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="identifier">f1</phrase><phrase role="special">);</phrase>
424 <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="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>
425 <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>
426 <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="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>
427 <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>
428 <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="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>
430 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
431 <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>
432 <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>
433 <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>
434 <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>
435 <phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">5</phrase>
436 <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>
439 The expression <code><phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase
440 role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase
441 role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">,</phrase><phrase
442 role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase
443 role="special">)</phrase></code> executes <code><phrase role="identifier">f2</phrase><phrase
444 role="special">()</phrase></code> on top of context <code><phrase role="identifier">ctx</phrase></code>,
445 e.g. an additional stack frame is allocated on top of the context stack (in
446 front of <code><phrase role="identifier">f1</phrase><phrase role="special">()</phrase></code>).
447 <code><phrase role="identifier">f2</phrase><phrase role="special">()</phrase></code>
448 returns argument <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
449 that will returned by the second invocation of <code><phrase role="identifier">ctx</phrase><phrase
450 role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase
451 role="number">1</phrase><phrase role="special">)</phrase></code> in <code><phrase
452 role="identifier">f1</phrase><phrase role="special">()</phrase></code>. [/
453 Another option is to execute a function on top of the context that throws an
454 exception. The thrown exception is catched and re-thrown as nested exception
455 of <emphasis>ontop_error</emphasis> from <emphasis>execution_context::operator()</emphasis>.
456 <emphasis>ontop_error</emphasis> gives access to the context that has resumed
459 <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">my_exception</phrase> <phrase role="special">:</phrase> <phrase role="keyword">public</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase> <phrase role="special">{</phrase>
460 <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">what</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
461 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">{</phrase> <phrase role="identifier">what</phrase> <phrase role="special">}</phrase> <phrase role="special">{</phrase>
462 <phrase role="special">}</phrase>
463 <phrase role="special">};</phrase>
465 <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">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>
466 <phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase>
467 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
468 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"entered"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
469 <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase>
470 <phrase role="special">}</phrase>
471 <phrase role="special">}</phrase> <phrase role="keyword">catch</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">ontop_error</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">e</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
472 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
473 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_if_nested</phrase><phrase role="special">(</phrase> <phrase role="identifier">e</phrase><phrase role="special">);</phrase>
474 <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase> <phrase role="identifier">my_exception</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">ex</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
475 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cerr</phrase> <phrase role="special"><<</phrase> <phrase role="string">"my_exception: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">what</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>
476 <phrase role="special">}</phrase>
477 <phrase role="keyword">return</phrase> <phrase role="identifier">e</phrase><phrase role="special">.</phrase><phrase role="identifier">get_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">>();</phrase>
478 <phrase role="special">}</phrase>
479 <phrase role="special">}</phrase>
480 <phrase role="keyword">return</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>
481 <phrase role="special">});</phrase>
482 <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase>
483 <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase>
484 <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="keyword">throw</phrase> <phrase role="identifier">my_exception</phrase><phrase role="special">{</phrase> <phrase role="string">"abc"</phrase> <phrase role="special">};</phrase> <phrase role="special">});</phrase>
486 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
487 <phrase role="identifier">entered</phrase>
488 <phrase role="identifier">entered</phrase>
489 <phrase role="identifier">my_exception</phrase><phrase role="special">:</phrase> <phrase role="identifier">abc</phrase>
492 In this exception <code><phrase role="identifier">my_exception</phrase></code>
493 is throw from a function invoked ontop of context <code><phrase role="identifier">ctx</phrase></code>
494 and catched inside the <code><phrase role="keyword">for</phrase></code>-loop.
496 <bridgehead renderas="sect3" id="context.ecv2.h4">
497 <phrase id="context.ecv2.stack_unwinding"/><link linkend="context.ecv2.stack_unwinding">stack
501 On construction of <emphasis>execution_context</emphasis> a stack is allocated.
502 If the <emphasis>context-function</emphasis> returns the stack will be destructed.
503 If the <emphasis>context-function</emphasis> has not yet returned and the destructor
504 of an valid <emphasis>execution_context</emphasis> instance (e.g. <emphasis>execution_context::operator
505 bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>)
506 is called, the stack will be destructed too.
510 Code executed by <emphasis>context-function</emphasis> must not prevent the
511 propagation of the <emphasis>detail::forced_unwind</emphasis> exception.
512 Absorbing that exception will cause stack unwinding to fail. Thus, any code
513 that catches all exceptions must re-throw any pending <emphasis>detail::forced_unwind</emphasis>
517 <anchor id="ecv2_prealloc"/>
518 <bridgehead renderas="sect3" id="context.ecv2.h5">
519 <phrase id="context.ecv2.allocating_control_structures_on_top_of_stack"/><link
520 linkend="context.ecv2.allocating_control_structures_on_top_of_stack">allocating
521 control structures on top of stack</link>
524 Allocating control structures on top of the stack requires to allocated the
525 <emphasis>stack_context</emphasis> and create the control structure with placement
526 new before <emphasis>execution_context</emphasis> is created.
530 The user is responsible for destructing the control structure at the top
534 <programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
535 <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase><phrase role="number">4048</phrase><phrase role="special">);</phrase>
536 <phrase role="comment">// allocate stack space</phrase>
537 <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>
538 <phrase role="comment">// reserve space for control structure on top of the stack</phrase>
539 <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="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</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>
540 <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>
541 <phrase role="comment">// placement new creates control structure on reserved space</phrase>
542 <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>
543 <phrase role="special">...</phrase>
544 <phrase role="comment">// destructing the control structure</phrase>
545 <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
546 <phrase role="special">...</phrase>
547 <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
548 <phrase role="comment">// captured context</phrase>
549 <phrase role="identifier">execution_context</phrase> <phrase role="identifier">cctx</phrase><phrase role="special">;</phrase>
551 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
552 <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>
553 <phrase role="comment">// create captured context</phrase>
554 <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>
555 <phrase role="special">}</phrase>
556 <phrase role="special">...</phrase>
557 <phrase role="special">};</phrase>
559 <bridgehead renderas="sect3" id="context.ecv2.h6">
560 <phrase id="context.ecv2.inverting_the_control_flow"/><link linkend="context.ecv2.inverting_the_control_flow">inverting
561 the control flow</link>
563 <programlisting><phrase role="comment">/*
566 * E ---> T {('+'|'-') T}
567 * T ---> S {('*'|'/') S}
568 * S ---> digit | '(' E ')'
570 <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
571 <phrase role="comment">// implementation omitted; see examples directory</phrase>
572 <phrase role="special">};</phrase>
574 <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>
575 <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
576 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase>
578 <phrase role="comment">// execute parser in new execution context</phrase>
579 <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>
580 <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="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase><phrase role="keyword">char</phrase><phrase role="special">){</phrase>
581 <phrase role="comment">// create parser with callback function</phrase>
582 <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase> <phrase role="identifier">is</phrase><phrase role="special">,</phrase>
583 <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>
584 <phrase role="comment">// resume main execution context</phrase>
585 <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>
586 <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>
587 <phrase role="special">});</phrase>
588 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
589 <phrase role="comment">// start recursive parsing</phrase>
590 <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
591 <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase>
592 <phrase role="comment">// store other exceptions in exception-pointer</phrase>
593 <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>
594 <phrase role="special">}</phrase>
595 <phrase role="comment">// set termination flag</phrase>
596 <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
597 <phrase role="comment">// resume main execution context</phrase>
598 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
599 <phrase role="special">});</phrase>
601 <phrase role="comment">// user-code pulls parsed data from parser</phrase>
602 <phrase role="comment">// invert control flow</phrase>
603 <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>
604 <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>
605 <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>
606 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
607 <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>
608 <phrase role="special">}</phrase>
609 <phrase role="keyword">while</phrase><phrase role="special">(!</phrase><phrase role="identifier">done</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
610 <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>
611 <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="identifier">source</phrase><phrase role="special">(</phrase><phrase role="char">'\0'</phrase><phrase role="special">);</phrase>
612 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
613 <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>
614 <phrase role="special">}</phrase>
615 <phrase role="special">}</phrase>
617 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
618 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
619 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
620 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
623 In this example a recursive descent parser uses a callback to emit a newly
624 passed symbol. Using <emphasis>execution_context</emphasis> the control flow
625 can be inverted, e.g. the user-code pulls parsed symbols from the parser -
626 instead to get pushed from the parser (via callback).
629 The data (character) is transferred between the two <emphasis>execution_context</emphasis>.
632 If the code executed by <emphasis>execution_context</emphasis> emits an exception,
633 the application is terminated. <emphasis>std::exception_ptr</emphasis> can
634 be used to transfer exceptions between different execution contexts.
637 Sometimes it is necessary to unwind the stack of an unfinished context to destroy
638 local stack variables so they can release allocated resources (RAII pattern).
639 The user is responsible for this task.
641 <bridgehead renderas="sect3" id="context.ecv2.h7">
642 <phrase id="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
643 linkend="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
644 <code><phrase role="identifier">execution_context</phrase></code></link>
646 <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="special">{};</phrase>
647 <phrase role="keyword">const</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">{};</phrase>
649 <phrase role="keyword">class</phrase> <phrase role="identifier">ontop_error</phrase> <phrase role="special">{</phrase>
650 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
651 <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>
652 <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">get_context</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
653 <phrase role="special">}</phrase>
655 <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>
656 <phrase role="keyword">class</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">{</phrase>
657 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
658 <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>
659 <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>
661 <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>
662 <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>
664 <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>
665 <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>
667 <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>
668 <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>
670 <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>
671 <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>
673 <phrase role="special">~</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">();</phrase>
675 <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>
676 <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>
678 <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>
679 <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>
681 <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>
682 <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>
684 <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>
686 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase>
687 <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>
689 <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>
691 <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>
693 <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>
695 <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>
697 <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>
699 <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>
701 <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>
702 <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>
703 <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>
704 <phrase role="special">};</phrase>
707 <bridgehead renderas="sect4" id="ecv2_constructor_bridgehead">
708 <phrase id="ecv2_constructor"/>
709 <link linkend="ecv2_constructor">Constructor</link>
712 <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>
713 <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>
715 <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>
716 <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>
718 <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>
719 <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>
724 <term>Effects:</term>
727 Creates a new execution context and prepares the context to execute
728 <code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
729 is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
730 The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
731 is used to create a user defined data <link linkend="ecv2_prealloc">(for
732 instance additional control structures)</link> on top of the stack.
738 <bridgehead renderas="sect4" id="ecv2_destructor destructor_bridgehead">
739 <phrase id="ecv2_destructor destructor"/>
740 <link linkend="ecv2_destructor
741 destructor">Destructor</link>
744 <programlisting><phrase role="special">~</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">();</phrase>
749 <term>Effects:</term>
752 Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
753 role="keyword">this</phrase></code> is a valid context, e.g. <emphasis>execution_context::operator
754 bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>.
768 <bridgehead renderas="sect4" id="ecv2_move constructor_bridgehead">
769 <phrase id="ecv2_move constructor"/>
770 <link linkend="ecv2_move constructor">Move
774 <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>
779 <term>Effects:</term>
782 Moves underlying capture record to <code><phrase role="special">*</phrase><phrase
783 role="keyword">this</phrase></code>.
797 <bridgehead renderas="sect4" id="ecv2_move assignment_bridgehead">
798 <phrase id="ecv2_move assignment"/>
799 <link linkend="ecv2_move assignment">Move
800 assignment operator</link>
803 <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>
808 <term>Effects:</term>
811 Moves the state of <code><phrase role="identifier">other</phrase></code>
812 to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
813 using move semantics.
827 <bridgehead renderas="sect4" id="ecv2_operator_bool_bridgehead">
828 <phrase id="ecv2_operator_bool"/>
829 <link linkend="ecv2_operator_bool">Member function
830 <code>operator bool</code>()</link>
833 <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>
838 <term>Returns:</term>
841 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
842 role="keyword">this</phrase></code> points to a capture record.
856 <bridgehead renderas="sect4" id="ecv2_operator_not_bridgehead">
857 <phrase id="ecv2_operator_not"/>
858 <link linkend="ecv2_operator_not">Member function
859 <code>operator!</code>()</link>
862 <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>
867 <term>Returns:</term>
870 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
871 role="keyword">this</phrase></code> does not point to a capture record.
885 <bridgehead renderas="sect4" id="ecv2_operator_call_bridgehead">
886 <phrase id="ecv2_operator_call"/>
887 <link linkend="ecv2_operator_call">Member function
888 <code>operator()</code>()</link>
891 <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>
893 <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>
898 <term>Effects:</term>
901 Stores internally the current context data (stack pointer, instruction
902 pointer, and CPU registers) of the current active context and restores
903 the context data from <code><phrase role="special">*</phrase><phrase
904 role="keyword">this</phrase></code>, which implies jumping to <code><phrase
905 role="special">*</phrase><phrase role="keyword">this</phrase></code>'s
906 context. The arguments, <code><phrase role="special">...</phrase> <phrase
907 role="identifier">args</phrase></code>, are passed to the current context
908 to be returned by the most recent call to <code><phrase role="identifier">execution_context</phrase><phrase
909 role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
910 role="special">()</phrase></code> in the same thread.
915 <term>Returns:</term>
918 The tuple of execution_context and returned arguments passed to the most
919 recent call to <code><phrase role="identifier">execution_context</phrase><phrase
920 role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
921 role="special">()</phrase></code>, if any and a execution_context representing
922 the context that has been suspended.
930 The returned execution_context indicates if the suspended context has
931 terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
932 <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
933 If the returned execution_context has terminated no data are transferred
934 in the returned tuple.
940 <bridgehead renderas="sect4" id="ecv2_operator_call_ontop_bridgehead">
941 <phrase id="ecv2_operator_call_ontop"/>
942 <link linkend="ecv2_operator_call_ontop">Member
943 function <code>operator()</code>()</link>
946 <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase>
947 <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>
949 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase>
950 <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>
955 <term>Effects:</term>
958 Same as <emphasis>execution_context::operator()</emphasis>. Additionally,
959 function <code><phrase role="identifier">fn</phrase></code> is executed
960 in the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
961 (e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code>
962 is allocated on stack of <code><phrase role="special">*</phrase><phrase
963 role="keyword">this</phrase></code>).
968 <term>Returns:</term>
971 The tuple of execution_context and returned arguments passed to the most
972 recent call to <code><phrase role="identifier">execution_context</phrase><phrase
973 role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
974 role="special">()</phrase></code>, if any and a execution_context representing
975 the context that has been suspended .
983 The tuple of execution_context and returned arguments from <code><phrase
984 role="identifier">fn</phrase></code> are passed as arguments to the context-function
985 of resumed context (if the context is entered the first time) or those
986 arguments are returned from <code><phrase role="identifier">execution_context</phrase><phrase
987 role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
988 role="special">()</phrase></code> within the resumed context.
996 Function <code><phrase role="identifier">fn</phrase></code> needs to
997 return a tuple of arguments (<link linkend="ecv2_ontop">see description</link>).
1005 The context calling this function must not be destroyed before the arguments,
1006 that will be returned from <code><phrase role="identifier">fn</phrase></code>,
1007 are preserved at least in the stack frame of the resumed context.
1015 The returned execution_context indicates if the suspended context has
1016 terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
1017 <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
1018 If the returned execution_context has terminated no data are transferred
1019 in the returned tuple.
1025 <bridgehead renderas="sect4" id="ecv2_operator_equal_bridgehead">
1026 <phrase id="ecv2_operator_equal"/>
1027 <link linkend="ecv2_operator_equal">Member
1028 function <code>operator==</code>()</link>
1031 <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>
1036 <term>Returns:</term>
1039 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
1040 role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>
1041 represent the same execution context, <code><phrase role="keyword">false</phrase></code>
1047 <term>Throws:</term>
1056 <bridgehead renderas="sect4" id="ecv2_operator_notequal_bridgehead">
1057 <phrase id="ecv2_operator_notequal"/>
1058 <link linkend="ecv2_operator_notequal">Member
1059 function <code>operator!=</code>()</link>
1062 <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>
1067 <term>Returns:</term>
1070 <code>! (other == * this)</code>
1075 <term>Throws:</term>
1084 <bridgehead renderas="sect4" id="ecv2_operator_less_bridgehead">
1085 <phrase id="ecv2_operator_less"/>
1086 <link linkend="ecv2_operator_less">Member function
1087 <code>operator<</code>()</link>
1090 <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>
1095 <term>Returns:</term>
1098 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
1099 role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase
1100 role="identifier">other</phrase></code> is true and the implementation-defined
1101 total order of <code><phrase role="identifier">execution_context</phrase></code>
1102 values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
1103 before <code><phrase role="identifier">other</phrase></code>, false otherwise.
1108 <term>Throws:</term>
1117 <bridgehead renderas="sect4" id="ecv2_operator_greater_bridgehead">
1118 <phrase id="ecv2_operator_greater"/>
1119 <link linkend="ecv2_operator_greater">Member
1120 function <code>operator></code>()</link>
1123 <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>
1128 <term>Returns:</term>
1131 <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
1132 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
1137 <term>Throws:</term>
1146 <bridgehead renderas="sect4" id="ecv2_operator_lesseq_bridgehead">
1147 <phrase id="ecv2_operator_lesseq"/>
1148 <link linkend="ecv2_operator_lesseq">Member
1149 function <code>operator<=</code>()</link>
1152 <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>
1157 <term>Returns:</term>
1160 <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
1161 role="identifier">other</phrase> <phrase role="special"><</phrase>
1162 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
1163 role="special">)</phrase></code>
1168 <term>Throws:</term>
1177 <bridgehead renderas="sect4" id="ecv2_operator_greatereq_bridgehead">
1178 <phrase id="ecv2_operator_greatereq"/>
1179 <link linkend="ecv2_operator_greatereq">Member
1180 function <code>operator>=</code>()</link>
1183 <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>
1188 <term>Returns:</term>
1191 <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
1192 <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
1193 <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
1198 <term>Throws:</term>
1207 <bridgehead renderas="sect4" id="ecv2__bridgehead">
1208 <phrase id="ecv2_"/>
1209 <link linkend="ecv2_">Non-member function <code>operator<<()</code></link>
1212 <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>
1213 <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>
1214 <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>
1219 <term>Efects:</term>
1222 Writes the representation of <code><phrase role="identifier">other</phrase></code>
1223 to stream <code><phrase role="identifier">os</phrase></code>.
1228 <term>Returns:</term>
1231 <code><phrase role="identifier">os</phrase></code>
1237 <section id="context.ecv1">
1238 <title><anchor id="ecv1"/><link linkend="context.ecv1">Class execution_context
1239 (version 1)</link></title>
1242 This class is only enabled if property <emphasis>segmented-stacks=on</emphasis>
1243 (enables segmented stacks) or compiler flag <emphasis>BOOST_EXECUTION_CONTEXT=1</emphasis>
1244 is specified at b2-commandline.
1248 Class <emphasis>execution_context</emphasis> encapsulates context switching
1249 and manages the associated context' stack (allocation/deallocation).
1252 <emphasis>execution_context</emphasis> allocates the context stack (using its
1253 <link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument)
1254 and creates a control structure on top of it. This structure is responsible
1255 for managing context' stack. Instances of <emphasis>execution_context</emphasis>,
1256 associated with a specific context, share the ownership of the control structure.
1257 If the last reference goes out of scope, the control structure is destroyed
1258 and the stack gets deallocated via the <emphasis>StackAllocator</emphasis>.
1261 <emphasis>execution_context</emphasis> is copy-constructible, move-constructible,
1262 copy-assignable and move-assignable.
1265 <emphasis>execution_context</emphasis> maintains a static (thread-local) pointer,
1266 accessed by <emphasis>execution_context::current()</emphasis>, pointing to
1267 the active context. On each context switch the pointer is updated. The usage
1268 of this global pointer makes the context switch a little bit slower (due access
1269 of thread local storage) but has some advantages. It allows to access the control
1270 structure of the current active context from arbitrary code paths required
1271 in order to support segmented stacks, which require to call certain maintenance
1272 functions (like __splitstack_getcontext() etc.) before each context switch
1273 (each context switch exchanges the stack).
1276 <emphasis>execution_context</emphasis> expects a function/functor with signature
1277 <code><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase
1278 role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase
1279 role="special">)</phrase></code> (<code><phrase role="identifier">vp</phrase></code>
1280 is the data passed at the first invocation of <link linkend="ecv1_operator_call"> <code>ecv1::operator()()</code></link>).
1282 <bridgehead renderas="sect3" id="context.ecv1.h0">
1283 <phrase id="context.ecv1.usage_of__emphasis_execution_context__emphasis_"/><link
1284 linkend="context.ecv1.usage_of__emphasis_execution_context__emphasis_">usage
1285 of <emphasis>execution_context</emphasis></link>
1287 <programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</phrase><phrase role="special">;</phrase>
1288 <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>
1289 <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>
1290 <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>
1291 <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
1292 <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1293 <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>
1294 <phrase role="identifier">sink</phrase><phrase role="special">(&</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase>
1295 <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>
1296 <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
1297 <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
1298 <phrase role="special">}</phrase>
1299 <phrase role="special">});</phrase>
1300 <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>
1301 <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>
1302 <phrase role="special">}</phrase>
1304 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1305 <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>
1308 This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>.
1309 The context <code><phrase role="identifier">sink</phrase></code>, returned
1310 by <emphasis>execution_context::current()</emphasis>, represents the <emphasis>main</emphasis>-context
1311 (function <emphasis>main()</emphasis> running) and is one of the captured parameters
1312 in the lambda expression. The lambda that calculates the Fibonacci numbers
1313 is executed inside the context represented by <code><phrase role="identifier">source</phrase></code>.
1314 Calculated Fibonacci numbers are transferred between the two context' via expression
1315 <emphasis>sink(&a)</emphasis> (and returned by <emphasis>source()</emphasis>).
1318 The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
1319 role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code>
1320 remain their values during each context switch (<emphasis>yield(a)</emphasis>).
1321 This is possible because <code><phrase role="identifier">ctx</phrase></code>
1322 owns a stack (exchanged by context switch).
1324 <bridgehead renderas="sect3" id="context.ecv1.h1">
1325 <phrase id="context.ecv1.inverting_the_control_flow"/><link linkend="context.ecv1.inverting_the_control_flow">inverting
1326 the control flow</link>
1328 <programlisting><phrase role="comment">/*
1331 * E ---> T {('+'|'-') T}
1332 * T ---> S {('*'|'/') S}
1333 * S ---> digit | '(' E ')'
1335 <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
1336 <phrase role="comment">// implementation omitted; see examples directory</phrase>
1337 <phrase role="special">};</phrase>
1339 <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>
1340 <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
1341 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase>
1343 <phrase role="comment">// create handle to main execution context</phrase>
1344 <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>
1345 <phrase role="comment">// execute parser in new execution context</phrase>
1346 <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>
1347 <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>
1348 <phrase role="comment">// create parser with callback function</phrase>
1349 <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase>
1350 <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>
1351 <phrase role="comment">// resume main execution context</phrase>
1352 <phrase role="identifier">sink</phrase><phrase role="special">(&</phrase><phrase role="identifier">ch</phrase><phrase role="special">);</phrase>
1353 <phrase role="special">});</phrase>
1354 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
1355 <phrase role="comment">// start recursive parsing</phrase>
1356 <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
1357 <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase>
1358 <phrase role="comment">// store other exceptions in exception-pointer</phrase>
1359 <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>
1360 <phrase role="special">}</phrase>
1361 <phrase role="comment">// set termination flag</phrase>
1362 <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
1363 <phrase role="comment">// resume main execution context</phrase>
1364 <phrase role="identifier">sink</phrase><phrase role="special">();</phrase>
1365 <phrase role="special">});</phrase>
1367 <phrase role="comment">// user-code pulls parsed data from parser</phrase>
1368 <phrase role="comment">// invert control flow</phrase>
1369 <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>
1370 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1371 <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>
1372 <phrase role="special">}</phrase>
1373 <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>
1374 <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>
1375 <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">();</phrase>
1376 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1377 <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>
1378 <phrase role="special">}</phrase>
1379 <phrase role="special">}</phrase>
1381 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1382 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
1383 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
1384 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
1387 In this example a recursive descent parser uses a callback to emit a newly
1388 passed symbol. Using <emphasis>execution_context</emphasis> the control flow
1389 can be inverted, e.g. the user-code pulls parsed symbols from the parser -
1390 instead to get pushed from the parser (via callback).
1393 The data (character) is transferred between the two <emphasis>execution_context</emphasis>.
1396 If the code executed by <emphasis>execution_context</emphasis> emits an exception,
1397 the application is terminated. <emphasis>std::exception_ptr</emphasis> can
1398 be used to transfer exceptions between different execution contexts.
1400 <bridgehead renderas="sect3" id="context.ecv1.h2">
1401 <phrase id="context.ecv1.stack_unwinding"/><link linkend="context.ecv1.stack_unwinding">stack
1405 Sometimes it is necessary to unwind the stack of an unfinished context to destroy
1406 local stack variables so they can release allocated resources (RAII pattern).
1407 The user is responsible for this task.
1409 <anchor id="ecv1_prealloc"/>
1410 <bridgehead renderas="sect3" id="context.ecv1.h3">
1411 <phrase id="context.ecv1.allocating_control_structures_on_top_of_stack"/><link
1412 linkend="context.ecv1.allocating_control_structures_on_top_of_stack">allocating
1413 control structures on top of stack</link>
1416 Allocating control structures on top of the stack requires to allocated the
1417 <emphasis>stack_context</emphasis> and create the control structure with placement
1418 new before <emphasis>execution_context</emphasis> is created.
1422 The user is responsible for destructing the control structure at the top
1426 <programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
1427 <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase> <phrase role="number">4048</phrase><phrase role="special">);</phrase>
1428 <phrase role="comment">// allocate stack space</phrase>
1429 <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>
1430 <phrase role="comment">// reserve space for control structure on top of the stack</phrase>
1431 <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>
1432 <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>
1433 <phrase role="comment">// placement new creates control structure on reserved space</phrase>
1434 <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>
1435 <phrase role="special">...</phrase>
1436 <phrase role="comment">// destructing the control structure</phrase>
1437 <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
1438 <phrase role="special">...</phrase>
1439 <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
1440 <phrase role="comment">// execution context</phrase>
1441 <phrase role="identifier">execution_context</phrase> <phrase role="identifier">ectx</phrase><phrase role="special">;</phrase>
1443 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
1444 <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>
1445 <phrase role="comment">// create execution context</phrase>
1446 <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>
1447 <phrase role="special">}</phrase>
1448 <phrase role="special">...</phrase>
1449 <phrase role="special">};</phrase>
1451 <bridgehead renderas="sect3" id="context.ecv1.h4">
1452 <phrase id="context.ecv1.exception_handling"/><link linkend="context.ecv1.exception_handling">exception
1456 If the function executed inside a <emphasis>execution_context</emphasis> emits
1457 ans exception, the application is terminated by calling <emphasis>std::terminate()</emphasis>.
1458 <emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
1459 between different execution contexts.
1463 Do not jump from inside a catch block and then re-throw the exception in
1464 another execution context.
1467 <bridgehead renderas="sect3" id="context.ecv1.h5">
1468 <phrase id="context.ecv1.parameter_passing"/><link linkend="context.ecv1.parameter_passing">parameter
1472 The void pointer argument passed to <emphasis>execution_context::operator()</emphasis>,
1473 in one context, is passed as the last argument of the <emphasis>context-function</emphasis>
1474 if the context is started for the first time. In all following invocations
1475 of <emphasis>execution_context::operator()</emphasis> the void pointer passed
1476 to <emphasis>execution_context::operator()</emphasis>, in one context, is returned
1477 by <emphasis>execution_context::operator()</emphasis> in the other context.
1479 <programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase> <phrase role="special">{</phrase>
1480 <phrase role="keyword">private</phrase><phrase role="special">:</phrase>
1481 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase>
1482 <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>
1483 <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>
1485 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
1486 <phrase role="identifier">X</phrase><phrase role="special">()</phrase> <phrase role="special">:</phrase>
1487 <phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase>
1488 <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>
1489 <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>
1490 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
1491 <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>
1492 <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>
1493 <phrase role="identifier">caller_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">str</phrase><phrase role="special">);</phrase>
1494 <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>
1495 <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>
1496 <phrase role="special">}</phrase>
1497 <phrase role="special">})</phrase>
1498 <phrase role="special">{}</phrase>
1500 <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>
1501 <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>
1502 <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase>
1503 <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>
1504 <phrase role="special">}</phrase>
1505 <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>
1506 <phrase role="special">}</phrase>
1507 <phrase role="special">};</phrase>
1509 <phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
1510 <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>
1512 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1513 <phrase role="number">7</phrase>
1515 <bridgehead renderas="sect3" id="context.ecv1.h6">
1516 <phrase id="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
1517 linkend="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
1518 <code><phrase role="identifier">execution_context</phrase></code></link>
1520 <programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">{</phrase>
1521 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
1522 <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>
1524 <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>
1525 <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>
1527 <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>
1528 <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>
1530 <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>
1531 <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>
1533 <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>
1534 <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>
1536 <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>
1537 <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>
1539 <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>
1540 <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>
1542 <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>
1544 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase>
1545 <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>
1547 <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>
1549 <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>
1551 <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>
1553 <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>
1555 <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>
1557 <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>
1559 <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>
1560 <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>
1561 <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>
1562 <phrase role="special">};</phrase>
1565 <bridgehead renderas="sect4" id="ecv1_current_bridgehead">
1566 <phrase id="ecv1_current"/>
1567 <link linkend="ecv1_current">Static member function <code>current</code>()</link>
1570 <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>
1575 <term>Returns:</term>
1578 Returns an instance of excution_context pointing to the active execution
1584 <term>Throws:</term>
1593 <bridgehead renderas="sect4" id="ecv1_constructor_bridgehead">
1594 <phrase id="ecv1_constructor"/>
1595 <link linkend="ecv1_constructor">Constructor</link>
1598 <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>
1599 <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>
1601 <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>
1602 <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>
1604 <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>
1605 <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>
1610 <term>Effects:</term>
1613 Creates a new execution context and prepares the context to execute
1614 <code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
1615 is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
1616 The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
1617 is used to create a user defined data <link linkend="ecv1_prealloc">(for
1618 instance additional control structures)</link> on top of the stack.
1624 <bridgehead renderas="sect4" id="ecv1_copy constructor_bridgehead">
1625 <phrase id="ecv1_copy constructor"/>
1626 <link linkend="ecv1_copy constructor">Copy
1630 <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>
1635 <term>Effects:</term>
1638 Copies <code><phrase role="identifier">other</phrase></code>, e.g. underlying
1639 control structure is shared with <code><phrase role="special">*</phrase><phrase
1640 role="keyword">this</phrase></code>.
1645 <term>Throws:</term>
1654 <bridgehead renderas="sect4" id="ecv1_move constructor_bridgehead">
1655 <phrase id="ecv1_move constructor"/>
1656 <link linkend="ecv1_move constructor">Move
1660 <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>
1665 <term>Effects:</term>
1668 Moves underlying control structure to <code><phrase role="special">*</phrase><phrase
1669 role="keyword">this</phrase></code>.
1674 <term>Throws:</term>
1683 <bridgehead renderas="sect4" id="ecv1_copy assignment_bridgehead">
1684 <phrase id="ecv1_copy assignment"/>
1685 <link linkend="ecv1_copy assignment">Copy
1686 assignment operator</link>
1689 <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>
1694 <term>Effects:</term>
1697 Copies the state of <code><phrase role="identifier">other</phrase></code>
1698 to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>,
1699 control structure is shared.
1704 <term>Throws:</term>
1713 <bridgehead renderas="sect4" id="ecv1_move assignment_bridgehead">
1714 <phrase id="ecv1_move assignment"/>
1715 <link linkend="ecv1_move assignment">Move
1716 assignment operator</link>
1719 <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>
1724 <term>Effects:</term>
1727 Moves the control structure of <code><phrase role="identifier">other</phrase></code>
1728 to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
1729 using move semantics.
1734 <term>Throws:</term>
1743 <bridgehead renderas="sect4" id="ecv1_operator_bool_bridgehead">
1744 <phrase id="ecv1_operator_bool"/>
1745 <link linkend="ecv1_operator_bool">Member function
1746 <code>operator bool</code>()</link>
1749 <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>
1754 <term>Returns:</term>
1757 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
1758 role="keyword">this</phrase></code> points to a control structure.
1763 <term>Throws:</term>
1772 <bridgehead renderas="sect4" id="ecv1_operator_not_bridgehead">
1773 <phrase id="ecv1_operator_not"/>
1774 <link linkend="ecv1_operator_not">Member function
1775 <code>operator!</code>()</link>
1778 <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>
1783 <term>Returns:</term>
1786 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
1787 role="keyword">this</phrase></code> does not point to a control structure.
1792 <term>Throws:</term>
1801 <bridgehead renderas="sect4" id="ecv1_operator_call_bridgehead">
1802 <phrase id="ecv1_operator_call"/>
1803 <link linkend="ecv1_operator_call">Member function
1804 <code>operator()</code>()</link>
1807 <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>
1812 <term>Effects:</term>
1815 Stores internally the current context data (stack pointer, instruction
1816 pointer, and CPU registers) of the current active context and restores
1817 the context data from <code><phrase role="special">*</phrase><phrase
1818 role="keyword">this</phrase></code>, which implies jumping to <code><phrase
1819 role="special">*</phrase><phrase role="keyword">this</phrase></code>'s
1820 context. The void pointer argument, <code><phrase role="identifier">vp</phrase></code>,
1821 is passed to the current context to be returned by the most recent call
1822 to <code><phrase role="identifier">execution_context</phrase><phrase
1823 role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
1824 role="special">()</phrase></code> in the same thread. <code><phrase role="identifier">fn</phrase></code>
1825 is executed with arguments <code><phrase role="identifier">args</phrase></code>
1826 on top of the stack of <code><phrase role="keyword">this</phrase></code>.
1834 The behaviour is undefined if <code><phrase role="keyword">operator</phrase><phrase
1835 role="special">()()</phrase></code> is called while <emphasis>execution_context::current()</emphasis>
1836 returns <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
1837 (e.g. resuming an already running context). If the top-level context
1838 function returns, <code><phrase role="identifier">std</phrase><phrase
1839 role="special">::</phrase><phrase role="identifier">exit</phrase><phrase
1840 role="special">()</phrase></code> is called.
1845 <term>Returns:</term>
1848 The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>,
1855 <bridgehead renderas="sect4" id="ecv1_operator_call_ontop_bridgehead">
1856 <phrase id="ecv1_operator_call_ontop"/>
1857 <link linkend="ecv1_operator_call_ontop">Member
1858 function <code>operator(exec_ontop_arg_t)</code>()</link>
1861 <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase>
1862 <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>
1867 <term>Effects:</term>
1870 Same as <emphasis>execution_context::operator()</emphasis>. Additionally,
1871 function <code><phrase role="identifier">fn</phrase></code> is executed
1872 with arguments <code><phrase role="identifier">vp</phrase></code> in
1873 the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
1874 (e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code>
1875 is allocated on stack of <code><phrase role="special">*</phrase><phrase
1876 role="keyword">this</phrase></code>).
1881 <term>Returns:</term>
1884 The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>,
1891 <bridgehead renderas="sect4" id="ecv1_operator_equal_bridgehead">
1892 <phrase id="ecv1_operator_equal"/>
1893 <link linkend="ecv1_operator_equal">Member
1894 function <code>operator==</code>()</link>
1897 <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>
1902 <term>Returns:</term>
1905 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
1906 role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>
1907 represent the same execution context, <code><phrase role="keyword">false</phrase></code>
1913 <term>Throws:</term>
1922 <bridgehead renderas="sect4" id="ecv1_operator_notequal_bridgehead">
1923 <phrase id="ecv1_operator_notequal"/>
1924 <link linkend="ecv1_operator_notequal">Member
1925 function <code>operator!=</code>()</link>
1928 <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>
1933 <term>Returns:</term>
1936 <code>! (other == * this)</code>
1941 <term>Throws:</term>
1950 <bridgehead renderas="sect4" id="ecv1_operator_less_bridgehead">
1951 <phrase id="ecv1_operator_less"/>
1952 <link linkend="ecv1_operator_less">Member function
1953 <code>operator<</code>()</link>
1956 <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>
1961 <term>Returns:</term>
1964 <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
1965 role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase
1966 role="identifier">other</phrase></code> is true and the implementation-defined
1967 total order of <code><phrase role="identifier">execution_context</phrase></code>
1968 values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
1969 before <code><phrase role="identifier">other</phrase></code>, false otherwise.
1974 <term>Throws:</term>
1983 <bridgehead renderas="sect4" id="ecv1_operator_greater_bridgehead">
1984 <phrase id="ecv1_operator_greater"/>
1985 <link linkend="ecv1_operator_greater">Member
1986 function <code>operator></code>()</link>
1989 <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>
1994 <term>Returns:</term>
1997 <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
1998 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
2003 <term>Throws:</term>
2012 <bridgehead renderas="sect4" id="ecv1_operator_lesseq_bridgehead">
2013 <phrase id="ecv1_operator_lesseq"/>
2014 <link linkend="ecv1_operator_lesseq">Member
2015 function <code>operator<=</code>()</link>
2018 <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>
2023 <term>Returns:</term>
2026 <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
2027 role="identifier">other</phrase> <phrase role="special"><</phrase>
2028 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
2029 role="special">)</phrase></code>
2034 <term>Throws:</term>
2043 <bridgehead renderas="sect4" id="ecv1_operator_greatereq_bridgehead">
2044 <phrase id="ecv1_operator_greatereq"/>
2045 <link linkend="ecv1_operator_greatereq">Member
2046 function <code>operator>=</code>()</link>
2049 <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>
2054 <term>Returns:</term>
2057 <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
2058 <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
2059 <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
2064 <term>Throws:</term>
2073 <bridgehead renderas="sect4" id="ecv1__bridgehead">
2074 <phrase id="ecv1_"/>
2075 <link linkend="ecv1_">Non-member function <code>operator<<()</code></link>
2078 <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>
2079 <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>
2080 <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>
2085 <term>Efects:</term>
2088 Writes the representation of <code><phrase role="identifier">other</phrase></code>
2089 to stream <code><phrase role="identifier">os</phrase></code>.
2094 <term>Returns:</term>
2097 <code><phrase role="identifier">os</phrase></code>
2103 <section id="context.stack">
2104 <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title>
2106 The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis>
2107 which is required to model a <emphasis>stack-allocator concept</emphasis>.
2109 <bridgehead renderas="sect3" id="context.stack.h0">
2110 <phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link
2111 linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
2112 concept</emphasis></link>
2115 A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator
2116 concept</emphasis> requirements shown in the following table, in which <code><phrase
2117 role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis>
2118 type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
2119 role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
2120 is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
2121 role="identifier">size_t</phrase></code>:
2123 <informaltable frame="all">
2148 <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase
2149 role="identifier">size</phrase><phrase role="special">)</phrase></code>
2156 creates a stack allocator
2163 <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
2164 role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
2169 <code><phrase role="identifier">stack_context</phrase></code>
2181 <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
2182 role="identifier">deallocate</phrase><phrase role="special">(</phrase>
2183 <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
2188 <code><phrase role="keyword">void</phrase></code>
2193 deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
2194 role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
2195 role="special">()</phrase></code>
2204 The implementation of <code><phrase role="identifier">allocate</phrase><phrase
2205 role="special">()</phrase></code> might include logic to protect against
2206 exceeding the context's available stack size rather than leaving it as undefined
2212 Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
2213 with a <code><phrase role="identifier">stack_context</phrase></code> not
2214 set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
2215 results in undefined behaviour.
2220 The stack is not required to be aligned; alignment takes place inside <emphasis>execution_context</emphasis>.
2225 Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
2226 role="special">()</phrase></code> stores an address from the top of the stack
2227 (growing downwards) or the bottom of the stack (growing upwards).
2230 <section id="context.stack.protected_fixedsize">
2231 <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title>
2233 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis>
2234 which models the <emphasis>stack-allocator concept</emphasis>. It appends
2235 a guard page at the end of each stack to protect against exceeding the stack.
2236 If the guard page is accessed (read or write operation) a segmentation fault/access
2237 violation is generated by the operating system.
2241 Using <emphasis>protected_fixedsize_stack</emphasis> is expensive. That
2242 is, launching a new coroutine with a new stack is expensive; the allocated
2243 stack is just as efficient to use as any other stack.
2248 The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
2249 is <emphasis role="bold">not</emphasis> mapped to physical memory, only
2250 virtual addresses are used.
2253 <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>
2255 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2256 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase> <phrase role="special">{</phrase>
2257 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2259 <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>
2261 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2263 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2264 <phrase role="special">}</phrase>
2266 <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>
2268 <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h0">
2269 <phrase id="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2270 linkend="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2271 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2272 role="special">()</phrase></code></link>
2277 <term>Preconditions:</term>
2280 <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2281 role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
2282 role="identifier">size</phrase><phrase role="special">()</phrase>
2283 <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
2284 and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2285 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2286 role="special">()</phrase> <phrase role="special">&&</phrase>
2287 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2288 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2289 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2290 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2291 role="identifier">size</phrase><phrase role="special">)</phrase></code>.
2296 <term>Effects:</term>
2299 Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
2300 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2301 role="identifier">sctx</phrase></code>. Depending on the architecture
2302 (the stack grows downwards/upwards) the stored address is the highest/lowest
2303 address of the stack.
2308 <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h1">
2309 <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
2310 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
2311 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2312 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2313 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2314 role="special">)</phrase></code></link>
2319 <term>Preconditions:</term>
2322 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2323 role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
2324 role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
2325 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2326 role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
2327 role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2328 role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
2329 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2330 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2331 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2332 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2333 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2334 role="identifier">size</phrase><phrase role="special">()</phrase>
2335 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2336 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2337 role="special">)</phrase></code>.
2342 <term>Effects:</term>
2345 Deallocates the stack space.
2351 <section id="context.stack.pooled_fixedsize">
2352 <title><link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link></title>
2354 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>pooled_fixedsize_stack</emphasis>
2355 which models the <emphasis>stack-allocator concept</emphasis>. In contrast
2356 to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
2357 page at the end of each stack. The memory is managed internally by <ulink
2358 url="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html"><code><phrase
2359 role="identifier">boost</phrase><phrase role="special">::</phrase><phrase
2360 role="identifier">pool</phrase><phrase role="special"><></phrase></code></ulink>.
2362 <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>
2364 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2365 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_pooled_fixedsize_stack</phrase> <phrase role="special">{</phrase>
2366 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2368 <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>
2370 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2372 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2373 <phrase role="special">}</phrase>
2375 <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>
2377 <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h0">
2378 <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
2379 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
2380 role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase
2381 role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
2382 <phrase role="identifier">stack_size</phrase><phrase role="special">,</phrase>
2383 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
2384 role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase><phrase
2385 role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
2386 role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase><phrase
2387 role="special">)</phrase></code></link>
2392 <term>Preconditions:</term>
2395 <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2396 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2397 role="special">()</phrase> <phrase role="special">&&</phrase>
2398 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2399 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2400 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2401 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2402 role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>
2403 and <code><phrase role="number">0</phrase> <phrase role="special"><</phrase>
2404 <phrase role="identifier">nest_size</phrase></code>.
2409 <term>Effects:</term>
2412 Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code>
2413 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2414 role="identifier">sctx</phrase></code>. Depending on the architecture
2415 (the stack grows downwards/upwards) the stored address is the highest/lowest
2416 address of the stack. Argument <code><phrase role="identifier">next_size</phrase></code>
2417 determines the number of stacks to request from the system the first
2418 time that <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
2419 needs to allocate system memory. The third argument <code><phrase role="identifier">max_size</phrase></code>
2420 controls how many memory might be allocated for stacks - a value of
2421 zero means no uper limit.
2426 <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h1">
2427 <phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2428 linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2429 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2430 role="special">()</phrase></code></link>
2435 <term>Preconditions:</term>
2438 <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2439 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2440 role="special">()</phrase> <phrase role="special">&&</phrase>
2441 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2442 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2443 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2444 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2445 role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>.
2450 <term>Effects:</term>
2453 Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code>
2454 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2455 role="identifier">sctx</phrase></code>. Depending on the architecture
2456 (the stack grows downwards/upwards) the stored address is the highest/lowest
2457 address of the stack.
2462 <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h2">
2463 <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
2464 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
2465 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2466 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2467 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2468 role="special">)</phrase></code></link>
2473 <term>Preconditions:</term>
2476 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2477 role="identifier">sp</phrase></code> is valid, <code><phrase role="special">!</phrase>
2478 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2479 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2480 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2481 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2482 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2483 role="identifier">size</phrase><phrase role="special">()</phrase>
2484 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2485 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2486 role="special">)</phrase></code>.
2491 <term>Effects:</term>
2494 Deallocates the stack space.
2500 <section id="context.stack.fixedsize">
2501 <title><link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link></title>
2503 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>fixedsize_stack</emphasis>
2504 which models the <emphasis>stack-allocator concept</emphasis>. In contrast
2505 to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
2506 page at the end of each stack. The memory is simply managed by <code><phrase
2507 role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">malloc</phrase><phrase
2508 role="special">()</phrase></code> and <code><phrase role="identifier">std</phrase><phrase
2509 role="special">::</phrase><phrase role="identifier">free</phrase><phrase
2510 role="special">()</phrase></code>.
2512 <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>
2514 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2515 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase> <phrase role="special">{</phrase>
2516 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2518 <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>
2520 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2522 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2523 <phrase role="special">}</phrase>
2525 <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>
2527 <bridgehead renderas="sect4" id="context.stack.fixedsize.h0">
2528 <phrase id="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2529 linkend="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2530 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2531 role="special">()</phrase></code></link>
2536 <term>Preconditions:</term>
2539 <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2540 role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
2541 role="identifier">size</phrase><phrase role="special">()</phrase>
2542 <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
2543 and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2544 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2545 role="special">()</phrase> <phrase role="special">&&</phrase>
2546 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2547 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2548 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2549 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2550 role="identifier">size</phrase><phrase role="special">)</phrase></code>.
2555 <term>Effects:</term>
2558 Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
2559 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2560 role="identifier">sctx</phrase></code>. Depending on the architecture
2561 (the stack grows downwards/upwards) the stored address is the highest/lowest
2562 address of the stack.
2567 <bridgehead renderas="sect4" id="context.stack.fixedsize.h1">
2568 <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
2569 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
2570 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2571 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2572 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2573 role="special">)</phrase></code></link>
2578 <term>Preconditions:</term>
2581 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2582 role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
2583 role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
2584 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2585 role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
2586 role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2587 role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
2588 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2589 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2590 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2591 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2592 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2593 role="identifier">size</phrase><phrase role="special">()</phrase>
2594 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2595 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2596 role="special">)</phrase></code>.
2601 <term>Effects:</term>
2604 Deallocates the stack space.
2610 <section id="context.stack.segmented">
2611 <title><link linkend="context.stack.segmented">Class <emphasis>segmented_stack</emphasis></link></title>
2613 <emphasis role="bold">Boost.Context</emphasis> supports usage of a <emphasis>segmented_stack</emphasis>,
2614 e. g. the size of the stack grows on demand. The coroutine is created with
2615 a minimal stack size and will be increased as required. Class <emphasis>segmented_stack</emphasis>
2616 models the <emphasis>stack-allocator concept</emphasis>. In contrast to
2617 <emphasis>protected_fixedsize_stack</emphasis> and <emphasis>fixedsize_stack</emphasis>
2618 it creates a stack which grows on demand.
2622 Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
2623 from version <emphasis role="bold">4.7</emphasis> <emphasis role="bold">clang</emphasis>
2624 from version <emphasis role="bold">3.4</emphasis> onwards. In order to
2625 use a __segmented_stack__ <emphasis role="bold">Boost.Context</emphasis>
2626 must be built with property <code><phrase role="identifier">segmented</phrase><phrase
2627 role="special">-</phrase><phrase role="identifier">stacks</phrase></code>,
2628 e.g. <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis> at
2629 b2/bjam command line.
2632 <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>
2634 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2635 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_segmented_stack</phrase> <phrase role="special">{</phrase>
2636 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2638 <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>
2640 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2642 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2643 <phrase role="special">}</phrase>
2645 <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>
2647 <bridgehead renderas="sect4" id="context.stack.segmented.h0">
2648 <phrase id="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2649 linkend="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2650 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2651 role="special">()</phrase></code></link>
2656 <term>Preconditions:</term>
2659 <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2660 role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
2661 role="identifier">size</phrase><phrase role="special">()</phrase>
2662 <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
2663 and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2664 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2665 role="special">()</phrase> <phrase role="special">&&</phrase>
2666 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2667 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2668 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2669 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2670 role="identifier">size</phrase><phrase role="special">)</phrase></code>.
2675 <term>Effects:</term>
2678 Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
2679 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2680 role="identifier">sctx</phrase></code>. Depending on the architecture
2681 (the stack grows downwards/upwards) the stored address is the highest/lowest
2682 address of the stack.
2687 <bridgehead renderas="sect4" id="context.stack.segmented.h1">
2688 <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
2689 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
2690 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2691 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2692 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2693 role="special">)</phrase></code></link>
2698 <term>Preconditions:</term>
2701 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2702 role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
2703 role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
2704 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2705 role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
2706 role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2707 role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
2708 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2709 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2710 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2711 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2712 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2713 role="identifier">size</phrase><phrase role="special">()</phrase>
2714 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2715 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2716 role="special">)</phrase></code>.
2721 <term>Effects:</term>
2724 Deallocates the stack space.
2731 If the library is compiled for segmented stacks, __segmented_stack__ is
2732 the only available stack allocator.
2736 <section id="context.stack.stack_traits">
2737 <title><link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link></title>
2739 <emphasis>stack_traits</emphasis> models a <emphasis>stack-traits</emphasis>
2740 providing a way to access certain properites defined by the enironment. Stack
2741 allocators use <emphasis>stack-traits</emphasis> to allocate stacks.
2743 <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>
2745 <phrase role="keyword">struct</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">{</phrase>
2746 <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>
2748 <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>
2750 <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>
2752 <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>
2754 <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>
2755 <phrase role="special">}</phrase>
2757 <bridgehead renderas="sect4" id="context.stack.stack_traits.h0">
2758 <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
2759 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
2760 role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase
2761 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code></link>
2766 <term>Returns:</term>
2769 Returns <code><phrase role="keyword">true</phrase></code> if the environment
2770 defines no limit for the size of a stack.
2775 <term>Throws:</term>
2783 <bridgehead renderas="sect4" id="context.stack.stack_traits.h1">
2784 <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
2785 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
2786 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
2787 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
2788 role="identifier">page_size</phrase><phrase role="special">()</phrase></code></link>
2793 <term>Returns:</term>
2796 Returns the page size in bytes.
2801 <term>Throws:</term>
2809 <bridgehead renderas="sect4" id="context.stack.stack_traits.h2">
2810 <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
2811 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
2812 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
2813 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
2814 role="identifier">default_size</phrase><phrase role="special">()</phrase></code></link>
2819 <term>Returns:</term>
2822 Returns a default stack size, which may be platform specific. If the
2823 stack is unbounded then the present implementation returns the maximum
2824 of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code>
2825 and <code><phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code>.
2830 <term>Throws:</term>
2838 <bridgehead renderas="sect4" id="context.stack.stack_traits.h3">
2839 <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
2840 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
2841 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
2842 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
2843 role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code></link>
2848 <term>Returns:</term>
2851 Returns the minimum size in bytes of stack defined by the environment
2852 (Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
2857 <term>Throws:</term>
2865 <bridgehead renderas="sect4" id="context.stack.stack_traits.h4">
2866 <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
2867 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
2868 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
2869 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
2870 role="identifier">maximum_size</phrase><phrase role="special">()</phrase></code></link>
2875 <term>Preconditions:</term>
2878 <code><phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code>
2879 returns <code><phrase role="keyword">false</phrase></code>.
2884 <term>Returns:</term>
2887 Returns the maximum size in bytes of stack defined by the environment.
2892 <term>Throws:</term>
2901 <section id="context.stack.stack_context">
2902 <title><link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title>
2904 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>stack_context</emphasis>
2905 which will contain the stack pointer and the size of the stack. In case of
2906 a <emphasis>segmented_stack</emphasis>, <emphasis>stack_context</emphasis>
2907 contains some extra control structures.
2909 <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">{</phrase>
2910 <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
2911 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
2913 <phrase role="comment">// might contain additional control structures</phrase>
2914 <phrase role="comment">// for segmented stacks</phrase>
2915 <phrase role="special">}</phrase>
2917 <bridgehead renderas="sect4" id="context.stack.stack_context.h0">
2918 <phrase id="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link
2919 linkend="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code><phrase
2920 role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase></code></link>
2928 Pointer to the beginning of the stack.
2933 <bridgehead renderas="sect4" id="context.stack.stack_context.h1">
2934 <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
2935 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
2936 role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
2937 <phrase role="identifier">size</phrase></code></link>
2945 Actual size of the stack.
2951 <section id="context.stack.valgrind">
2952 <title><link linkend="context.stack.valgrind">Support for valgrind</link></title>
2954 Running programs that switch stacks under valgrind causes problems. Property
2955 (b2 command-line) <code><phrase role="identifier">valgrind</phrase><phrase
2956 role="special">=</phrase><phrase role="identifier">on</phrase></code> let
2957 valgrind treat the memory regions as stack space which suppresses the errors.
2961 <section id="context.struct__preallocated_">
2962 <title><link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link></title>
2963 <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="special">{</phrase>
2964 <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
2965 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
2966 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">;</phrase>
2968 <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>
2969 <phrase role="special">};</phrase>
2971 <bridgehead renderas="sect3" id="context.struct__preallocated_.h0">
2972 <phrase id="context.struct__preallocated_.constructor"/><link linkend="context.struct__preallocated_.constructor">Constructor</link>
2974 <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>
2979 <term>Effects:</term>
2982 Creates an object of preallocated.
2988 <section id="context.performance">
2989 <title><link linkend="context.performance">Performance</link></title>
2991 Performance of <emphasis role="bold">Boost.Context</emphasis> was measured
2992 on the platforms shown in the following table. Performance measurements were
2993 taken using <code><phrase role="identifier">rdtsc</phrase></code> and <code><phrase
2994 role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase
2995 role="special">::</phrase><phrase role="identifier">high_resolution_clock</phrase></code>,
2996 with overhead corrections, on x86 platforms. In each case, cache warm-up was
2997 accounted for, and the one running thread was pinned to a single CPU. The code
2998 was compiled using the build options, 'variant = release cxxflags = -DBOOST_DISABLE_ASSERTS'.
3000 <table frame="all" id="context.performance.performance_of_context_switch">
3001 <title>Performance of context switch</title>
3017 execution_context (v1)
3022 execution_context (v2)
3031 x86_64 <footnote id="context.performance.f0">
3033 Intel Core i7-4770S 3.10GHz
3040 547 ns / 1433 cycles
3058 <section id="context.architectures">
3059 <title><link linkend="context.architectures">Architectures</link></title>
3061 <emphasis role="bold">Boost.Context</emphasis> supports following architectures:
3063 <table frame="all" id="context.architectures.supported_architectures___abi_binary_format__">
3064 <title>Supported architectures (<ABI|binary format>)</title>
3315 <section id="context.architectures.crosscompiling">
3316 <title><link linkend="context.architectures.crosscompiling">Cross compiling</link></title>
3318 Cross compiling the library requires to specify the build properties <architecture>,
3319 <address-model>, <binary-format> and <abi> at b2 command
3324 <section id="context.rationale">
3325 <title><link linkend="context.rationale">Rationale</link></title>
3326 <bridgehead renderas="sect3" id="context.rationale.h0">
3327 <phrase id="context.rationale.no_inline_assembler"/><link linkend="context.rationale.no_inline_assembler">No
3328 inline-assembler</link>
3331 Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support
3332 inline assembler. <footnote id="context.rationale.f0">
3334 <ulink url="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx">MSDN article
3335 'Inline Assembler'</ulink>
3337 </footnote>. Inlined assembler generates code bloating which is not welcome
3338 on embedded systems.
3340 <bridgehead renderas="sect3" id="context.rationale.h1">
3341 <phrase id="context.rationale.fcontext_t"/><link linkend="context.rationale.fcontext_t">fcontext_t</link>
3344 <emphasis role="bold">Boost.Context</emphasis> provides the low level API fcontext_t
3345 which is implemented in assembler to provide context swapping operations. fcontext_t
3346 is the part to port to new platforms.
3350 Context switches do not preserve the signal mask on UNIX systems.
3354 <emphasis>fcontext_t</emphasis> is an opaque pointer.
3356 <section id="context.rationale.other_apis_">
3357 <title><link linkend="context.rationale.other_apis_">Other APIs </link></title>
3358 <bridgehead renderas="sect4" id="context.rationale.other_apis_.h0">
3359 <phrase id="context.rationale.other_apis_.setjmp___longjmp__"/><link linkend="context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</link>
3362 C99 defines <code><phrase role="identifier">setjmp</phrase><phrase role="special">()</phrase></code>/<code><phrase
3363 role="identifier">longjmp</phrase><phrase role="special">()</phrase></code>
3364 to provide non-local jumps but it does not require that <emphasis>longjmp()</emphasis>
3365 preserves the current stack frame. Therefore, jumping into a function which
3366 was exited via a call to <emphasis>longjmp()</emphasis> is undefined <footnote
3367 id="context.rationale.other_apis_.f0">
3369 ISO/IEC 9899:1999, 2005, 7.13.2.1:2
3373 <bridgehead renderas="sect4" id="context.rationale.other_apis_.h1">
3374 <phrase id="context.rationale.other_apis_.ucontext_t"/><link linkend="context.rationale.other_apis_.ucontext_t">ucontext_t</link>
3377 Since POSIX.1-2003 <code><phrase role="identifier">ucontext_t</phrase></code>
3378 is deprecated and was removed in POSIX.1-2008! The function signature of
3379 <code><phrase role="identifier">makecontext</phrase><phrase role="special">()</phrase></code>
3382 <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>
3385 The third argument of <code><phrase role="identifier">makecontext</phrase><phrase
3386 role="special">()</phrase></code> specifies the number of integer arguments
3387 that follow which will require function pointer cast if <code><phrase role="identifier">func</phrase></code>
3388 will accept those arguments which is undefined in C99 <footnote id="context.rationale.other_apis_.f1">
3390 ISO/IEC 9899:1999, 2005, J.2
3395 The arguments in the var-arg list are required to be integers, passing pointers
3396 in var-arg list is not guaranteed to work, especially it will fail for architectures
3397 where pointers are larger than integers.
3400 <code><phrase role="identifier">ucontext_t</phrase></code> preserves signal
3401 mask between context switches which involves system calls consuming a lot
3402 of CPU cycles (ucontext_t is slower by perfomance_link[factor 13x] relative
3403 to <code><phrase role="identifier">fcontext_t</phrase></code>).
3405 <bridgehead renderas="sect4" id="context.rationale.other_apis_.h2">
3406 <phrase id="context.rationale.other_apis_.windows_fibers"/><link linkend="context.rationale.other_apis_.windows_fibers">Windows
3410 A drawback of Windows Fiber API is that <code><phrase role="identifier">CreateFiber</phrase><phrase
3411 role="special">()</phrase></code> does not accept a pointer to user allocated
3412 stack space preventing the reuse of stacks for other context instances. Because
3413 the Windows Fiber API requires to call <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
3414 role="special">()</phrase></code> if <code><phrase role="identifier">SwitchFiber</phrase><phrase
3415 role="special">()</phrase></code> is called for a thread which has not been
3416 converted to a fiber. For the same reason <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
3417 role="special">()</phrase></code> must be called after return from <code><phrase
3418 role="identifier">SwitchFiber</phrase><phrase role="special">()</phrase></code>
3419 if the thread was forced to be converted to a fiber before (which is inefficient).
3421 <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>
3422 <phrase role="special">{</phrase>
3423 <phrase role="identifier">ConvertThreadToFiber</phrase><phrase role="special">(</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase>
3424 <phrase role="identifier">SwitchToFiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">);</phrase>
3425 <phrase role="identifier">ConvertFiberToThread</phrase><phrase role="special">();</phrase>
3426 <phrase role="special">}</phrase>
3429 If the condition <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase
3430 role="special">>=</phrase> <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code>
3431 is met function <code><phrase role="identifier">IsThreadAFiber</phrase><phrase
3432 role="special">()</phrase></code> is provided in order to detect if the current
3433 thread was already converted. Unfortunately Windows XP + SP 2/3 defines
3434 <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase role="special">>=</phrase>
3435 <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code> without providing
3436 <code><phrase role="identifier">IsThreadAFiber</phrase><phrase role="special">()</phrase></code>.
3440 <section id="context.reference">
3441 <title><link linkend="context.reference">Reference</link></title>
3442 <bridgehead renderas="sect3" id="context.reference.h0">
3443 <phrase id="context.reference.arm"/><link linkend="context.reference.arm">ARM</link>
3448 AAPCS ABI: Procedure Call Standard for the ARM Architecture
3453 AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
3457 <bridgehead renderas="sect3" id="context.reference.h1">
3458 <phrase id="context.reference.mips"/><link linkend="context.reference.mips">MIPS</link>
3463 O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
3467 <bridgehead renderas="sect3" id="context.reference.h2">
3468 <phrase id="context.reference.powerpc32"/><link linkend="context.reference.powerpc32">PowerPC32</link>
3473 SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
3477 <bridgehead renderas="sect3" id="context.reference.h3">
3478 <phrase id="context.reference.powerpc64"/><link linkend="context.reference.powerpc64">PowerPC64</link>
3483 SYSV ABI: PowerPC User Instruction Set Architecture, Book I
3487 <bridgehead renderas="sect3" id="context.reference.h4">
3488 <phrase id="context.reference.x86_32"/><link linkend="context.reference.x86_32">X86-32</link>
3493 SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture
3494 Processor Supplement
3499 MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">Calling
3504 <bridgehead renderas="sect3" id="context.reference.h5">
3505 <phrase id="context.reference.x86_64"/><link linkend="context.reference.x86_64">X86-64</link>
3510 SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor
3516 MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx">x64
3517 Software Conventions</ulink>
3522 <section id="context.acknowledgements">
3523 <title><link linkend="context.acknowledgements">Acknowledgments</link></title>
3525 I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins,
3526 Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull,
3527 Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin
3528 Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente
3529 J. Botet Escriba, Wayne Piekarski.