Esempio n. 1
0
 cv_status wait_until( LockType & lt, std::chrono::time_point< Clock, Duration > const& timeout_time_) {
     context * active_ctx = context::active();
     cv_status status = cv_status::no_timeout;
     std::chrono::steady_clock::time_point timeout_time = detail::convert( timeout_time_);
     // atomically call lt.unlock() and block on *this
     // store this fiber in waiting-queue
     detail::spinlock_lock lk{ wait_queue_splk_ };
     BOOST_ASSERT( ! active_ctx->wait_is_linked() );
     active_ctx->wait_link( wait_queue_);
     // unlock external lt
     lt.unlock();
     // suspend this fiber
     if ( ! active_ctx->wait_until( timeout_time, lk) ) {
         status = cv_status::timeout;
         // relock local lk
         lk.lock();
         // remove from waiting-queue
         wait_queue_.remove( * active_ctx);
         // unlock local lk
         lk.unlock();
     }
     // relock external again before returning
     try {
         lt.lock();
     } catch (...) {
         std::terminate();
     }
     // post-conditions
     BOOST_ASSERT( ! active_ctx->wait_is_linked() );
     return status;
 }
Esempio n. 2
0
 void wait( LockType & lt) {
     context * ctx = context::active();
     // atomically call lt.unlock() and block on *this
     // store this fiber in waiting-queue
     detail::spinlock_lock lk( wait_queue_splk_);
     BOOST_ASSERT( ! ctx->wait_is_linked() );
     ctx->wait_link( wait_queue_);
     // unlock external lt
     lt.unlock();
     // suspend this fiber
     ctx->suspend( lk);
     // relock local lk
     lk.lock();
     // remove from waiting-queue
     ctx->wait_unlink();
     // unlock local lk
     lk.unlock();
     // relock external again before returning
     try {
         lt.lock();
     } catch (...) {
         std::terminate();
     }
     // post-conditions
     BOOST_ASSERT( ! ctx->wait_is_linked() );
 }
Esempio n. 3
0
    void wait( LockType & lt)
    {
        detail::notify::ptr_t n( detail::scheduler::instance().active() );
        try
        {
            if ( n)
            {
                // store this fiber in order to be notified later
                unique_lock< detail::spinlock > lk( waiting_mtx_);
                waiting_.push_back( n);
                lt.unlock();

                // suspend fiber
                detail::scheduler::instance().wait( lk);

                // check if fiber was interrupted
                this_fiber::interruption_point();
            }
            else
            {
                // notifier for main-fiber
                n = detail::scheduler::instance().notifier();
                // store this fiber in order to be notified later
                unique_lock< detail::spinlock > lk( waiting_mtx_);
                waiting_.push_back( n);

                lk.unlock();
                lt.unlock();
                while ( ! n->is_ready() )
                {
                    fprintf(stdout, "condition: main-fiber not woken-up\n");
                    // run scheduler
                    detail::scheduler::instance().run();
                }
                    fprintf(stdout, "condition: main-fiber woken-up\n");
            }
        }
        catch (...)
        {
            // remove fiber from waiting_
            unique_lock< detail::spinlock > lk( waiting_mtx_);
            waiting_.erase(
                std::find( waiting_.begin(), waiting_.end(), n) );
            throw;
        }

        // lock external again before returning
        lt.lock();
    }
Esempio n. 4
0
    void wait( LockType & lt)
    {
        detail::notify::ptr_t n( detail::scheduler::instance()->active() );
        try
        {
            if ( n)
            {
                // store this fiber in order to be notified later
                waiting_.push_back( n);
                lt.unlock();

                // suspend fiber
                detail::scheduler::instance()->wait();

                // check if fiber was interrupted
                this_fiber::interruption_point();
            }
            else
            {
                // notifier for main-fiber
                detail::main_notifier mn;
                n = detail::main_notifier::make_pointer( mn);

                // store this fiber in order to be notified later
                waiting_.push_back( n);

                lt.unlock();
                while ( ! n->is_ready() )
                {
                    // run scheduler
                    detail::scheduler::instance()->run();
                }
            }
        }
        catch (...)
        {
            // remove fiber from waiting-list
            waiting_.erase(
                std::find( waiting_.begin(), waiting_.end(), n) );
            throw;
        }

        // lock external again before returning
        lt.lock();
    }
