Get fiber_manager out of the business of casting returned properties: that
introduces a circular dependency. Defer casting to fiber_properties subclass
to consumers in fiber.hpp and operations.hpp.
- lambda capture expressions supports move-only types
- parameters are packed into std::tuple<> and with context-function
moved to the context-lambda (->lambda capture expression)
- in context-lambda context-function with packed parameters called
(-> deferred call)
Every sched_algorithm_with_properties<PROPS> subclass awakened() call must
ensure that control reaches sched_algorithm_with_properties<PROPS>::awakened()
_before_ any logic in the subclass method attempts to access properties. This
turns out to be all too easy to forget.
So instead, advise subclasses to overrride new awakened_props() method. Base-
class method sets things up and then calls awakened_props(). Moreover, when
the compiler supports it, sched_algorithm_with_properties<PROPS>::awakened()
is now marked 'final' to remind subclass authors to override awakened_props()
instead.
sched_algorithm knows nothing about properties, so that class isn't really the
best place for the property_change() virtual method. Introduce intermediate
sched_algorithm_with_properties_base class, which introduces property_change_()
virtual method accepting fiber_properties*. Then the properties-specific
sched_algorithm_with_properties<PROPS> implementation calls property_change()
(no trailing underscore) with fiber_properties* cast to PROPS&. Thus the user-
coded sched_algorithm implementation can override property_change() and accept
PROPS& rather than the generic fiber_properties* pointer. But
fiber_properties::notify() -- which doesn't know its own PROPS subclass -- can
nonetheless call sched_algorithm_with_properties_base::property_change_().
- Change some doc references from 'algorithm' to 'sched_algorithm'.
- Initial cut at supporting arbitrary user-coded scheduler properties.
- Set fiber_properties::sched_algo_ every time through awakened().
- Define sched_algorithm methods on fiber_base*, not worker_fiber*.
- Simplify detail::fifo by making tail_ point to last link pointer.
- Reimplement waiting_queue::push() using pointer-to-pointer trick.
- Reimplement waiting_queue::move_to() using fiber_base** scan.
- Make bounded_queue::tail_ a ptr* to simplify appending new nodes.
- Make unbounded_queue::tail_ a ptr* to simplify linking new nodes.
- Remove thread_affinity flag and access methods.
- Re-add thread_affinity specific to workstealing_round_robin.
- Remove 'priority' for every fiber, and its support methods.
Priority is another property that's only relevant for future sched_algorithm
implementations. We don't even have an example yet. It's a good candidate for
moving to a specific fiber_properties subclass for that specific
sched_algorithm implementation.
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.
Specificaly, remove access methods in worker_fiber, fiber and this_fiber.
thread_affinity is not used by any present library code. It was intended for
use by workstealing user sched_algorithm implementations. The properties
mechanism is a better way to address scheduler-specific properties.
Change waiting_queue::head_ from worker_fiber* to fiber_base* for uniformity
with worker_fiber::nxt_. This lets push() scan from head_ with a fiber_base**,
looking for the right insertion point. Insertion then becomes a couple
unconditional assignments.
Because push() always scans from head_, tail_ was actually never used. Remove
it.