⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutex.cxx

📁 ecos为实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
    // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}//==========================================================================// Condition variablesCyg_Condition_Variable::Cyg_Condition_Variable(    Cyg_Mutex   &mx                // linked mutex    ){    CYG_REPORT_FUNCTION();            mutex       = &mx;    CYG_ASSERTCLASS( mutex, "Invalid mutex argument");    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// DestructorCyg_Condition_Variable::~Cyg_Condition_Variable(){    CYG_REPORT_FUNCTION();            CYG_ASSERT( queue.empty(), "Deleting condvar with waiting threads");    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------#ifdef CYGDBG_USE_ASSERTSboolCyg_Condition_Variable::check_this( cyg_assert_class_zeal zeal) const{    bool result = true;    CYG_REPORT_FUNCTYPE("returning %d");    CYG_REPORT_FUNCARG1("zeal = %d", zeal);            // check that we have a non-NULL pointer first    if( this == NULL )        result = false;    else {                switch( zeal )        {        case cyg_system_test:        case cyg_extreme:        case cyg_thorough:            if( !mutex->check_this(zeal) )                result = false;        case cyg_quick:        case cyg_trivial:        case cyg_none:        default:            break;        }    }    CYG_REPORT_RETVAL(result);    return result;}#endif// -------------------------------------------------------------------------// Wait for condition to be true    // Note: if this function is entered with the scheduler locked (e.g. to// suspend DSR processing) then there is no need to take the lock.  Also// in this case, exit with the scheduler locked, which allows this function// to be used in a totally thread-safe manner.voidCyg_Condition_Variable::wait(void){    CYG_REPORT_FUNCTION();            Cyg_Thread *self = Cyg_Thread::self();    cyg_int32 current_lock = Cyg_Scheduler::get_sched_lock();    if (current_lock == 0)         // Prevent preemption        Cyg_Scheduler::lock();    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    CYG_ASSERTCLASS( self, "Bad self thread");    CYG_INSTRUMENT_CONDVAR(WAIT, this, 0);        mutex->unlock();    self->set_sleep_reason( Cyg_Thread::WAIT );            self->sleep();            queue.enqueue( self );    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1, "Called with non-zero scheduler lock");        // Unlock the scheduler and switch threads    Cyg_Scheduler::unlock();    CYG_INSTRUMENT_CONDVAR(WOKE, this, self->get_wake_reason());        CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    switch( self->get_wake_reason() )    {    case Cyg_Thread::EXIT:                    self->exit();        break;    default:        break;    }    // When we awake, we must re-acquire the mutex.  Note that while    // it is essential to release the mutex and queue on the CV    // atomically relative to other threads, to avoid races, it is not    // necessary for us to re-acquire the mutex in the same atomic    // action. Hence we can do it after unlocking the scheduler.    // We need to loop here in case the thread is released while waiting    // for the mutex. It is essential that we exit this function with the    // mutex claimed.        while ( !mutex->lock() )        continue;    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    CYG_ASSERT( mutex->owner == self, "Not mutex owner");    CYG_REPORT_RETURN();    if (current_lock)        // Reacquire the DSR pseudo lock        Cyg_Scheduler::lock();}// -------------------------------------------------------------------------// Wake one threadvoidCyg_Condition_Variable::signal(void){    CYG_REPORT_FUNCTION();            CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    // Prevent preemption    Cyg_Scheduler::lock();    CYG_INSTRUMENT_CONDVAR(SIGNAL, this, 0);        if( !queue.empty() )    {        // The queue is non-empty, so grab the next        // thread from it and wake it up.        Cyg_Thread *thread = queue.dequeue();        CYG_ASSERTCLASS( thread, "Bad thread pointer");                thread->set_wake_reason( Cyg_Thread::DONE );                thread->wake();        CYG_INSTRUMENT_CONDVAR(WAKE, this, thread);            }        CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Set cond true, wake all threadsvoidCyg_Condition_Variable::broadcast(void){    CYG_REPORT_FUNCTION();            CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    // Prevent preemption    Cyg_Scheduler::lock();    CYG_INSTRUMENT_CONDVAR(BROADCAST, this, 0);        // Grab all the threads from the queue and let them    // go.        while( !queue.empty() )    {        Cyg_Thread *thread = queue.dequeue();        CYG_ASSERTCLASS( thread, "Bad thread pointer");                thread->set_wake_reason( Cyg_Thread::DONE );                thread->wake();        CYG_INSTRUMENT_CONDVAR(WAKE, this, thread);            }        CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");        // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();        CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Optional timed wait on a CV#if defined(CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT)cyg_boolCyg_Condition_Variable::wait( cyg_tick_count timeout ){    CYG_REPORT_FUNCTYPE("returning %d");    CYG_REPORT_FUNCARG1("timeout = %d", timeout);            CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    cyg_bool result = true;        Cyg_Thread *self = Cyg_Thread::self();    CYG_ASSERTCLASS( self, "Bad self thread");        // Prevent preemption    Cyg_Scheduler::lock();    CYG_INSTRUMENT_CONDVAR(TIMED_WAIT, this, 0 );        mutex->unlock();    // The ordering of sleep() and set_timer() here are    // important. If the timeout is in the past, the thread    // will be woken up immediately and will not sleep.        self->sleep();            // Set the timer and sleep reason    self->set_timer( timeout, Cyg_Thread::TIMEOUT );    // Only enqueue if the timeout has not already fired.    if( self->get_wake_reason() == Cyg_Thread::NONE )        queue.enqueue( self );    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1, "Called with non-zero scheduler lock");        // Unlock the scheduler and switch threads    Cyg_Scheduler::unlock();    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");        self->clear_timer();    CYG_INSTRUMENT_CONDVAR(WOKE, this, self->get_wake_reason());        switch( self->get_wake_reason() )    {    case Cyg_Thread::TIMEOUT:                case Cyg_Thread::DESTRUCT:          // which, the cv or the mutex?    case Cyg_Thread::BREAK:        result = false;        break;                case Cyg_Thread::EXIT:                    self->exit();        break;    default:        break;    }        // When we awake, we must re-acquire the mutex.  Note that while    // it is essential to release the mutex and queue on the CV    // atomically relative to other threads, to avoid races, it is not    // necessary for us to re-acquire the mutex in the same atomic    // action. Hence we can do it after unlocking the scheduler.    // FIXME: what if we woke up above due to TIMEOUT/DESTRUCT/BREAK?    // In that situation is it correct to not lock the mutex?    if (false != result)        result = mutex->lock();    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mutex, "Corrupt mutex");    CYG_REPORT_RETVAL(result);        return result;}#endif// -------------------------------------------------------------------------// EOF sync/mutex.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -