mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-18 01:52:24 +00:00
Reimplement waiting_queue::push() using pointer-to-pointer trick.
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.
This commit is contained in:
@@ -30,8 +30,7 @@ class waiting_queue : private noncopyable
|
||||
{
|
||||
public:
|
||||
waiting_queue() BOOST_NOEXCEPT :
|
||||
head_( 0),
|
||||
tail_( 0)
|
||||
head_( 0)
|
||||
{}
|
||||
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
@@ -42,53 +41,36 @@ public:
|
||||
BOOST_ASSERT( 0 != item);
|
||||
BOOST_ASSERT( 0 == item->nxt_ );
|
||||
|
||||
if ( empty() )
|
||||
head_ = tail_ = item;
|
||||
else
|
||||
{
|
||||
worker_fiber * f = head_, * prev = 0;
|
||||
do
|
||||
{
|
||||
worker_fiber * nxt = static_cast<worker_fiber*>(f->nxt_);
|
||||
if ( item->time_point() <= f->time_point() )
|
||||
{
|
||||
if ( head_ == f)
|
||||
{
|
||||
BOOST_ASSERT( 0 == prev);
|
||||
// Skip past any worker_fibers in the queue whose time_point() is less
|
||||
// than item->time_point(), looking for the first worker_fiber in the
|
||||
// queue whose time_point() is at least item->time_point(). Insert
|
||||
// item before that. In other words, insert item so as to preserve
|
||||
// ascending order of time_point() values. (Recall that a worker_fiber
|
||||
// waiting with no timeout uses the maximum time_point value.)
|
||||
|
||||
item->nxt_ = f;
|
||||
head_ = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT( 0 != prev);
|
||||
// We do this by walking the linked list of nxt_ fields with a
|
||||
// fiber_base**. In other words, first we point to &head_, then to
|
||||
// &head_->nxt_, then to &head_->nxt_->nxt_ and so forth. When we find
|
||||
// the item with the right time_point(), we're already pointing to the
|
||||
// fiber_base* that links it into the list. Insert item right there.
|
||||
|
||||
item->nxt_ = f;
|
||||
prev->nxt_ = item;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ( tail_ == f)
|
||||
{
|
||||
BOOST_ASSERT( 0 == nxt);
|
||||
fiber_base** f = &head_;
|
||||
for ( ; *f; f = &(*f)->nxt_)
|
||||
if (item->time_point() <= (static_cast<worker_fiber*>(*f))->time_point())
|
||||
break;
|
||||
|
||||
tail_->nxt_ = item;
|
||||
tail_ = item;
|
||||
break;
|
||||
}
|
||||
|
||||
prev = f;
|
||||
f = nxt;
|
||||
}
|
||||
while ( 0 != f);
|
||||
}
|
||||
// Here, either we reached the end of the list (! *f) or we found a
|
||||
// (*f) before which to insert 'item'. Break the link at *f and insert
|
||||
// item.
|
||||
item->nxt_ = *f;
|
||||
*f = item;
|
||||
}
|
||||
|
||||
worker_fiber * top() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT( ! empty() );
|
||||
|
||||
return head_;
|
||||
return static_cast<worker_fiber*>(head_);
|
||||
}
|
||||
|
||||
template< typename SchedAlgo, typename Fn >
|
||||
@@ -96,28 +78,23 @@ public:
|
||||
{
|
||||
BOOST_ASSERT( sched_algo);
|
||||
|
||||
worker_fiber * f = head_, * prev = 0;
|
||||
worker_fiber * f = static_cast<worker_fiber*>(head_), * prev = 0;
|
||||
chrono::high_resolution_clock::time_point now( chrono::high_resolution_clock::now() );
|
||||
while ( 0 != f)
|
||||
{
|
||||
worker_fiber * nxt = static_cast<worker_fiber*>(f->nxt_);
|
||||
if ( fn( f, now) )
|
||||
{
|
||||
if ( f == head_)
|
||||
if ( f == static_cast<worker_fiber*>(head_))
|
||||
{
|
||||
BOOST_ASSERT( 0 == prev);
|
||||
|
||||
head_ = nxt;
|
||||
if ( 0 == head_)
|
||||
tail_ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT( 0 != prev);
|
||||
|
||||
if ( 0 == nxt)
|
||||
tail_ = prev;
|
||||
|
||||
prev->nxt_ = nxt;
|
||||
}
|
||||
f->nxt_ = 0;
|
||||
@@ -133,12 +110,10 @@ public:
|
||||
void swap( waiting_queue & other)
|
||||
{
|
||||
std::swap( head_, other.head_);
|
||||
std::swap( tail_, other.tail_);
|
||||
}
|
||||
|
||||
private:
|
||||
worker_fiber * head_;
|
||||
worker_fiber * tail_;
|
||||
fiber_base * head_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
Reference in New Issue
Block a user