mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-12 12:02:54 +00:00
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.
69 lines
1.7 KiB
C++
69 lines
1.7 KiB
C++
// 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)
|
|
|
|
#ifndef WORKSTEALING_ROUND_ROBIN_H
|
|
#define WORKSTEALING_ROUND_ROBIN_H
|
|
|
|
#include <deque>
|
|
|
|
#include <boost/config.hpp>
|
|
#include <boost/thread/mutex.hpp>
|
|
|
|
#include <boost/fiber/fiber.hpp>
|
|
#include <boost/fiber/properties.hpp>
|
|
|
|
#ifdef BOOST_HAS_ABI_HEADERS
|
|
# include BOOST_ABI_PREFIX
|
|
#endif
|
|
|
|
# if defined(BOOST_MSVC)
|
|
# pragma warning(push)
|
|
# pragma warning(disable:4251 4275)
|
|
# endif
|
|
|
|
struct affinity: public boost::fibers::fiber_properties
|
|
{
|
|
affinity(boost::fibers::fiber_properties::back_ptr p):
|
|
fiber_properties(p),
|
|
// By default, assume a given fiber CAN migrate to another thread.
|
|
thread_affinity(false)
|
|
{}
|
|
|
|
bool thread_affinity;
|
|
};
|
|
|
|
class workstealing_round_robin :
|
|
public boost::fibers::sched_algorithm_with_properties<affinity>
|
|
{
|
|
private:
|
|
boost::mutex mtx_;
|
|
|
|
// We should package these as a queue class. Better yet, we should
|
|
// refactor one of our existing (intrusive) queue classes to support the
|
|
// required operations generically. But for now...
|
|
boost::fibers::fiber_base *rhead_, **rtail_;
|
|
|
|
public:
|
|
workstealing_round_robin();
|
|
|
|
virtual void awakened( boost::fibers::fiber_base *);
|
|
|
|
virtual boost::fibers::fiber_base * pick_next();
|
|
|
|
virtual void priority( boost::fibers::fiber_base *, int) BOOST_NOEXCEPT;
|
|
|
|
boost::fibers::fiber steal();
|
|
};
|
|
|
|
# if defined(BOOST_MSVC)
|
|
# pragma warning(pop)
|
|
# endif
|
|
|
|
#ifdef BOOST_HAS_ABI_HEADERS
|
|
# include BOOST_ABI_SUFFIX
|
|
#endif
|
|
|
|
#endif // WORKSTEALING_ROUND_ROBIN_H
|