]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/doc/html/fiber/migration.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / doc / html / fiber / migration.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Migrating fibers between threads</title>
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
7 <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Fiber">
8 <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Fiber">
9 <link rel="prev" href="fls.html" title="Fiber local storage">
10 <link rel="next" href="callbacks.html" title="Integrating Fibers with Asynchronous Callbacks">
11 </head>
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../more/index.htm">More</a></td>
20 </tr></table>
21 <hr>
22 <div class="spirit-nav">
23 <a accesskey="p" href="fls.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="callbacks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
27 <a name="fiber.migration"></a><a name="migration"></a><a class="link" href="migration.html" title="Migrating fibers between threads">Migrating fibers
28 between threads</a>
29 </h2></div></div></div>
30 <h4>
31 <a name="fiber.migration.h0"></a>
32 <span><a name="fiber.migration.overview"></a></span><a class="link" href="migration.html#fiber.migration.overview">Overview</a>
33 </h4>
34 <p>
35 Each fiber owns a stack and manages its execution state, including all registers
36 and CPU flags, the instruction pointer and the stack pointer. That means, in
37 general, a fiber is not bound to a specific thread.<sup>[<a name="fiber.migration.f0" href="#ftn.fiber.migration.f0" class="footnote">2</a>]</sup><sup>,</sup><sup>[<a name="fiber.migration.f1" href="#ftn.fiber.migration.f1" class="footnote">3</a>]</sup>
38 </p>
39 <p>
40 Migrating a fiber from a logical CPU with heavy workload to another logical
41 CPU with a lighter workload might speed up the overall execution. Note that
42 in the case of NUMA-architectures, it is not always advisable to migrate data
43 between threads. Suppose fiber <span class="emphasis"><em>f</em></span> is running on logical
44 CPU <span class="emphasis"><em>cpu0</em></span> which belongs to NUMA node <span class="emphasis"><em>node0</em></span>.
45 The data of <span class="emphasis"><em>f</em></span> are allocated on the physical memory located
46 at <span class="emphasis"><em>node0</em></span>. Migrating the fiber from <span class="emphasis"><em>cpu0</em></span>
47 to another logical CPU <span class="emphasis"><em>cpuX</em></span> which is part of a different
48 NUMA node <span class="emphasis"><em>nodeX</em></span> might reduce the performance of the application
49 due to increased latency of memory access.
50 </p>
51 <p>
52 Only fibers that are contained in <a class="link" href="scheduling.html#class_algorithm"><code class="computeroutput">algorithm</code></a>&#8217;s ready queue can
53 migrate between threads. You cannot migrate a running fiber, nor one that is
54 <a class="link" href="overview.html#blocking"><span class="emphasis"><em>blocked</em></span></a>. You cannot migrate
55 a fiber if its <a class="link" href="scheduling.html#context_is_context"><code class="computeroutput">context::is_context()</code></a> method returns <code class="computeroutput"><span class="keyword">true</span></code> for <code class="computeroutput"><span class="identifier">pinned_context</span></code>.
56 </p>
57 <p>
58 In <span class="bold"><strong>Boost.Fiber</strong></span> a fiber is migrated by invoking
59 <a class="link" href="scheduling.html#context_detach"><code class="computeroutput">context::detach()</code></a> on the thread from which the fiber migrates
60 and <a class="link" href="scheduling.html#context_attach"><code class="computeroutput">context::attach()</code></a> on the thread to which the fiber migrates.
61 </p>
62 <p>
63 Thus, fiber migration is accomplished by sharing state between instances of
64 a user-coded <a class="link" href="scheduling.html#class_algorithm"><code class="computeroutput">algorithm</code></a> implementation running on different threads.
65 The fiber&#8217;s original thread calls <a class="link" href="scheduling.html#algorithm_awakened"><code class="computeroutput">algorithm::awakened()</code></a>, passing
66 the fiber&#8217;s <a class="link" href="scheduling.html#class_context"><code class="computeroutput">context</code></a><code class="literal">*</code>. The <code class="computeroutput"><span class="identifier">awakened</span><span class="special">()</span></code> implementation calls <a class="link" href="scheduling.html#context_detach"><code class="computeroutput">context::detach()</code></a>.
67 </p>
68 <p>
69 At some later point, when the same or a different thread calls <a class="link" href="scheduling.html#algorithm_pick_next"><code class="computeroutput">algorithm::pick_next()</code></a>,
70 the <code class="computeroutput"><span class="identifier">pick_next</span><span class="special">()</span></code>
71 implementation selects a ready fiber and calls <a class="link" href="scheduling.html#context_attach"><code class="computeroutput">context::attach()</code></a> on
72 it before returning it.
73 </p>
74 <p>
75 As stated above, a <code class="computeroutput"><span class="identifier">context</span></code>
76 for which <code class="computeroutput"><span class="identifier">is_context</span><span class="special">(</span><span class="identifier">pinned_context</span><span class="special">)</span>
77 <span class="special">==</span> <span class="keyword">true</span></code>
78 must never be passed to either <a class="link" href="scheduling.html#context_detach"><code class="computeroutput">context::detach()</code></a> or <a class="link" href="scheduling.html#context_attach"><code class="computeroutput">context::attach()</code></a>.
79 It may only be returned from <code class="computeroutput"><span class="identifier">pick_next</span><span class="special">()</span></code> called by the <span class="emphasis"><em>same</em></span> thread
80 that passed that context to <code class="computeroutput"><span class="identifier">awakened</span><span class="special">()</span></code>.
81 </p>
82 <h4>
83 <a name="fiber.migration.h1"></a>
84 <span><a name="fiber.migration.example_of_work_sharing"></a></span><a class="link" href="migration.html#fiber.migration.example_of_work_sharing">Example
85 of work sharing</a>
86 </h4>
87 <p>
88 In the example <a href="../../../examples/work_sharing.cpp" target="_top">work_sharing.cpp</a>
89 multiple worker fibers are created on the main thread. Each fiber gets a character
90 as parameter at construction. This character is printed out ten times. Between
91 each iteration the fiber calls <a class="link" href="fiber_mgmt/this_fiber.html#this_fiber_yield"><code class="computeroutput">this_fiber::yield()</code></a>. That puts
92 the fiber in the ready queue of the fiber-scheduler <span class="emphasis"><em>shared_ready_queue</em></span>,
93 running in the current thread. The next fiber ready to be executed is dequeued
94 from the shared ready queue and resumed by <span class="emphasis"><em>shared_ready_queue</em></span>
95 running on <span class="emphasis"><em>any participating thread</em></span>.
96 </p>
97 <p>
98 All instances of <span class="emphasis"><em>shared_ready_queue</em></span> share one global concurrent
99 queue, used as ready queue. This mechanism shares all worker fibers between
100 all instances of <span class="emphasis"><em>shared_ready_queue</em></span>, thus between all
101 participating threads.
102 </p>
103 <h4>
104 <a name="fiber.migration.h2"></a>
105 <span><a name="fiber.migration.setup_of_threads_and_fibers"></a></span><a class="link" href="migration.html#fiber.migration.setup_of_threads_and_fibers">Setup
106 of threads and fibers</a>
107 </h4>
108 <p>
109 In <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code>
110 the fiber-scheduler is installed and the worker fibers and the threads are
111 launched.
112 </p>
113 <p>
114 </p>
115 <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">use_scheduling_algorithm</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">algo</span><span class="special">::</span><span class="identifier">shared_work</span> <span class="special">&gt;();</span> <a class="co" name="fiber.migration.c0" href="migration.html#fiber.migration.c1"><img src="../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
116
117 <span class="keyword">for</span> <span class="special">(</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"abcdefghijklmnopqrstuvwxyz"</span><span class="special">))</span> <span class="special">{</span> <a class="co" name="fiber.migration.c2" href="migration.html#fiber.migration.c3"><img src="../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
118 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">([</span><span class="identifier">c</span><span class="special">](){</span> <span class="identifier">whatevah</span><span class="special">(</span> <span class="identifier">c</span><span class="special">);</span> <span class="special">}).</span><span class="identifier">detach</span><span class="special">();</span>
119 <span class="special">++</span><span class="identifier">fiber_count</span><span class="special">;</span> <a class="co" name="fiber.migration.c4" href="migration.html#fiber.migration.c5"><img src="../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
120 <span class="special">}</span>
121 <span class="identifier">barrier</span> <span class="identifier">b</span><span class="special">(</span> <span class="number">4</span><span class="special">);</span>
122 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">threads</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <a class="co" name="fiber.migration.c6" href="migration.html#fiber.migration.c7"><img src="../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
123 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <span class="identifier">thread</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">b</span><span class="special">),</span>
124 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <span class="identifier">thread</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">b</span><span class="special">),</span>
125 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <span class="identifier">thread</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span>
126 <span class="special">};</span>
127 <span class="identifier">b</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span> <a class="co" name="fiber.migration.c8" href="migration.html#fiber.migration.c9"><img src="../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a>
128 <span class="special">{</span>
129 <span class="identifier">lock_t</span><a class="co" name="fiber.migration.c10" href="migration.html#fiber.migration.c11"><img src="../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_count</span><span class="special">);</span>
130 <span class="identifier">cnd_count</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="special">[](){</span> <span class="keyword">return</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">;</span> <span class="special">}</span> <span class="special">);</span> <a class="co" name="fiber.migration.c12" href="migration.html#fiber.migration.c13"><img src="../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a>
131 <span class="special">}</span> <a class="co" name="fiber.migration.c14" href="migration.html#fiber.migration.c15"><img src="../../../../../doc/src/images/callouts/8.png" alt="8" border="0"></a>
132 <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">);</span>
133 <span class="keyword">for</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="special">&amp;</span> <span class="identifier">t</span> <span class="special">:</span> <span class="identifier">threads</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.migration.c16" href="migration.html#fiber.migration.c17"><img src="../../../../../doc/src/images/callouts/9.png" alt="9" border="0"></a>
134 <span class="identifier">t</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
135 <span class="special">}</span>
136 </pre>
137 <p>
138 </p>
139 <div class="calloutlist"><table border="0" summary="Callout list">
140 <tr>
141 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c1"></a><a href="#fiber.migration.c0"><img src="../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
142 <td valign="top" align="left"><p>
143 Install the scheduling algorithm <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">algo</span><span class="special">::</span><span class="identifier">shared_work</span></code>
144 in the main thread too, so each new fiber gets launched into the shared
145 pool.
146 </p></td>
147 </tr>
148 <tr>
149 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c3"></a><a href="#fiber.migration.c2"><img src="../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
150 <td valign="top" align="left"><p>
151 Launch a number of worker fibers; each worker fiber picks up a character
152 that is passed as parameter to fiber-function <code class="computeroutput"><span class="identifier">whatevah</span></code>.
153 Each worker fiber gets detached.
154 </p></td>
155 </tr>
156 <tr>
157 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c5"></a><a href="#fiber.migration.c4"><img src="../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
158 <td valign="top" align="left"><p>
159 Increment fiber counter for each new fiber.
160 </p></td>
161 </tr>
162 <tr>
163 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c7"></a><a href="#fiber.migration.c6"><img src="../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
164 <td valign="top" align="left"><p>
165 Launch a couple of threads that join the work sharing.
166 </p></td>
167 </tr>
168 <tr>
169 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c9"></a><a href="#fiber.migration.c8"><img src="../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a> </p></td>
170 <td valign="top" align="left"><p>
171 sync with other threads: allow them to start processing
172 </p></td>
173 </tr>
174 <tr>
175 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c11"></a><a href="#fiber.migration.c10"><img src="../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> </p></td>
176 <td valign="top" align="left"><p>
177 <code class="computeroutput"><span class="identifier">lock_t</span></code> is typedef'ed as
178 <a href="http://en.cppreference.com/w/cpp/thread/unique_lock" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span></code></a>&lt; <a href="http://en.cppreference.com/w/cpp/thread/mutex" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span></code></a> &gt;
179 </p></td>
180 </tr>
181 <tr>
182 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c13"></a><a href="#fiber.migration.c12"><img src="../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a> </p></td>
183 <td valign="top" align="left"><p>
184 Suspend main fiber and resume worker fibers in the meanwhile. Main fiber
185 gets resumed (e.g returns from <code class="computeroutput"><span class="identifier">condition_variable_any</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>) if all worker fibers are complete.
186 </p></td>
187 </tr>
188 <tr>
189 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c15"></a><a href="#fiber.migration.c14"><img src="../../../../../doc/src/images/callouts/8.png" alt="8" border="0"></a> </p></td>
190 <td valign="top" align="left"><p>
191 Releasing lock of mtx_count is required before joining the threads, otherwise
192 the other threads would be blocked inside condition_variable::wait() and
193 would never return (deadlock).
194 </p></td>
195 </tr>
196 <tr>
197 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c17"></a><a href="#fiber.migration.c16"><img src="../../../../../doc/src/images/callouts/9.png" alt="9" border="0"></a> </p></td>
198 <td valign="top" align="left"><p>
199 wait for threads to terminate
200 </p></td>
201 </tr>
202 </table></div>
203 <p>
204 The start of the threads is synchronized with a barrier. The main fiber of
205 each thread (including main thread) is suspended until all worker fibers are
206 complete. When the main fiber returns from <a class="link" href="synchronization/conditions.html#condition_variable_wait"><code class="computeroutput">condition_variable::wait()</code></a>,
207 the thread terminates: the main thread joins all other threads.
208 </p>
209 <p>
210 </p>
211 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">thread</span><span class="special">(</span> <span class="identifier">barrier</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">{</span>
212 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">buffer</span><span class="special">;</span>
213 <span class="identifier">buffer</span> <span class="special">&lt;&lt;</span> <span class="string">"thread started "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
214 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
215 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">use_scheduling_algorithm</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">algo</span><span class="special">::</span><span class="identifier">shared_work</span> <span class="special">&gt;();</span> <a class="co" name="fiber.migration.c18" href="migration.html#fiber.migration.c19"><img src="../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
216 <span class="identifier">b</span><span class="special">-&gt;</span><span class="identifier">wait</span><span class="special">();</span> <a class="co" name="fiber.migration.c20" href="migration.html#fiber.migration.c21"><img src="../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
217 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_count</span><span class="special">);</span>
218 <span class="identifier">cnd_count</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="special">[](){</span> <span class="keyword">return</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">;</span> <span class="special">}</span> <span class="special">);</span> <a class="co" name="fiber.migration.c22" href="migration.html#fiber.migration.c23"><img src="../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
219 <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">);</span>
220 <span class="special">}</span>
221 </pre>
222 <p>
223 </p>
224 <div class="calloutlist"><table border="0" summary="Callout list">
225 <tr>
226 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c19"></a><a href="#fiber.migration.c18"><img src="../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
227 <td valign="top" align="left"><p>
228 Install the scheduling algorithm <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">algo</span><span class="special">::</span><span class="identifier">shared_work</span></code>
229 in order to join the work sharing.
230 </p></td>
231 </tr>
232 <tr>
233 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c21"></a><a href="#fiber.migration.c20"><img src="../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
234 <td valign="top" align="left"><p>
235 sync with other threads: allow them to start processing
236 </p></td>
237 </tr>
238 <tr>
239 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c23"></a><a href="#fiber.migration.c22"><img src="../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
240 <td valign="top" align="left"><p>
241 Suspend main fiber and resume worker fibers in the meanwhile. Main fiber
242 gets resumed (e.g returns from <code class="computeroutput"><span class="identifier">condition_variable_any</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>) if all worker fibers are complete.
243 </p></td>
244 </tr>
245 </table></div>
246 <p>
247 Each worker fiber executes function <code class="computeroutput"><span class="identifier">whatevah</span><span class="special">()</span></code> with character <code class="computeroutput"><span class="identifier">me</span></code>
248 as parameter. The fiber yields in a loop and prints out a message if it was
249 migrated to another thread.
250 </p>
251 <p>
252 </p>
253 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">whatevah</span><span class="special">(</span> <span class="keyword">char</span> <span class="identifier">me</span><span class="special">)</span> <span class="special">{</span>
254 <span class="keyword">try</span> <span class="special">{</span>
255 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">id</span> <span class="identifier">my_thread</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">();</span> <a class="co" name="fiber.migration.c24" href="migration.html#fiber.migration.c25"><img src="../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
256 <span class="special">{</span>
257 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">buffer</span><span class="special">;</span>
258 <span class="identifier">buffer</span> <span class="special">&lt;&lt;</span> <span class="string">"fiber "</span> <span class="special">&lt;&lt;</span> <span class="identifier">me</span> <span class="special">&lt;&lt;</span> <span class="string">" started on thread "</span> <span class="special">&lt;&lt;</span> <span class="identifier">my_thread</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
259 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
260 <span class="special">}</span>
261 <span class="keyword">for</span> <span class="special">(</span> <span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.migration.c26" href="migration.html#fiber.migration.c27"><img src="../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
262 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">yield</span><span class="special">();</span> <a class="co" name="fiber.migration.c28" href="migration.html#fiber.migration.c29"><img src="../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
263 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">id</span> <span class="identifier">new_thread</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">();</span> <a class="co" name="fiber.migration.c30" href="migration.html#fiber.migration.c31"><img src="../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
264 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">new_thread</span> <span class="special">!=</span> <span class="identifier">my_thread</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.migration.c32" href="migration.html#fiber.migration.c33"><img src="../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a>
265 <span class="identifier">my_thread</span> <span class="special">=</span> <span class="identifier">new_thread</span><span class="special">;</span>
266 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">buffer</span><span class="special">;</span>
267 <span class="identifier">buffer</span> <span class="special">&lt;&lt;</span> <span class="string">"fiber "</span> <span class="special">&lt;&lt;</span> <span class="identifier">me</span> <span class="special">&lt;&lt;</span> <span class="string">" switched to thread "</span> <span class="special">&lt;&lt;</span> <span class="identifier">my_thread</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
268 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
269 <span class="special">}</span>
270 <span class="special">}</span>
271 <span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span> <span class="special">...</span> <span class="special">)</span> <span class="special">{</span>
272 <span class="special">}</span>
273 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_count</span><span class="special">);</span>
274 <span class="keyword">if</span> <span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="special">--</span><span class="identifier">fiber_count</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.migration.c34" href="migration.html#fiber.migration.c35"><img src="../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a>
275 <span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
276 <span class="identifier">cnd_count</span><span class="special">.</span><span class="identifier">notify_all</span><span class="special">();</span> <a class="co" name="fiber.migration.c36" href="migration.html#fiber.migration.c37"><img src="../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a>
277 <span class="special">}</span>
278 <span class="special">}</span>
279 </pre>
280 <p>
281 </p>
282 <div class="calloutlist"><table border="0" summary="Callout list">
283 <tr>
284 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c25"></a><a href="#fiber.migration.c24"><img src="../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
285 <td valign="top" align="left"><p>
286 get ID of initial thread
287 </p></td>
288 </tr>
289 <tr>
290 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c27"></a><a href="#fiber.migration.c26"><img src="../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
291 <td valign="top" align="left"><p>
292 loop ten times
293 </p></td>
294 </tr>
295 <tr>
296 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c29"></a><a href="#fiber.migration.c28"><img src="../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
297 <td valign="top" align="left"><p>
298 yield to other fibers
299 </p></td>
300 </tr>
301 <tr>
302 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c31"></a><a href="#fiber.migration.c30"><img src="../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
303 <td valign="top" align="left"><p>
304 get ID of current thread
305 </p></td>
306 </tr>
307 <tr>
308 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c33"></a><a href="#fiber.migration.c32"><img src="../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a> </p></td>
309 <td valign="top" align="left"><p>
310 test if fiber was migrated to another thread
311 </p></td>
312 </tr>
313 <tr>
314 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c35"></a><a href="#fiber.migration.c34"><img src="../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> </p></td>
315 <td valign="top" align="left"><p>
316 Decrement fiber counter for each completed fiber.
317 </p></td>
318 </tr>
319 <tr>
320 <td width="5%" valign="top" align="left"><p><a name="fiber.migration.c37"></a><a href="#fiber.migration.c36"><img src="../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a> </p></td>
321 <td valign="top" align="left"><p>
322 Notify all fibers waiting on <code class="computeroutput"><span class="identifier">cnd_count</span></code>.
323 </p></td>
324 </tr>
325 </table></div>
326 <h4>
327 <a name="fiber.migration.h3"></a>
328 <span><a name="fiber.migration.scheduling_fibers"></a></span><a class="link" href="migration.html#fiber.migration.scheduling_fibers">Scheduling
329 fibers</a>
330 </h4>
331 <p>
332 The fiber scheduler <code class="computeroutput"><span class="identifier">shared_ready_queue</span></code>
333 is like <code class="computeroutput"><span class="identifier">round_robin</span></code>, except
334 that it shares a common ready queue among all participating threads. A thread
335 participates in this pool by executing <a class="link" href="fiber_mgmt/fiber.html#use_scheduling_algorithm"><code class="computeroutput">use_scheduling_algorithm()</code></a>
336 before
337 any other <span class="bold"><strong>Boost.Fiber</strong></span> operation.
338 </p>
339 <p>
340 The important point about the ready queue is that it&#8217;s a class static, common
341 to all instances of shared_ready_queue. Fibers that are enqueued via <a class="link" href="scheduling.html#algorithm_awakened"><code class="computeroutput">algorithm::awakened()</code></a> (fibers
342 that are ready to be resumed) are thus available to all threads. It is required
343 to reserve a separate, scheduler-specific queue for the thread&#8217;s main fiber
344 and dispatcher fibers: these may <span class="emphasis"><em>not</em></span> be shared between
345 threads! When we&#8217;re passed either of these fibers, push it there instead of
346 in the shared queue: it would be Bad News for thread B to retrieve and attempt
347 to execute thread A&#8217;s main fiber.
348 </p>
349 <p>
350 [awakened_ws]
351 </p>
352 <p>
353 When <a class="link" href="scheduling.html#algorithm_pick_next"><code class="computeroutput">algorithm::pick_next()</code></a> gets called inside one thread,
354 a fiber is dequeued from <span class="emphasis"><em>rqueue_</em></span> and will be resumed in
355 that thread.
356 </p>
357 <p>
358 [pick_next_ws]
359 </p>
360 <p>
361 The source code above is found in <a href="../../../examples/work_sharing.cpp" target="_top">work_sharing.cpp</a>.
362 </p>
363 <div class="footnotes">
364 <br><hr width="100" align="left">
365 <div class="footnote"><p><sup>[<a name="ftn.fiber.migration.f0" href="#fiber.migration.f0" class="para">2</a>] </sup>
366 The <span class="quote">&#8220;<span class="quote">main</span>&#8221;</span> fiber on each thread, that is, the fiber on which
367 the thread is launched, cannot migrate to any other thread. Also <span class="bold"><strong>Boost.Fiber</strong></span> implicitly creates a dispatcher fiber
368 for each thread &#8212; this cannot migrate either.
369 </p></div>
370 <div class="footnote"><p><sup>[<a name="ftn.fiber.migration.f1" href="#fiber.migration.f1" class="para">3</a>] </sup>
371 Of course it would be problematic to migrate a fiber that relies on <a class="link" href="overview.html#thread_local_storage">thread-local storage</a>.
372 </p></div>
373 </div>
374 </div>
375 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
376 <td align="left"></td>
377 <td align="right"><div class="copyright-footer">Copyright &#169; 2013 Oliver Kowalke<p>
378 Distributed under the Boost Software License, Version 1.0. (See accompanying
379 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
380 </p>
381 </div></td>
382 </tr></table>
383 <hr>
384 <div class="spirit-nav">
385 <a accesskey="p" href="fls.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="callbacks.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
386 </div>
387 </body>
388 </html>