123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- [/
- Copyright Oliver Kowalke 2013.
- Distributed under the Boost Software License, Version 1.0.
- (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt
- ]
- [/ import path is relative to this .qbk file]
- [import ../examples/priority.cpp]
- [#custom]
- [section:custom Customization]
- [heading Overview]
- As noted in the [link scheduling Scheduling] section, by default
- __boost_fiber__ uses its own [class_link round_robin] scheduler for each
- thread. To control the way __boost_fiber__ schedules ready fibers on a
- particular thread, in general you must follow several steps. This section
- discusses those steps, whereas [link scheduling Scheduling] serves as a
- reference for the classes involved.
- The library's fiber manager keeps track of suspended (blocked) fibers. Only
- when a fiber becomes ready to run is it passed to the scheduler. Of course, if
- there are fewer than two ready fibers, the scheduler's job is trivial. Only
- when there are two or more ready fibers does the particular scheduler
- implementation start to influence the overall sequence of fiber execution.
- In this section we illustrate a simple custom scheduler that honors an integer
- fiber priority. We will implement it such that a fiber with higher priority is
- preferred over a fiber with lower priority. Any fibers with equal priority
- values are serviced on a round-robin basis.
- [/ @path link is relative to (eventual) doc/html/index.html, hence ../..]
- The full source code for the examples below is found in
- [@../../examples/priority.cpp priority.cpp].
- [heading Custom Property Class]
- The first essential point is that we must associate an integer priority with
- each fiber.[footnote A previous version of the Fiber library implicitly
- tracked an int priority for each fiber, even though the default scheduler
- ignored it. This has been dropped, since the library now supports arbitrary
- scheduler-specific fiber properties.]
- One might suggest deriving a custom [class_link fiber] subclass to store such
- properties. There are a couple of reasons for the present mechanism.
- # __boost_fiber__ provides a number of different ways to launch a fiber.
- (Consider [ns_function_link fibers..async].) Higher-level libraries might
- introduce additional such wrapper functions. A custom scheduler must
- associate its custom properties with ['every] fiber in the thread, not only
- the ones explicitly launched by instantiating a custom `fiber` subclass.
- # Consider a large existing program that launches fibers in many different
- places in the code. We discover a need to introduce a custom scheduler for a
- particular thread. If supporting that scheduler's custom properties required
- a particular `fiber` subclass, we would have to hunt down and modify every
- place that launches a fiber on that thread.
- # The [class_link fiber] class is actually just a handle to internal
- [class_link context] data. A subclass of `fiber` would not add data to
- `context`.
- The present mechanism allows you to ["drop in] a custom scheduler with its
- attendant custom properties ['without] altering the rest of your application.
- Instead of deriving a custom scheduler fiber properties subclass from
- [class_link fiber], you must instead derive it from [class_link
- fiber_properties].
- [priority_props]
- [heading Custom Scheduler Class]
- Now we can derive a custom scheduler from [template_link
- algorithm_with_properties], specifying our custom property class
- `priority_props` as the template parameter.
- [priority_scheduler]
- Our example `priority_scheduler` doesn't override [member_link
- algorithm_with_properties..new_properties]: we're content with
- allocating `priority_props` instances on the heap.
- [heading Replace Default Scheduler]
- You must call [function_link use_scheduling_algorithm] at the start of each
- thread on which you want __boost_fiber__ to use your custom scheduler rather
- than its own default [class_link round_robin]. Specifically, you must call
- `use_scheduling_algorithm()` before performing any other __boost_fiber__
- operations on that thread.
- [main]
- [heading Use Properties]
- The running fiber can access its own [class_link fiber_properties] subclass
- instance by calling [ns_function_link this_fiber..properties]. Although
- `properties<>()` is a nullary function, you must pass, as a template
- parameter, the `fiber_properties` subclass.
- [main_name]
- Given a [class_link fiber] instance still connected with a running fiber (that
- is, not [member_link fiber..detach]ed), you may access that fiber's properties
- using [template_member_link fiber..properties]. As with
- `boost::this_fiber::properties<>()`, you must pass your `fiber_properties` subclass
- as the template parameter.
- [launch]
- Launching a new fiber schedules that fiber as ready, but does ['not]
- immediately enter its ['fiber-function]. The current fiber retains control
- until it blocks (or yields, or terminates) for some other reason. As shown in
- the `launch()` function above, it is reasonable to launch a fiber and
- immediately set relevant properties -- such as, for instance, its priority.
- Your custom scheduler can then make use of this information next time the
- fiber manager calls [member_link algorithm_with_properties..pick_next].
- [endsect]
|