Esempio n. 5
0
	void wait( LockType & lt)
	{
		{
			mutex::scoped_lock lk( enter_mtx_);
			BOOST_ASSERT( lk);
			++waiters_;
			lt.unlock();
		}

		bool unlock_enter_mtx = false;
		for (;;)
		{
			while ( SLEEPING == cmd_)
				strategy_->wait_for_object( id_);

			mutex::scoped_lock lk( check_mtx_);
			BOOST_ASSERT( lk);

			if ( SLEEPING == cmd_)
				continue;
			else if ( NOTIFY_ONE == cmd_)
			{
				cmd_ = SLEEPING;	
				unlock_enter_mtx = true;
				--waiters_;
				break;
			}
			else
			{
				unlock_enter_mtx = 0 == --waiters_;
				if ( unlock_enter_mtx)
					cmd_ = SLEEPING;
				break;
			}
		}

		if ( unlock_enter_mtx)
			enter_mtx_.unlock();

		lt.lock();
	}
Esempio n. 6
0
 static bool isFullyReset(LockType& lock)
 {
     return lock.isFullyReset();
 }
Esempio n. 7
0
 explicit upgrade_to_unique_lock(LockType& other) {
   lockable_ = other.release();
   if (lockable_) lockable_->unlock_upgrade_and_lock();
 }
Esempio n. 8
0
 void unlock() const
 {
     state.store(Unlocked, std::memory_order_release);
 }
Esempio n. 9
0
 bool try_lock() const
 {
     return state.exchange(Locked, std::memory_order_acquire) != Locked;
 }
Esempio n. 10
0
 upgrade_to_unique_lock(LockType& other) {
   m_lockable = other.release();
   if (m_lockable) m_lockable->lock_upgrade();
 }
Esempio n. 11
0
    void wait( LockType & lt)
    {
        detail::fiber_base * n( fm_active() );
        try
        {
            if ( n)
            {
                // lock spinlock
                unique_lock< detail::spinlock > lk( splk_);

                BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
                // store this fiber in waiting-queue
                // in order notify (resume) this fiber later
                waiting_.push_back( n);

                // unlock external
                lt.unlock();

                // suspend this fiber
                // locked spinlock will be released if this fiber
                // was stored inside schedulers's waiting-queue
                fm_wait( lk);

                // this fiber was notified and resumed
                // check if fiber was interrupted
                this_fiber::interruption_point();

                // lock external again before returning
                lt.lock();
            }
            else
            {
                // notification for main-fiber
                detail::main_fiber mf;
                n = & mf;

                // lock spinlock
                unique_lock< detail::spinlock > lk( splk_);

                BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
                // store this main-notifier in waiting-queue
                // in order to be notified later
                waiting_.push_back( n);

                // unlock external
                lt.unlock();

                // release spinlock
                lk.unlock();

                // loop until main-notifier gets notified
                while ( ! n->is_ready() )
                    // run scheduler
                    fm_run();

                // lock external again before returning
                lt.lock();
            }
        }
        catch (...)
        {
            unique_lock< detail::spinlock > lk( splk_);
            std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
            if (wit != waiting_.end())
            {
                // remove fiber from waiting-list
                waiting_.erase( wit );
            }
            throw;
        }
    }
