thread_affinity is a good example of a property relevant only to a particular
sched_algorithm implementation. In examples/cpp03/migration, introduce an
'affinity' subclass of fiber_properties with a thread_affinity data
member.
Derive workstealing_round_robin from sched_algorithm_with_properties<affinity>
and, as required by that base class, forward awakened() calls to base-class
awakened() method.
Reimplement workstealing_round_robin's queue from a std::deque to a "by hand"
intrusive singly-linked list so we can efficiently remove an arbitrary item.
Make steal() method, instead of always popping the last item, scan the list to
find the last item willing to migrate (! thread_affinity).
From examples/cpp03/migration/workstealing_round_robin.hpp, an example of a
user-supplied sched_algorithm implementation, remove all boost/fiber/detail
#includes. These should no longer be needed.
Change sched_algorithm_with_properties::properties(worker_fiber*) method to
accept fiber_base* instead. The original signature was introduced when every
sched_algorithm implementation necessarily manipulated worker_fiber* pointers.
Now we're intentionally avoiding the need.
For the same reason, introduce a fiber_properties::back_ptr typedef so
subclasses can opaquely pass such pointers through their own constructor to
the base-class constructor.
Some reviewers disliked that to build a custom sched_algorithm subclass, you
must necessarily manipulate pointers to classes in the boost::fibers::detail
namespace. Redefine all such methods to use fiber_base* rather than
detail::worker_fiber*.
Hoist fiber_base* into boost::fibers namespace. We considered an opaque
typedef rather than fiber_base*, but in fact a sched_algorithm subclass may
need is_ready().
Moreover, a sched_algorithm subclass may well want to use an intrusive linked
list to queue fibers. Hoist worker_fiber::nxt_ pointer into fiber_base, and
remove worker_fiber::next() and next_reset() methods. This allows recasting
detail::fifo in terms of fiber_base*, therefore round_robin can be stated
almost entirely in terms of fiber_base* rather than worker_fiber*.
Recast fiber constructor taking worker_fiber* to take fiber_base* instead.
This constructor is used solely for fiber migration; with relevant functions
now returning fiber_base*, we think we no longer need fiber(worker_fiber*).