]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/doc/scheduling.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / doc / scheduling.qbk
CommitLineData
7c673cae
FG
1[/
2 Copyright Oliver Kowalke 2013.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt
6]
7
8[#scheduling]
9[section:scheduling Scheduling]
10
11The fibers in a thread are coordinated by a fiber manager. Fibers trade
12control cooperatively, rather than preemptively: the currently-running fiber
13retains control until it invokes some operation that passes control to the
14manager. Each time a fiber suspends (or yields), the fiber manager consults a
15scheduler to determine which fiber will run next.
16
17__boost_fiber__ provides the fiber manager, but the scheduler is a
18customization point. (See [link custom Customization].)
19
20Each thread has its own scheduler. Different threads in a process may use
21different schedulers. By default, __boost_fiber__ implicitly instantiates
22[class_link round_robin] as the scheduler for each thread.
23
24You are explicitly permitted to code your own __algo__ subclass. For the most
25part, your `algorithm` subclass need not defend against cross-thread
26calls: the fiber manager intercepts and defers such calls. Most
27`algorithm` methods are only ever directly called from the thread whose
28fibers it is managing [mdash] with exceptions as documented below.
29
30Your `algorithm` subclass is engaged on a particular thread by calling
31[function_link use_scheduling_algorithm]:
32
33 void thread_fn() {
34 boost::fibers::use_scheduling_algorithm< my_fiber_scheduler >();
35 ...
36 }
37
38A scheduler class must implement interface __algo__. __boost_fiber__ provides
39one scheduler: [class_link round_robin].
40
41
42[class_heading algorithm]
43
44`algorithm` is the abstract base class defining the interface that a
45fiber scheduler must implement.
46
47 #include <boost/fiber/algo/algorithm.hpp>
48
49 namespace boost {
50 namespace fibers {
51 namespace algo {
52
53 struct algorithm {
54 virtual ~algorithm();
55
56 virtual void awakened( context *) noexcept = 0;
57
58 virtual context * pick_next() noexcept = 0;
59
60 virtual bool has_ready_fibers() const noexcept = 0;
61
62 virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
63
64 virtual void notify() noexcept = 0;
65 };
66
67 }}}
68
69[member_heading algorithm..awakened]
70
71 virtual void awakened( context * f) noexcept = 0;
72
73[variablelist
74[[Effects:] [Informs the scheduler that fiber `f` is ready to run. Fiber `f`
75might be newly launched, or it might have been blocked but has just been
76awakened, or it might have called [ns_function_link this_fiber..yield].]]
77[[Note:] [This method advises the scheduler to add fiber `f` to its collection
78of fibers ready to run. A typical scheduler implementation places `f` into a
79queue.]]
80[[See also:] [[class_link round_robin]]]
81]
82
83[member_heading algorithm..pick_next]
84
85 virtual context * pick_next() noexcept = 0;
86
87[variablelist
88[[Returns:] [the fiber which is to be resumed next, or `nullptr` if there is no
89ready fiber.]]
90[[Note:] [This is where the scheduler actually specifies the fiber which is to
91run next. A typical scheduler implementation chooses the head of the ready
92queue.]]
93[[See also:] [[class_link round_robin]]]
94]
95
96[member_heading algorithm..has_ready_fibers]
97
98 virtual bool has_ready_fibers() const noexcept = 0;
99
100[variablelist
101[[Returns:] [`true` if scheduler has fibers ready to run.]]
102]
103
104[member_heading algorithm..suspend_until]
105
106 virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept = 0;
107
108[variablelist
109[[Effects:] [Informs the scheduler that no fiber will be ready until
110time-point `abs_time`.]]
111[[Note:] [This method allows a custom scheduler to yield control to the
112containing environment in whatever way makes sense. The fiber manager is
113stating that `suspend_until()` need not return until `abs_time` [mdash] or
114[member_link algorithm..notify] is called [mdash] whichever comes first.
115The interaction with `notify()` means that, for instance, calling
116[@http://en.cppreference.com/w/cpp/thread/sleep_until
117`std::this_thread::sleep_until(abs_time)`] would be too simplistic.
118[member_link round_robin..suspend_until] uses a
119[@http://en.cppreference.com/w/cpp/thread/condition_variable
120`std::condition_variable`] to coordinate with [member_link
121round_robin..notify].]]
122[[Note:] [Given that `notify()` might be called from another thread, your
123`suspend_until()` implementation [mdash] like the rest of your
124`algorithm` implementation [mdash] must guard any data it shares with
125your `notify()` implementation.]]
126]
127
128[member_heading algorithm..notify]
129
130 virtual void notify() noexcept = 0;
131
132[variablelist
133[[Effects:] [Requests the scheduler to return from a pending call to
134[member_link algorithm..suspend_until].]]
135[[Note:] [Alone among the `algorithm` methods, `notify()` may be called
136from another thread. Your `notify()` implementation must guard any data it
137shares with the rest of your `algorithm` implementation.]]
138]
139
140[class_heading round_robin]
141
142This class implements __algo__, scheduling fibers in round-robin fashion.
143
144 #include <boost/fiber/algo/round_robin.hpp>
145
146 namespace boost {
147 namespace fibers {
148 namespace algo {
149
150 class round_robin : public algorithm {
151 virtual void awakened( context *) noexcept;
152
153 virtual context * pick_next() noexcept;
154
155 virtual bool has_ready_fibers() const noexcept;
156
157 virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept;
158
159 virtual void notify() noexcept;
160 };
161
162 }}}
163
164[member_heading round_robin..awakened]
165
166 virtual void awakened( context * f) noexcept;
167
168[variablelist
169[[Effects:] [Enqueues fiber `f` onto a ready queue.]]
170[[Throws:] [Nothing.]]
171]
172
173[member_heading round_robin..pick_next]
174
175 virtual context * pick_next() noexcept;
176
177[variablelist
178[[Returns:] [the fiber at the head of the ready queue, or `nullptr` if the
179queue is empty.]]
180[[Throws:] [Nothing.]]
181[[Note:] [Placing ready fibers onto the tail of a queue, and returning them
182from the head of that queue, shares the thread between ready fibers in
183round-robin fashion.]]
184]
185
186[member_heading round_robin..has_ready_fibers]
187
188 virtual bool has_ready_fibers() const noexcept;
189
190[variablelist
191[[Returns:] [`true` if scheduler has fibers ready to run.]]
192[[Throws:] [Nothing.]]
193]
194
195[member_heading round_robin..suspend_until]
196
197 virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept;
198
199[variablelist
200[[Effects:] [Informs `round_robin` that no ready fiber will be available until
201time-point `abs_time`. This implementation blocks in
202[@http://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
203`std::condition_variable::wait_until()`].]]
204[[Throws:] [Nothing.]]
205]
206
207[member_heading round_robin..notify]
208
209 virtual void notify() noexcept = 0;
210
211[variablelist
212[[Effects:] [Wake up a pending call to [member_link
213round_robin..suspend_until], some fibers might be ready. This implementation
214wakes `suspend_until()` via
215[@http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all
216`std::condition_variable::notify_all()`].]]
217[[Throws:] [Nothing.]]
218]
219
220
221[class_heading shared_work]
222
223This class implements __algo__; ready fibers are shared between all instances (running on different threads)
224of shared_work.
225
226 #include <boost/fiber/algo/shared_work.hpp>
227
228 namespace boost {
229 namespace fibers {
230 namespace algo {
231
232 class shared_work : public algorithm {
233 virtual void awakened( context *) noexcept;
234
235 virtual context * pick_next() noexcept;
236
237 virtual bool has_ready_fibers() const noexcept;
238
239 virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept;
240
241 virtual void notify() noexcept;
242 };
243
244 }}}
245
246[member_heading shared_work..awakened]
247
248 virtual void awakened( context * f) noexcept;
249
250[variablelist
251[[Effects:] [Enqueues fiber `f` onto the shared ready queue.]]
252[[Throws:] [Nothing.]]
253]
254
255[member_heading shared_work..pick_next]
256
257 virtual context * pick_next() noexcept;
258
259[variablelist
260[[Returns:] [the fiber at the head of the ready queue, or `nullptr` if the
261queue is empty.]]
262[[Throws:] [Nothing.]]
263[[Note:] [Placing ready fibers onto the tail of the shared queue, and returning them
264from the head of that queue, shares the thread between ready fibers in
265round-robin fashion.]]
266]
267
268[member_heading shared_work..has_ready_fibers]
269
270 virtual bool has_ready_fibers() const noexcept;
271
272[variablelist
273[[Returns:] [`true` if scheduler has fibers ready to run.]]
274[[Throws:] [Nothing.]]
275]
276
277[member_heading shared_work..suspend_until]
278
279 virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept;
280
281[variablelist
282[[Effects:] [Informs `shared_work` that no ready fiber will be available until
283time-point `abs_time`. This implementation blocks in
284[@http://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
285`std::condition_variable::wait_until()`].]]
286[[Throws:] [Nothing.]]
287]
288
289[member_heading shared_work..notify]
290
291 virtual void notify() noexcept = 0;
292
293[variablelist
294[[Effects:] [Wake up a pending call to [member_link
295shared_work..suspend_until], some fibers might be ready. This implementation
296wakes `suspend_until()` via
297[@http://en.cppreference.com/w/cpp/thread/condition_variable/notify_all
298`std::condition_variable::notify_all()`].]]
299[[Throws:] [Nothing.]]
300]
301
302
303[heading Custom Scheduler Fiber Properties]
304
305A scheduler class directly derived from __algo__ can use any information
306available from [class_link context] to implement the `algorithm`
307interface. But a custom scheduler might need to track additional properties
308for a fiber. For instance, a priority-based scheduler would need to track a
309fiber[s] priority.
310
311__boost_fiber__ provides a mechanism by which your custom scheduler can
312associate custom properties with each fiber.
313
314[class_heading fiber_properties]
315
316A custom fiber properties class must be derived from `fiber_properties`.
317
318 #include <boost/fiber/properties.hpp>
319
320 namespace boost {
321 namespace fibers {
322
323 class fiber_properties {
324 public:
325 fiber_properties( context *) noexcept;
326
327 virtual ~fiber_properties();
328
329 protected:
330 void notify() noexcept;
331 };
332
333 }}
334
335[heading Constructor]
336
337 fiber_properties( context * f) noexcept;
338
339[variablelist
340[[Effects:] [Constructs base-class component of custom subclass.]]
341[[Throws:] [Nothing.]]
342[[Note:] [Your subclass constructor must accept a `context*` and pass it
343to the base-class `fiber_properties` constructor.]]
344]
345
346[member_heading fiber_properties..notify]
347
348 void notify() noexcept;
349
350[variablelist
351[[Effects:] [Pass control to the custom [template_link
352algorithm_with_properties] subclass[s] [member_link
353algorithm_with_properties..property_change] method.]]
354[[Throws:] [Nothing.]]
355[[Note:] [A custom scheduler[s] [member_link
356algorithm_with_properties..pick_next] method might dynamically select
357from the ready fibers, or [member_link
358algorithm_with_properties..awakened] might instead insert each ready
359fiber into some form of ready queue for `pick_next()`. In the latter case, if
360application code modifies a fiber property (e.g. priority) that should affect
361that fiber[s] relationship to other ready fibers, the custom scheduler must be
362given the opportunity to reorder its ready queue. The custom property subclass
363should implement an access method to modify such a property; that access
364method should call `notify()` once the new property value has been stored.
365This passes control to the custom scheduler[s] `property_change()` method,
366allowing the custom scheduler to reorder its ready queue appropriately. Use at
367your discretion. Of course, if you define a property which does not affect the
368behavior of the `pick_next()` method, you need not call `notify()` when that
369property is modified.]]
370]
371
372[template_heading algorithm_with_properties]
373
374A custom scheduler that depends on a custom properties class `PROPS` should be
375derived from `algorithm_with_properties<PROPS>`. `PROPS` should be
376derived from [class_link fiber_properties].
377
378 #include <boost/fiber/algorithm.hpp>
379
380 namespace boost {
381 namespace fibers {
382 namespace algo {
383
384 template< typename PROPS >
385 struct algorithm_with_properties {
386 virtual void awakened( context *, PROPS &) noexcept = 0;
387
388 virtual context * pick_next() noexcept;
389
390 virtual bool has_ready_fibers() const noexcept;
391
392 virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
393
394 virtual void notify() noexcept = 0;
395
396 PROPS & properties( context *) noexcept;
397
398 virtual void property_change( context *, PROPS &) noexcept;
399
400 virtual fiber_properties * new_properties( context *);
401 };
402
403 }}}
404
405[member_heading algorithm_with_properties..awakened]
406
407 virtual void awakened( context * f, PROPS & properties) noexcept;
408
409[variablelist
410[[Effects:] [Informs the scheduler that fiber `f` is ready to run, like
411[member_link algorithm..awakened]. Passes the fiber[s] associated `PROPS`
412instance.]]
413[[Throws:] [Nothing.]]
414[[Note:] [An `algorithm_with_properties<>` subclass must override this
415method instead of `algorithm::awakened()`.]]
416]
417
418[member_heading algorithm_with_properties..pick_next]
419
420 virtual context * pick_next() noexcept;
421
422[variablelist
423[[Returns:] [the fiber which is to be resumed next, or `nullptr` if there is no
424ready fiber.]]
425[[Throws:] [Nothing.]]
426[[Note:] [same as [member_link algorithm..pick_next]]]
427]
428
429[member_heading algorithm_with_properties..has_ready_fibers]
430
431 virtual bool has_ready_fibers() const noexcept;
432
433[variablelist
434[[Returns:] [`true` if scheduler has fibers ready to run.]]
435[[Throws:] [Nothing.]]
436[[Note:] [same as [member_link algorithm..has_ready_fibers]]]
437]
438
439[member_heading algorithm_with_properties..suspend_until]
440
441 virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept = 0;
442
443[variablelist
444[[Effects:] [Informs the scheduler that no fiber will be ready until
445time-point `abs_time`.]]
446[[Note:] [same as [member_link algorithm..suspend_until]]]
447]
448
449[member_heading algorithm_with_properties..notify]
450
451 virtual void notify() noexcept = 0;
452
453[variablelist
454[[Effects:] [Requests the scheduler to return from a pending call to
455[member_link algorithm_with_properties..suspend_until].]]
456[[Note:] [same as [member_link algorithm..notify]]]
457]
458
459[member_heading algorithm_with_properties..properties]
460
461 PROPS& properties( context * f) noexcept;
462
463[variablelist
464[[Returns:] [the `PROPS` instance associated with fiber `f`.]]
465[[Throws:] [Nothing.]]
466[[Note:] [The fiber[s] associated `PROPS` instance is already passed to
467[member_link algorithm_with_properties..awakened] and [member_link
468algorithm_with_properties..property_change]. However, every [class_link
469algorithm] subclass is expected to track a collection of ready
470[class_link context] instances. This method allows your custom scheduler
471to retrieve the [class_link fiber_properties] subclass instance for any
472`context` in its collection.]]
473]
474
475[member_heading algorithm_with_properties..property_change]
476
477 virtual void property_change( context * f, PROPS & properties) noexcept;
478
479[variablelist
480[[Effects:] [Notify the custom scheduler of a possibly-relevant change to a
481property belonging to fiber `f`. `properties` contains the new values of
482all relevant properties.]]
483[[Throws:] [Nothing.]]
484[[Note:] [This method is only called when a custom [class_link
485fiber_properties] subclass explicitly calls [member_link
486fiber_properties..notify].]]
487]
488
489[member_heading algorithm_with_properties..new_properties]
490
491 virtual fiber_properties * new_properties( context * f);
492
493[variablelist
494[[Returns:] [A new instance of [class_link fiber_properties] subclass
495`PROPS`.]]
496[[Note:] [By default, `algorithm_with_properties<>::new_properties()`
497simply returns `new PROPS(f)`, placing the `PROPS` instance on the heap.
498Override this method to allocate `PROPS` some other way. The returned
499`fiber_properties` pointer must point to the `PROPS` instance to be associated
500with fiber `f`.]]
501]
502
503[#context]
504[class_heading context]
505
506While you are free to treat `context*` as an opaque token, certain
507`context` members may be useful to a custom scheduler implementation.
508
509[#ready_queue_t]
510Of particular note is the fact that `context` contains a hook to participate
511in a [@http://www.boost.org/doc/libs/release/doc/html/intrusive/list.html
512`boost::intrusive::list`] [^typedef][,]ed as
513`boost::fibers::scheduler::ready_queue_t`. This hook is reserved for use by
514[class_link algorithm] implementations. (For instance, [class_link
515round_robin] contains a `ready_queue_t` instance to manage its ready fibers.)
516See [member_link context..ready_is_linked], [member_link context..ready_link],
517[member_link context..ready_unlink].
518
519Your `algorithm` implementation may use any container you desire to
520manage passed `context` instances. `ready_queue_t` avoids some of the overhead
521of typical STL containers.
522
523 #include <boost/fiber/context.hpp>
524
525 namespace boost {
526 namespace fibers {
527
528 enum class type {
529 none = ``['unspecified]``,
530 main_context = ``['unspecified]``, // fiber associated with thread's stack
531 dispatcher_context = ``['unspecified]``, // special fiber for maintenance operations
532 worker_context = ``['unspecified]``, // fiber not special to the library
533 pinned_context = ``['unspecified]`` // fiber must not be migrated to another thread
534 };
535
536 class context {
537 public:
538 class id;
539
540 static context * active() noexcept;
541
542 context( context const&) = delete;
543 context & operator=( context const&) = delete;
544
545 id get_id() const noexcept;
546
547 void detach() noexcept;
548 void attach( context *) noexcept;
549
550 bool is_context( type) const noexcept;
551
552 bool is_terminated() const noexcept;
553
554 bool ready_is_linked() const noexcept;
555 bool remote_ready_is_linked() const noexcept;
556 bool wait_is_linked() const noexcept;
557
558 template< typename List >
559 void ready_link( List &) noexcept;
560 template< typename List >
561 void remote_ready_link( List &) noexcept;
562 template< typename List >
563 void wait_link( List &) noexcept;
564
565 void ready_unlink() noexcept;
566 void remote_ready_unlink() noexcept;
567 void wait_unlink() noexcept;
568
569 void suspend() noexcept;
570 void set_ready( context *) noexcept;
571 };
572
573 bool operator<( context const& l, context const& r) noexcept;
574
575 }}
576
577[static_member_heading context..active]
578
579 static context * active() noexcept;
580
581[variablelist
582[[Returns:] [Pointer to instance of current fiber.]]
583[[Throws:] [Nothing]]
584]
585
586[member_heading context..get_id]
587
588 context::id get_id() const noexcept;
589
590[variablelist
591[[Returns:] [If `*this` refers to a fiber of execution, an instance of
592__fiber_id__ that represents that fiber. Otherwise returns a
593default-constructed __fiber_id__.]]
594[[Throws:] [Nothing]]
595[[See also:] [[member_link fiber..get_id]]]
596]
597
598[member_heading context..attach]
599
600 void attach( context * f) noexcept;
601
602[variablelist
603[[Precondition:] [`this->get_scheduler() == nullptr`]]
604[[Effects:] [Attach fiber `f` to scheduler running `*this`.]]
605[[Postcondition:] [`this->get_scheduler() != nullptr`]]
606[[Throws:] [Nothing]]
607[[Note:] [A typical call: `boost::fibers::context::active()->attach(f);`]]
608[[Note:] [`f` must not be the running fiber[s] context. It must not be
609__blocked__ or terminated. It must not be a `pinned_context`. It must be
610currently detached. It must not currently be linked into an [class_link
611algorithm] implementation[s] ready queue. Most of these conditions are
612implied by `f` being owned by an `algorithm` implementation: that is, it
613has been passed to [member_link algorithm..awakened] but has not yet
614been returned by [member_link algorithm..pick_next]. Typically a
615`pick_next()` implementation would call `attach()` with the `context*` it is
616about to return. It must first remove `f` from its ready queue. You should
617never pass a `pinned_context` to `attach()` because you should never have
618called its `detach()` method in the first place.]]
619]
620
621[member_heading context..detach]
622
623 void detach() noexcept;
624
625[variablelist
626[[Precondition:] [`(this->get_scheduler() != nullptr) && ! this->is_context(pinned_context)`]]
627[[Effects:] [Detach fiber `*this` from its scheduler running `*this`.]]
628[[Throws:] [Nothing]]
629[[Postcondition:] [`this->get_scheduler() == nullptr`]]
630[[Note:] [This method must be called on the thread with which the fiber is
631currently associated. `*this` must not be the running fiber[s] context. It
632must not be __blocked__ or terminated. It must not be a `pinned_context`. It
633must not be detached already. It must not already be linked into an [class_link
634algorithm] implementation[s] ready queue. Most of these conditions are
635implied by `*this` being passed to [member_link algorithm..awakened]; an
636`awakened()` implementation must, however, test for `pinned_context`. It must
637call `detach()` ['before] linking `*this` into its ready queue.]]
638[[Note:] [In particular, it is erroneous to attempt to migrate a fiber from
639one thread to another by calling both `detach()` and `attach()` in the
640[member_link algorithm..pick_next] method. `pick_next()` is called on
641the intended destination thread. `detach()` must be called on the fiber[s]
642original thread. You must call `detach()` in the corresponding `awakened()`
643method.]]
644[[Note:] [Unless you intend make a fiber available for potential migration to
645a different thread, you should call neither `detach()` nor `attach()` with its
646`context`.]]
647]
648
649[member_heading context..is_context]
650
651 bool is_context( type t) const noexcept;
652
653[variablelist
654[[Returns:] [`true` if `*this` is of the specified type.]]
655[[Throws:] [Nothing]]
656[[Note:] [`type::worker_context` here means any fiber not special to the
657library. For `type::main_context` the `context` is associated with the ["main]
658fiber of the thread: the one implicitly created by the thread itself, rather
659than one explicitly created by __boost_fiber__. For `type::dispatcher_context`
660the `context` is associated with a ["dispatching] fiber, responsible for
661dispatching awakened fibers to a scheduler[s] ready-queue. The ["dispatching]
662fiber is an implementation detail of the fiber manager. The context of the
663["main] or ["dispatching] fiber [mdash] any fiber for which
664`is_context(pinned_context)` is `true` [mdash] must never be passed to
665[member_link context..detach].]]
666]
667
668[member_heading context..is_terminated]
669
670 bool is_terminated() const noexcept;
671
672[variablelist
673[[Returns:] [`true` if `*this` is no longer a valid context.]]
674[[Throws:] [Nothing]]
675[[Note:] [The `context` has returned from its fiber-function and is
676no longer considered a valid context.]]
677]
678
679[member_heading context..ready_is_linked]
680
681 bool ready_is_linked() const noexcept;
682
683[variablelist
684[[Returns:] [`true` if `*this` is stored in an [class_link algorithm]
685implementation[s] ready-queue.]]
686[[Throws:] [Nothing]]
687[[Note:] [Specifically, this method indicates whether [member_link
688context..ready_link] has been called on `*this`. `ready_is_linked()` has
689no information about participation in any other containers.]]
690]
691
692[member_heading context..remote_ready_is_linked]
693
694 bool remote_ready_is_linked() const noexcept;
695
696[variablelist
697[[Returns:] [`true` if `*this` is stored in the fiber manager[s]
698remote-ready-queue.]]
699[[Throws:] [Nothing]]
700[[Note:] [A `context` signaled as ready by another thread is first stored in
701the fiber manager[s] remote-ready-queue. This is the mechanism by which the
702fiber manager protects an [class_link algorithm] implementation from
703cross-thread [member_link algorithm..awakened] calls.]]
704]
705
706[member_heading context..wait_is_linked]
707
708 bool wait_is_linked() const noexcept;
709
710[variablelist
711[[Returns:] [`true` if `*this` is stored in the wait-queue of some
712synchronization object.]]
713[[Throws:] [Nothing]]
714[[Note:] [The `context` of a fiber waiting on a synchronization object (e.g.
715`mutex`, `condition_variable` etc.) is stored in the wait-queue of that
716synchronization object.]]
717]
718
719[member_heading context..ready_link]
720
721 template< typename List >
722 void ready_link( List & lst) noexcept;
723
724[variablelist
725[[Effects:] [Stores `*this` in ready-queue `lst`.]]
726[[Throws:] [Nothing]]
727[[Note:] [Argument `lst` must be a doubly-linked list from
728__boost_intrusive__, e.g. an instance of
729`boost::fibers::scheduler::ready_queue_t`. Specifically, it must be a
730[@http://www.boost.org/doc/libs/release/doc/html/intrusive/list.html
731`boost::intrusive::list`] compatible with the `list_member_hook` stored in the
732`context` object.]]
733]
734
735[member_heading context..remote_ready_link]
736
737 template< typename List >
738 void remote_ready_link( List & lst) noexcept;
739
740[variablelist
741[[Effects:] [Stores `*this` in remote-ready-queue `lst`.]]
742[[Throws:] [Nothing]]
743[[Note:] [Argument `lst` must be a doubly-linked list from
744__boost_intrusive__.]]
745]
746
747[member_heading context..wait_link]
748
749 template< typename List >
750 void wait_link( List & lst) noexcept;
751
752[variablelist
753[[Effects:] [Stores `*this` in wait-queue `lst`.]]
754[[Throws:] [Nothing]]
755[[Note:] [Argument `lst` must be a doubly-linked list from
756__boost_intrusive__.]]
757]
758
759[member_heading context..ready_unlink]
760
761 void ready_unlink() noexcept;
762
763[variablelist
764[[Effects:] [Removes `*this` from ready-queue: undoes the effect of
765[member_link context..ready_link].]]
766[[Throws:] [Nothing]]
767]
768
769[member_heading context..remote_ready_unlink]
770
771 void remote_ready_unlink() noexcept;
772
773[variablelist
774[[Effects:] [Removes `*this` from remote-ready-queue.]]
775[[Throws:] [Nothing]]
776]
777
778[member_heading context..wait_unlink]
779
780 void wait_unlink() noexcept;
781
782[variablelist
783[[Effects:] [Removes `*this` from wait-queue.]]
784[[Throws:] [Nothing]]
785]
786
787[member_heading context..suspend]
788
789 void suspend() noexcept;
790
791[variablelist
792[[Effects:] [Suspends the running fiber (the fiber associated with `*this`)
793until some other fiber passes `this` to [member_link context..set_ready].
794`*this` is marked as not-ready, and control passes to the scheduler to select
795another fiber to run.]]
796[[Throws:] [Nothing]]
797[[Note:] [This is a low-level API potentially useful for integration with
798other frameworks. It is not intended to be directly invoked by a typical
799application program.]]
800[[Note:] [The burden is on the caller to arrange for a call to `set_ready()`
801with a pointer to `this` at some future time.]]
802]
803
804[member_heading context..set_ready]
805
806 void set_ready( context * ctx ) noexcept;
807
808[variablelist
809[[Effects:] [Mark the fiber associated with context `*ctx` as being ready to
810run. This does not immediately resume that fiber; rather it passes the fiber
811to the scheduler for subsequent resumption. If the scheduler is idle (has not
812returned from a call to [member_link algorithm..suspend_until]),
813[member_link algorithm..notify] is called to wake it up.]]
814[[Throws:] [Nothing]]
815[[Note:] [This is a low-level API potentially useful for integration with
816other frameworks. It is not intended to be directly invoked by a typical
817application program.]]
818[[Note:] [It is explicitly supported to call `set_ready(ctx)` from a thread
819other than the one on which `*ctx` is currently suspended. The corresponding
820fiber will be resumed on its original thread in due course.]]
821[/[[Note:] [See [member_link context..migrate] for a way to migrate the
822suspended thread to the thread calling `set_ready()`.]]]
823]
824
825[hding context_less..Non-member function [`operator<()]]
826
827 bool operator<( context const& l, context const& r) noexcept;
828
829[variablelist
830[[Returns:] [`true` if `l.get_id() < r.get_id()` is `true`, `false`
831otherwise.]]
832[[Throws:] [Nothing.]]
833]
834
835
836[endsect]