value_type value_pop() {
     for (;;) {
         slot * s{ nullptr };
         std::size_t idx{ 0 };
         channel_op_status status{ try_value_pop_( s, idx) };
         if ( channel_op_status::success == status) {
             value_type value{ std::move( * reinterpret_cast< value_type * >( std::addressof( s->storage) ) ) };
             s->cycle.store( idx + capacity_, std::memory_order_release);
             not_full_cnd_.notify_one();
             return std::move( value);
         } else if ( channel_op_status::empty == status) {
             std::unique_lock< std::mutex > lk{ mtx_ };
             ++waiting_consumer_;
             if ( is_closed() ) {
                 throw std::runtime_error{ "boost fiber: channel is closed" };
             }
             if ( ! is_empty_() ) {
                 continue;
             }
             not_empty_cnd_.wait( lk, [this](){ return is_closed() || ! is_empty_(); });
             --waiting_consumer_;
         } else {
             BOOST_ASSERT( channel_op_status::closed == status);
             throw std::runtime_error{ "boost fiber: channel is closed" };
         }
     }
 }
 channel_op_status pop( value_type & va) {
     std::unique_lock< mutex > lk( mtx_);
     not_empty_cond_.wait( lk,
                           [this](){
                             return is_closed_() || ! is_empty_();
                           });
     if ( is_closed_() && is_empty_() ) {
         return channel_op_status::closed;
     }
     va = value_pop_( lk);
     return channel_op_status::success;
 }
 value_type value_pop() {
     std::unique_lock< mutex > lk( mtx_);
     not_empty_cond_.wait( lk,
                           [this](){
                             return is_closed_() || ! is_empty_();
                           });
     if ( is_closed_() && is_empty_() ) {
         throw fiber_error(
                 std::make_error_code( std::errc::operation_not_permitted),
                 "boost fiber: queue is closed");
     }
     return value_pop_( lk);
 }
 channel_op_status pop_wait_until( value_type & va,
                                   std::chrono::time_point< Clock, Duration > const& timeout_time) {
     std::unique_lock< mutex > lk( mtx_);
     if ( ! not_empty_cond_.wait_until( lk, timeout_time,
                                        [this](){
                                              return is_closed_() || ! is_empty_();
                                        })) {
         return channel_op_status::timeout;
     }
     if ( is_closed_() && is_empty_() ) {
         return channel_op_status::closed;
     }
     va = value_pop_( lk);
     return channel_op_status::success;
 }
 channel_op_status try_pop( value_type & va) {
     std::unique_lock< mutex > lk( mtx_);
     if ( is_closed_() && is_empty_() ) {
         // let other fibers run
         lk.unlock();
         this_fiber::yield();
         return channel_op_status::closed;
     }
     if ( is_empty_() ) {
         // let other fibers run
         lk.unlock();
         this_fiber::yield();
         return channel_op_status::empty;
     }
     va = value_pop_( lk);
     return channel_op_status::success;
 }
	context * pop() {
        spinlock_lock lk{ splk_ };
		context * c = nullptr;
		if ( ! is_empty_() ) {
			c = slots_[cidx_];
			cidx_ = (cidx_ + 1) % capacity_;
		}
		return c;
	}
	context * steal() {
        spinlock_lock lk{ splk_ };
		context * c = nullptr;
		if ( ! is_empty_() ) {
			c = slots_[cidx_];
            if ( c->is_context( type::pinned_context) ) {
                return nullptr;
            }
			cidx_ = (cidx_ + 1) % capacity_;
		}
		return c;
	}
 value_type value_pop_( std::unique_lock< mutex > & lk) {
     BOOST_ASSERT( ! is_empty_() );
     auto old_head = pop_head_();
     return std::move( old_head->va);
 }
	bool empty() const noexcept {
        spinlock_lock lk{ splk_ };
		return is_empty_();
	}