2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-14 00:32:17 +00:00
Files
fiber/examples/cpp03/migration/workstealing_round_robin.cpp
Nat Goodspeed f1a34d297f 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.
2014-11-11 18:00:18 -05:00

85 lines
2.3 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)
#include "workstealing_round_robin.hpp"
#include <boost/assert.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
workstealing_round_robin::workstealing_round_robin():
rhead_(0),
rtail_(&rhead_)
{}
void
workstealing_round_robin::awakened( boost::fibers::fiber_base * f)
{
// forward this call to base-class method
boost::fibers::sched_algorithm_with_properties<affinity>::awakened(f);
boost::mutex::scoped_lock lk( mtx_);
// append this fiber_base* to ready queue
BOOST_ASSERT(! f->nxt_);
*rtail_ = f;
rtail_ = &f->nxt_;
}
boost::fibers::fiber_base *
workstealing_round_robin::pick_next()
{
boost::mutex::scoped_lock lk( mtx_);
boost::fibers::fiber_base * f = 0;
if ( rhead_ )
{
f = rhead_;
// pop head item from ready queue
rhead_ = rhead_->nxt_;
f->nxt_ = 0;
// if that was the last item, reset tail_
if (! rhead_)
rtail_ = &rhead_;
}
return f;
}
boost::fibers::fiber
workstealing_round_robin::steal() BOOST_NOEXCEPT
{
boost::mutex::scoped_lock lk( mtx_);
// Search the queue for the LAST fiber_base that's willing to migrate,
// in other words (! thread_affinity).
boost::fibers::fiber_base ** fp = &rhead_, ** found = 0;
for ( ; *fp; fp = &(*fp)->nxt_)
{
// do not consider any fiber whose thread_affinity is set
if (! properties(*fp).thread_affinity)
found = fp;
}
if (! found)
{
// either the queue is completely empty or all current entries have
// thread_affinity set
return boost::fibers::fiber(static_cast<boost::fibers::fiber_base*>(0));
}
// We found at least one fiber_base whose thread_affinity is NOT set;
// *found points to the last of these. Unlink and return it.
boost::fibers::fiber_base* ret = *found;
*found = ret->nxt_;
ret->nxt_ = 0;
// if that was the last item, reset tail_
if (! *found)
rtail_ = &rhead_;
return boost::fibers::fiber(ret);
}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif