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[/ import path is relative to this .qbk file] 9[import ../examples/priority.cpp] 10 11[#custom] 12[section:custom Customization] 13 14[heading Overview] 15 16As noted in the [link scheduling Scheduling] section, by default 17__boost_fiber__ uses its own [class_link round_robin] scheduler for each 18thread. To control the way __boost_fiber__ schedules ready fibers on a 19particular thread, in general you must follow several steps. This section 20discusses those steps, whereas [link scheduling Scheduling] serves as a 21reference for the classes involved. 22 23The library's fiber manager keeps track of suspended (blocked) fibers. Only 24when a fiber becomes ready to run is it passed to the scheduler. Of course, if 25there are fewer than two ready fibers, the scheduler's job is trivial. Only 26when there are two or more ready fibers does the particular scheduler 27implementation start to influence the overall sequence of fiber execution. 28 29In this section we illustrate a simple custom scheduler that honors an integer 30fiber priority. We will implement it such that a fiber with higher priority is 31preferred over a fiber with lower priority. Any fibers with equal priority 32values are serviced on a round-robin basis. 33 34[/ @path link is relative to (eventual) doc/html/index.html, hence ../..] 35The full source code for the examples below is found in 36[@../../examples/priority.cpp priority.cpp]. 37 38[heading Custom Property Class] 39 40The first essential point is that we must associate an integer priority with 41each fiber.[footnote A previous version of the Fiber library implicitly 42tracked an int priority for each fiber, even though the default scheduler 43ignored it. This has been dropped, since the library now supports arbitrary 44scheduler-specific fiber properties.] 45 46One might suggest deriving a custom [class_link fiber] subclass to store such 47properties. There are a couple of reasons for the present mechanism. 48 49# __boost_fiber__ provides a number of different ways to launch a fiber. 50 (Consider [ns_function_link fibers..async].) Higher-level libraries might 51 introduce additional such wrapper functions. A custom scheduler must 52 associate its custom properties with ['every] fiber in the thread, not only 53 the ones explicitly launched by instantiating a custom `fiber` subclass. 54# Consider a large existing program that launches fibers in many different 55 places in the code. We discover a need to introduce a custom scheduler for a 56 particular thread. If supporting that scheduler's custom properties required 57 a particular `fiber` subclass, we would have to hunt down and modify every 58 place that launches a fiber on that thread. 59# The [class_link fiber] class is actually just a handle to internal 60 [class_link context] data. A subclass of `fiber` would not add data to 61 `context`. 62 63The present mechanism allows you to ["drop in] a custom scheduler with its 64attendant custom properties ['without] altering the rest of your application. 65 66Instead of deriving a custom scheduler fiber properties subclass from 67[class_link fiber], you must instead derive it from [class_link 68fiber_properties]. 69 70[priority_props] 71 72[heading Custom Scheduler Class] 73 74Now we can derive a custom scheduler from [template_link 75algorithm_with_properties], specifying our custom property class 76`priority_props` as the template parameter. 77 78[priority_scheduler] 79 80Our example `priority_scheduler` doesn't override [member_link 81algorithm_with_properties..new_properties]: we're content with 82allocating `priority_props` instances on the heap. 83 84[heading Replace Default Scheduler] 85 86You must call [function_link use_scheduling_algorithm] at the start of each 87thread on which you want __boost_fiber__ to use your custom scheduler rather 88than its own default [class_link round_robin]. Specifically, you must call 89`use_scheduling_algorithm()` before performing any other __boost_fiber__ 90operations on that thread. 91 92[main] 93 94[heading Use Properties] 95 96The running fiber can access its own [class_link fiber_properties] subclass 97instance by calling [ns_function_link this_fiber..properties]. Although 98`properties<>()` is a nullary function, you must pass, as a template 99parameter, the `fiber_properties` subclass. 100 101[main_name] 102 103Given a [class_link fiber] instance still connected with a running fiber (that 104is, not [member_link fiber..detach]ed), you may access that fiber's properties 105using [template_member_link fiber..properties]. As with 106`boost::this_fiber::properties<>()`, you must pass your `fiber_properties` subclass 107as the template parameter. 108 109[launch] 110 111Launching a new fiber schedules that fiber as ready, but does ['not] 112immediately enter its ['fiber-function]. The current fiber retains control 113until it blocks (or yields, or terminates) for some other reason. As shown in 114the `launch()` function above, it is reasonable to launch a fiber and 115immediately set relevant properties -- such as, for instance, its priority. 116Your custom scheduler can then make use of this information next time the 117fiber manager calls [member_link algorithm_with_properties..pick_next]. 118 119[endsect] 120