Esempio n. 12
0
    cv_status wait_until( LockType & lt, chrono::time_point< Clock, Duration > const& timeout_time_)
    {
        cv_status status = cv_status::no_timeout;
        chrono::high_resolution_clock::time_point timeout_time(
            detail::convert_tp( timeout_time_) );

        detail::fiber_base * n( fm_active() );
        try
        {
            if ( n)
            {
                // lock spinlock
                unique_lock< detail::spinlock > lk( splk_);

                // store this fiber in waiting-queue
                // in order notify (resume) this fiber later
                waiting_.push_back( n);

                // unlock external
                lt.unlock();

                // suspend this fiber
                // locked spinlock will be released if this fiber
                // was stored inside schedulers's waiting-queue
                if ( ! fm_wait_until( timeout_time, lk) )
                {
                    // this fiber was not notified before timeout
                    // lock spinlock again
                    unique_lock< detail::spinlock > lk( splk_);
                    std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
                    if (wit != waiting_.end())
                    {
                        // remove fiber from waiting-list
                        waiting_.erase( wit );
                    }

                    status = cv_status::timeout;
                }

                // check if fiber was interrupted
                this_fiber::interruption_point();

                // lock external again before returning
                lt.lock();
            }
            else
            {
                // notification for main-fiber
                detail::main_fiber mf;
                n = & mf;

                // lock spinlock
                unique_lock< detail::spinlock > lk( splk_);

                // store this fiber in order to be notified later
                waiting_.push_back( n);

                // unlock external
                lt.unlock();

                // release spinlock
                lk.unlock();

                // loop until main-notifier gets notified
                while ( ! n->is_ready() )
                {
                    // check timepoint
                    if ( ! ( chrono::high_resolution_clock::now() < timeout_time) )
                    {
                        // timeout happend before notified
                        // lock spinlock
                        unique_lock< detail::spinlock > lk( splk_);
                        std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
                        if (wit != waiting_.end())
                        {
                            // remove fiber from waiting-list
                            waiting_.erase(wit);
                        }

                        status = cv_status::timeout;
                        break;
                    }
                    // run scheduler
                    fm_run();
                }

                // lock external again before returning
                lt.lock();
            }
        }
        catch (...)
        {
            unique_lock< detail::spinlock > lk( splk_);
            std::deque< detail::fiber_base * >::iterator wit = std::find( waiting_.begin(), waiting_.end(), n);
            if (wit != waiting_.end())
            {
                // remove fiber from waiting-list
                waiting_.erase( wit );
            }
            throw;
        }

        return status;
    }
Esempio n. 13
0
    cv_status wait_until( LockType & lt, clock_type::time_point const& timeout_time)
    {
        cv_status status = cv_status::no_timeout;

        detail::notify::ptr_t n( detail::scheduler::instance()->active() );
        try
        {
            if ( n)
            {
                // store this fiber in order to be notified later
                waiting_.push_back( n);
                lt.unlock();

                // suspend fiber
                if ( ! detail::scheduler::instance()->wait_until( timeout_time) )
                {
                    // remove fiber from waiting-list
                    waiting_.erase(
                        std::find( waiting_.begin(), waiting_.end(), n) );
                
                    status = cv_status::timeout;
                }

                // check if fiber was interrupted
                this_fiber::interruption_point();
            }
            else
            {
                // notifier for main-fiber
                detail::main_notifier mn;
                n = detail::main_notifier::make_pointer( mn);

                // store this fiber in order to be notified later
                waiting_.push_back( n);

                lt.unlock();
                while ( ! n->is_ready() )
                {
                    if ( ! ( clock_type::now() < timeout_time) )
                    {
                        // remove fiber from waiting-list
                        waiting_.erase(
                            std::find( waiting_.begin(), waiting_.end(), n) );

                        status = cv_status::timeout;

                        break;
                    }
                    // run scheduler
                    detail::scheduler::instance()->run();
                }
            }
        }
        catch (...)
        {
            // remove fiber from waiting-list
            waiting_.erase(
                std::find( waiting_.begin(), waiting_.end(), n) );
            throw;
        }

        // lock external again before returning
        lt.lock();

        return status;
    }