]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/doc/fiber.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / doc / fiber.qbk
1 [/
2 (C) Copyright 2007-8 Anthony Williams.
3 (C) Copyright 2011-12 Vicente J. Botet Escriba.
4 (C) Copyright 2013 Oliver Kowalke.
5 Distributed under the Boost Software License, Version 1.0.
6 (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt).
8 ]
9
10 [section:fiber_mgmt Fiber management]
11
12 [heading Synopsis]
13
14 #include <boost/fiber/all.hpp>
15
16 namespace boost {
17 namespace fibers {
18
19 class fiber;
20 bool operator<( fiber const& l, fiber const& r) noexcept;
21 void swap( fiber & l, fiber & r) noexcept;
22
23 template< typename SchedAlgo, typename ... Args >
24 void use_scheduling_algorithm( Args && ... args);
25 bool has_ready_fibers();
26
27 namespace algo {
28
29 struct algorithm;
30 template< typename PROPS >
31 struct algorithm_with_properties;
32 class round_robin;
33 class shared_round_robin;
34
35 }
36
37 namespace this_fiber {
38
39 fibers::id get_id() noexcept;
40 void yield();
41 template< typename Clock, typename Duration >
42 void sleep_until( std::chrono::time_point< Clock, Duration > const& abs_time)
43 template< typename Rep, typename Period >
44 void sleep_for( std::chrono::duration< Rep, Period > const& rel_time);
45 template< typename PROPS >
46 PROPS & properties();
47
48 }}
49
50
51 [heading Tutorial]
52
53 Each __fiber__ represents a micro-thread which will be launched and managed
54 cooperatively by a scheduler. Objects of type __fiber__ are move-only.
55
56 boost::fibers::fiber f1; // not-a-fiber
57
58 void f() {
59 boost::fibers::fiber f2( some_fn);
60
61 f1 = std::move( f2); // f2 moved to f1
62 }
63
64
65 [heading Launching]
66
67 A new fiber is launched by passing an object of a callable type that can be
68 invoked with no parameters.
69 If the object must not be copied or moved, then ['std::ref] can be used to
70 pass in a reference to the function object. In this case, the user must ensure
71 that the referenced object outlives the newly-created fiber.
72
73 struct callable {
74 void operator()();
75 };
76
77 boost::fibers::fiber copies_are_safe() {
78 callable x;
79 return boost::fibers::fiber( x);
80 } // x is destroyed, but the newly-created fiber has a copy, so this is OK
81
82 boost::fibers::fiber oops() {
83 callable x;
84 return boost::fibers::fiber( std::ref( x) );
85 } // x is destroyed, but the newly-created fiber still has a reference
86 // this leads to undefined behaviour
87
88 The spawned __fiber__ does not immediately start running. It is enqueued in
89 the list of ready-to-run fibers, and will run when the scheduler gets around
90 to it.
91
92
93 [#exceptions]
94 [heading Exceptions]
95
96 An exception escaping from the function or callable object passed to the __fiber__
97 constructor calls `std::terminate()`.
98 If you need to know which exception was thrown, use __future__ or
99 __packaged_task__.
100
101
102 [heading Detaching]
103
104 A __fiber__ can be detached by explicitly invoking the __detach__ member
105 function. After __detach__ is called on a fiber object, that object represents
106 __not_a_fiber__. The fiber object may then safely be destroyed.
107
108 boost::fibers::fiber( some_fn).detach();
109
110 __boost_fiber__ provides a number of ways to wait for a running fiber to
111 complete. You can coordinate even with a detached fiber using a [class_link
112 mutex], or [class_link condition_variable], or any of the other [link
113 synchronization synchronization objects] provided by the library.
114
115 If a detached fiber is still running when the thread[s] main fiber terminates,
116 the thread will not shut down.
117
118 [heading Joining]
119
120 In order to wait for a fiber to finish, the __join__ member function of the
121 __fiber__ object can be used. __join__ will block until the __fiber__ object
122 has completed.
123
124 void some_fn() {
125 ...
126 }
127
128 boost::fibers::fiber f( some_fn);
129 ...
130 f.join();
131
132 If the fiber has already completed, then __join__ returns immediately and
133 the joined __fiber__ object becomes __not_a_fiber__.
134
135
136 [heading Destruction]
137
138 When a __fiber__ object representing a valid execution context (the fiber is
139 __joinable__) is destroyed, the program terminates. If you intend the fiber to
140 outlive the __fiber__ object that launched it, use the __detach__ method.
141
142 {
143 boost::fibers::fiber f( some_fn);
144 } // std::terminate() will be called
145
146 {
147 boost::fibers::fiber f(some_fn);
148 f.detach();
149 } // okay, program continues
150
151
152 [#class_fiber_id]
153 [heading Fiber IDs]
154
155 Objects of class __fiber_id__ can be used to identify fibers. Each running
156 __fiber__ has a unique __fiber_id__ obtainable from the corresponding __fiber__
157 by calling the __get_id__ member function.
158 Objects of class __fiber_id__ can be copied, and used as keys in associative
159 containers: the full range of comparison operators is provided.
160 They can also be written to an output stream using the stream insertion
161 operator, though the output format is unspecified.
162
163 Each instance of __fiber_id__ either refers to some fiber, or __not_a_fiber__.
164 Instances that refer to __not_a_fiber__ compare equal to each other, but
165 not equal to any instances that refer to an actual fiber. The comparison
166 operators on __fiber_id__ yield a total order for every non-equal __fiber_id__.
167
168 [#class_launch]
169 [heading Enumeration `launch`]
170
171 `launch` specifies whether control passes immediately into a
172 newly-launched fiber.
173
174 enum class launch {
175 dispatch,
176 post
177 };
178
179 [heading `dispatch`]
180 [variablelist
181 [[Effects:] [A fiber launched with `launch == dispatch` is entered
182 immediately. In other words, launching a fiber with `dispatch` suspends the
183 caller (the previously-running fiber) until the fiber scheduler has a chance
184 to resume it later.]]
185 ]
186
187 [heading `post`]
188 [variablelist
189 [[Effects:] [A fiber launched with `launch == post` is passed to the
190 fiber scheduler as ready, but it is not yet entered. The caller (the
191 previously-running fiber) continues executing. The newly-launched fiber will
192 be entered when the fiber scheduler has a chance to resume it later.]]
193 [[Note:] [If `launch` is not explicitly specified, `post` is the default.]]
194 ]
195
196
197 [#class_fiber]
198 [section:fiber Class `fiber`]
199
200 #include <boost/fiber/fiber.hpp>
201
202 namespace boost {
203 namespace fibers {
204
205 class fiber {
206 public:
207 class id;
208
209 constexpr fiber() noexcept;
210
211 template< typename Fn, typename ... Args >
212 fiber( Fn &&, Args && ...);
213
214 template< typename Fn, typename ... Args >
215 fiber( ``[link class_launch `launch`]``, Fn &&, Args && ...);
216
217 template< typename __StackAllocator__, typename Fn, typename ... Args >
218 fiber( __allocator_arg_t__, StackAllocator, Fn &&, Args && ...);
219
220 template< typename __StackAllocator__, typename Fn, typename ... Args >
221 fiber( ``[link class_launch `launch`]``, __allocator_arg_t__, StackAllocator, Fn &&, Args && ...);
222
223 ~fiber();
224
225 fiber( fiber const&) = delete;
226
227 fiber & operator=( fiber const&) = delete;
228
229 fiber( fiber &&) noexcept;
230
231 fiber & operator=( fiber &&) noexcept;
232
233 void swap( fiber &) noexcept;
234
235 bool joinable() const noexcept;
236
237 id get_id() const noexcept;
238
239 void detach();
240
241 void join();
242
243 template< typename PROPS >
244 PROPS & properties();
245 };
246
247 bool operator<( fiber const&, fiber const&) noexcept;
248
249 void swap( fiber &, fiber &) noexcept;
250
251 template< typename SchedAlgo, typename ... Args >
252 void use_scheduling_algorithm( Args && ...) noexcept;
253
254 bool has_ready_fibers() noexcept;
255
256 }}
257
258
259 [heading Default constructor]
260
261 constexpr fiber() noexcept;
262
263 [variablelist
264 [[Effects:] [Constructs a __fiber__ instance that refers to __not_a_fiber__.]]
265 [[Postconditions:] [`this->get_id() == fiber::id()`]]
266 [[Throws:] [Nothing]]
267 ]
268
269 [#fiber_fiber]
270 [heading Constructor]
271
272 template< typename Fn, typename ... Args >
273 fiber( Fn && fn, Args && ... args);
274
275 template< typename Fn, typename ... Args >
276 fiber( ``[link class_launch `launch`]`` policy, Fn && fn, Args && ... args);
277
278 template< typename __StackAllocator__, typename Fn, typename ... Args >
279 fiber( __allocator_arg_t__, StackAllocator salloc, Fn && fn, Args && ... args);
280
281 template< typename __StackAllocator__, typename Fn, typename ... Args >
282 fiber( ``[link class_launch `launch`]`` policy, __allocator_arg_t__, StackAllocator salloc,
283 Fn && fn, Args && ... args);
284
285 [variablelist
286 [[Preconditions:] [`Fn` must be copyable or movable.]]
287 [[Effects:] [`fn` is copied or moved into internal storage for access by the
288 new fiber. If [class_link launch] is specified (or defaulted) to
289 `post`, the new fiber is marked ["ready] and will be entered at the next
290 opportunity. If `launch` is specified as `dispatch`, the calling fiber
291 is suspended and the new fiber is entered immediately.]]
292 [[Postconditions:] [`*this` refers to the newly created fiber of execution.]]
293 [[Throws:] [__fiber_error__ if an error occurs.]]
294 [[Note:] [__StackAllocator__ is required to allocate a stack for the internal
295 __econtext__. If `StackAllocator` is not explicitly passed, the default stack
296 allocator depends on `BOOST_USE_SEGMENTED_STACKS`: if defined, you will get a
297 __segmented_stack__, else a __fixedsize_stack__.]]
298 [[See also:] [__allocator_arg_t__, [link stack Stack allocation]]]
299 ]
300
301 [heading Move constructor]
302
303 fiber( fiber && other) noexcept;
304
305 [variablelist
306 [[Effects:] [Transfers ownership of the fiber managed by `other` to the newly
307 constructed __fiber__ instance.]]
308 [[Postconditions:] [`other.get_id() == fiber::id()` and `get_id()` returns the
309 value of `other.get_id()` prior to the construction]]
310 [[Throws:] [Nothing]]
311 ]
312
313 [heading Move assignment operator]
314
315 fiber & operator=( fiber && other) noexcept;
316
317 [variablelist
318 [[Effects:] [Transfers ownership of the fiber managed by `other` (if any) to
319 `*this`.]]
320 [[Postconditions:] [`other->get_id() == fiber::id()` and `get_id()` returns the
321 value of `other.get_id()` prior to the assignment.]]
322 [[Throws:] [Nothing]]
323 ]
324
325 [heading Destructor]
326
327 ~fiber();
328
329 [variablelist
330 [[Effects:] [If the fiber is __joinable__, calls std::terminate. Destroys
331 `*this`.]]
332 [[Note:] [The programmer must ensure that the destructor is never executed while
333 the fiber is still __joinable__. Even if you know that the fiber has completed,
334 you must still call either __join__ or __detach__ before destroying the `fiber`
335 object.]]
336 ]
337
338 [member_heading fiber..joinable]
339
340 bool joinable() const noexcept;
341
342 [variablelist
343 [[Returns:] [`true` if `*this` refers to a fiber of execution, which may or
344 may not have completed; otherwise `false`.]]
345 [[Throws:] [Nothing]]
346 ]
347
348 [member_heading fiber..join]
349
350 void join();
351
352 [variablelist
353 [[Preconditions:] [the fiber is __joinable__.]]
354 [[Effects:] [Waits for the referenced fiber of execution to complete.]]
355 [[Postconditions:] [The fiber of execution referenced on entry has completed.
356 `*this` no longer refers to any fiber of execution.]]
357 [[Throws:] [`fiber_error`]]
358 [[Error Conditions:] [
359 [*resource_deadlock_would_occur]: if `this->get_id() == boost::this_fiber::get_id()`.
360 [*invalid_argument]: if the fiber is not __joinable__.]]
361 ]
362
363 [member_heading fiber..detach]
364
365 void detach();
366
367 [variablelist
368 [[Preconditions:] [the fiber is __joinable__.]]
369 [[Effects:] [The fiber of execution becomes detached, and no longer has an
370 associated __fiber__ object.]]
371 [[Postconditions:] [`*this` no longer refers to any fiber of execution.]]
372 [[Throws:] [`fiber_error`]]
373 [[Error Conditions:] [
374 [*invalid_argument]: if the fiber is not __joinable__.]]
375 ]
376
377 [member_heading fiber..get_id]
378
379 fiber::id get_id() const noexcept;
380
381 [variablelist
382 [[Returns:] [If `*this` refers to a fiber of execution, an instance of
383 __fiber_id__ that represents that fiber. Otherwise returns a
384 default-constructed __fiber_id__.]]
385 [[Throws:] [Nothing]]
386 [[See also:] [[ns_function_link this_fiber..get_id]]]
387 ]
388
389 [template_member_heading fiber..properties]
390
391 template< typename PROPS >
392 PROPS & properties();
393
394 [variablelist
395 [[Preconditions:] [`*this` refers to a fiber of execution. [function_link
396 use_scheduling_algorithm] has been called from this thread with a subclass of
397 [template_link algorithm_with_properties] with the same template
398 argument `PROPS`.]]
399 [[Returns:] [a reference to the scheduler properties instance for `*this`.]]
400 [[Throws:] [`std::bad_cast` if `use_scheduling_algorithm()` was called with a
401 `algorithm_with_properties` subclass with some other template parameter
402 than `PROPS`.]]
403 [[Note:] [[template_link algorithm_with_properties] provides a way for a
404 user-coded scheduler to associate extended properties, such as priority, with
405 a fiber instance. This method allows access to those user-provided properties.]]
406 [[See also:] [[link custom Customization]]]
407 ]
408
409 [member_heading fiber..swap]
410
411 void swap( fiber & other) noexcept;
412
413 [variablelist
414 [[Effects:] [Exchanges the fiber of execution associated with `*this` and
415 `other`, so `*this` becomes associated with the fiber formerly associated with
416 `other`, and vice-versa.]]
417 [[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()`
418 prior to the call. `other.get_id()` returns the same value as `this->get_id()`
419 prior to the call.]]
420 [[Throws:] [Nothing]]
421 ]
422
423 [function_heading_for swap..fiber]
424
425 void swap( fiber & l, fiber & r) noexcept;
426
427 [variablelist
428 [[Effects:] [Same as `l.swap( r)`.]]
429 [[Throws:] [Nothing]]
430 ]
431
432 [function_heading operator<]
433
434 bool operator<( fiber const& l, fiber const& r) noexcept;
435
436 [variablelist
437 [[Returns:] [`true` if `l.get_id() < r.get_id()` is `true`, false otherwise.]]
438 [[Throws:] [Nothing.]]
439 ]
440
441 [function_heading use_scheduling_algorithm]
442
443 template< typename SchedAlgo, typename ... Args >
444 void use_scheduling_algorithm( Args && ... args) noexcept;
445
446 [variablelist
447 [[Effects:] [Directs __boost_fiber__ to use `SchedAlgo`, which must be a
448 concrete subclass of __algo__, as the scheduling algorithm for all fibers in
449 the current thread. Pass any required `SchedAlgo` constructor arguments as
450 `args`.]]
451 [[Note:] [If you want a given thread to use a non-default scheduling
452 algorithm, make that thread call `use_scheduling_algorithm()` before any other
453 __boost_fiber__ entry point. If no scheduler has been set for the current
454 thread by the time __boost_fiber__ needs to use it, the library will
455 create a default [class_link round_robin] instance for this thread.]]
456 [[Throws:] [Nothing]]
457 [[See also:] [[link scheduling Scheduling], [link custom Customization]]]
458 ]
459
460 [function_heading has_ready_fibers]
461
462 bool has_ready_fibers() noexcept;
463
464 [variablelist
465 [[Returns:] [`true` if scheduler has fibers ready to run.]]
466 [[Throws:] [Nothing]]
467 [[Note:] [Can be used for work-stealing to find an idle scheduler.]]
468 ]
469
470 [endsect] [/ section Class fiber]
471
472
473 [#class_id]
474 [section:id Class fiber::id]
475
476 #include <boost/fiber/fiber.hpp>
477
478 namespace boost {
479 namespace fibers {
480
481 class id {
482 public:
483 constexpr id() noexcept;
484
485 bool operator==( id const&) const noexcept;
486
487 bool operator!=( id const&) const noexcept;
488
489 bool operator<( id const&) const noexcept;
490
491 bool operator>( id const&) const noexcept;
492
493 bool operator<=( id const&) const noexcept;
494
495 bool operator>=( id const&) const noexcept;
496
497 template< typename charT, class traitsT >
498 friend std::basic_ostream< charT, traitsT > &
499 operator<<( std::basic_ostream< charT, traitsT > &, id const&);
500 };
501
502 }}
503
504 [heading Constructor]
505
506 constexpr id() noexcept;
507
508 [variablelist
509 [[Effects:] [Represents an instance of __not_a_fiber__.]]
510 [[Throws:] [Nothing.]]
511 ]
512
513 [operator_heading id..operator_equal..operator==]
514
515 bool operator==( id const& other) const noexcept;
516
517 [variablelist
518 [[Returns:] [`true` if `*this` and `other` represent the same fiber,
519 or both represent __not_a_fiber__, `false` otherwise.]]
520 [[Throws:] [Nothing.]]
521 ]
522
523 [operator_heading id..operator_not_equal..operator!=]
524
525 bool operator!=( id const& other) const noexcept;
526
527 [variablelist
528 [[Returns:] [[`! (other == * this)]]]
529 [[Throws:] [Nothing.]]
530 ]
531
532 [operator_heading id..operator_less..operator<]
533
534 bool operator<( id const& other) const noexcept;
535
536 [variablelist
537 [[Returns:] [`true` if `*this != other` is true and the
538 implementation-defined total order of `fiber::id` values places `*this` before
539 `other`, false otherwise.]]
540 [[Throws:] [Nothing.]]
541 ]
542
543 [operator_heading id..operator_greater..operator>]
544
545 bool operator>( id const& other) const noexcept;
546
547 [variablelist
548 [[Returns:] [`other < * this`]]
549 [[Throws:] [Nothing.]]
550 ]
551
552 [operator_heading id..operator_less_equal..operator<=]
553
554 bool operator<=( id const& other) const noexcept;
555
556 [variablelist
557 [[Returns:] [`! (other < * this)`]]
558 [[Throws:] [Nothing.]]
559 ]
560
561 [operator_heading id..operator_greater_equal..operator>=]
562
563 bool operator>=( id const& other) const noexcept;
564
565 [variablelist
566 [[Returns:] [`! (* this < other)`]]
567 [[Throws:] [Nothing.]]
568 ]
569
570 [heading operator<<]
571
572 template< typename charT, class traitsT >
573 std::basic_ostream< charT, traitsT > &
574 operator<<( std::basic_ostream< charT, traitsT > & os, id const& other);
575
576 [variablelist
577 [[Efects:] [Writes the representation of `other` to stream `os`. The
578 representation is unspecified.]]
579 [[Returns:] [`os`]]
580 ]
581
582
583 [endsect] [/ section Class fiber::id]
584
585
586 [section:this_fiber Namespace this_fiber]
587
588 In general, `this_fiber` operations may be called from the ["main] fiber
589 [mdash] the fiber on which function `main()` is entered [mdash] as well as
590 from an explicitly-launched thread[s] thread-function. That is, in many
591 respects the main fiber on each thread can be treated like an
592 explicitly-launched fiber.
593
594
595 namespace boost {
596 namespace this_fiber {
597
598 fibers::fiber::id get_id() noexcept;
599 void yield() noexcept;
600 template< typename Clock, typename Duration >
601 void sleep_until( std::chrono::time_point< Clock, Duration > const&);
602 template< typename Rep, typename Period >
603 void sleep_for( std::chrono::duration< Rep, Period > const&);
604 template< typename PROPS >
605 PROPS & properties();
606
607 }}
608
609 [ns_function_heading this_fiber..get_id]
610
611 #include <boost/fiber/operations.hpp>
612
613 namespace boost {
614 namespace fibers {
615
616 fiber::id get_id() noexcept;
617
618 }}
619
620 [variablelist
621 [[Returns:] [An instance of __fiber_id__ that represents the currently
622 executing fiber.]]
623 [[Throws:] [Nothing.]]
624 ]
625
626 [ns_function_heading this_fiber..sleep_until]
627
628 #include <boost/fiber/operations.hpp>
629
630 namespace boost {
631 namespace fibers {
632
633 template< typename Clock, typename Duration >
634 void sleep_until( std::chrono::time_point< Clock, Duration > const& abs_time);
635
636 }}
637
638 [variablelist
639 [[Effects:] [Suspends the current fiber until the time point specified by
640 `abs_time` has been reached.]]
641 [[Throws:] [timeout-related exceptions.]]
642 [[Note:] [The current fiber will not resume before `abs_time`, but there are no
643 guarantees about how soon after `abs_time` it might resume.]]
644 [[Note:] [["timeout-related exceptions] are as defined in the C++ Standard,
645 section [*30.2.4 Timing specifications \[thread.req.timing\]]: ["A function
646 that takes an argument which specifies a timeout will throw if, during its
647 execution, a clock, time point, or time duration throws an exception. Such
648 exceptions are referred to as ['timeout-related exceptions.]]]]
649 ]
650
651 [ns_function_heading this_fiber..sleep_for]
652
653 #include <boost/fiber/operations.hpp>
654
655 namespace boost {
656 namespace fibers {
657
658 template< class Rep, class Period >
659 void sleep_for( std::chrono::duration< Rep, Period > const& rel_time);
660
661 }}
662
663 [variablelist
664 [[Effects:] [Suspends the current fiber until the time duration specified by
665 `rel_time` has elapsed.]]
666 [[Throws:] [timeout-related exceptions.]]
667 [[Note:][The current fiber will not resume before `rel_time` has elapsed, but
668 there are no guarantees about how soon after that it might resume.]]
669 ]
670
671 [ns_function_heading this_fiber..yield]
672
673 #include <boost/fiber/operations.hpp>
674
675 namespace boost {
676 namespace fibers {
677
678 void yield() noexcept;
679
680 }}
681
682 [variablelist
683 [[Effects:] [Reliquishes execution control, allowing other fibers to run.]]
684 [[Throws:] [Nothing.]]
685 [[Note:] [A fiber that calls
686 `yield()` is not suspended: it is immediately passed to the scheduler as ready
687 to run.]]
688 ]
689
690 [ns_function_heading this_fiber..properties]
691
692 #include <boost/fiber/operations.hpp>
693
694 namespace boost {
695 namespace fibers {
696
697 template< typename PROPS >
698 PROPS & properties();
699
700 }}
701
702 [variablelist
703 [[Preconditions:] [[function_link use_scheduling_algorithm] has been called
704 from this thread with a subclass of [template_link
705 algorithm_with_properties] with the same template argument `PROPS`.]]
706 [[Returns:] [a reference to the scheduler properties instance for the
707 currently running fiber.]]
708 [[Throws:] [`std::bad_cast` if `use_scheduling_algorithm()` was called with an
709 `algorithm_with_properties` subclass with some other template parameter
710 than `PROPS`.]]
711 [[Note:] [[template_link algorithm_with_properties] provides a way for a
712 user-coded scheduler to associate extended properties, such as priority, with
713 a fiber instance. This function allows access to those user-provided
714 properties.]]
715 [[Note:] [The first time this function is called from the main fiber of a
716 thread, it may internally yield, permitting other fibers to run.]]
717 [[See also:] [[link custom Customization]]]
718 ]
719
720
721 [endsect] [/ section Namespace this_fiber]
722
723
724 [endsect] [/ section Fiber Management]