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

📄 mutex.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
    IF_PROTOCOL_CEILING        owner->clear_priority_ceiling();        #endif        locked      = false;    owner       = NULL;        CYG_ASSERTCLASS( this, "Bad this pointer");            // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Release all waiting threads.void Cyg_Mutex::release(){    CYG_REPORT_FUNCTION();    // Prevent preemption    Cyg_Scheduler::lock();    CYG_INSTRUMENT_MUTEX(RELEASE, this, 0);    CYG_ASSERTCLASS( this, "Bad this pointer");            while( !queue.empty() )    {        // The queue is non-empty, so grab each        // thread from it and release it.        Cyg_Thread *thread = queue.dequeue();        CYG_ASSERTCLASS( thread, "Bad thread pointer");        thread->release();        CYG_INSTRUMENT_MUTEX(RELEASED, this, thread);            }    CYG_ASSERTCLASS( this, "Bad this pointer");            // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Set ceiling priority for priority ceiling protocol#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILINGvoid Cyg_Mutex::set_ceiling( cyg_priority priority ){    CYG_REPORT_FUNCTION();//    CYG_ASSERT( priority >=  CYG_THREAD_MAX_PRIORITY, "Priority out of range");//    CYG_ASSERT( priority <=  CYG_THREAD_MIN_PRIORITY, "Priority out of range");        // Prevent preemption    Cyg_Scheduler::lock();    ceiling = priority;        // Unlock the scheduler    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();    }#endif// -------------------------------------------------------------------------// Set priority inversion protocol#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMICvoid Cyg_Mutex::set_protocol( cyg_protcol new_protocol ){    CYG_REPORT_FUNCTION();    // Prevent preemption    Cyg_Scheduler::lock();        protocol = new_protocol;        // Unlock the scheduler    Cyg_Scheduler::unlock();        CYG_REPORT_RETURN();    }#endif//==========================================================================// 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();}Cyg_Condition_Variable::Cyg_Condition_Variable(){    CYG_REPORT_FUNCTION();            mutex       = NULL;    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_ASSERTScyg_boolCyg_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 != NULL && !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.cyg_boolCyg_Condition_Variable::wait_inner( Cyg_Mutex *mx ){    CYG_REPORT_FUNCTION();    cyg_bool result = true;    Cyg_Thread *self = Cyg_Thread::self();    Cyg_Scheduler::lock();    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mx, "Corrupt mutex");    CYG_ASSERTCLASS( self, "Bad self thread");    CYG_INSTRUMENT_CONDVAR(WAIT, this, 0);        mx->unlock();    self->set_sleep_reason( Cyg_Thread::WAIT );            self->sleep();            queue.enqueue( self );    // Avoid calling ASRs during the following unlock.    self->set_asr_inhibit();        // Unlock the scheduler and switch threads    Cyg_Scheduler::unlock_reschedule();    // Allow ASRs again    self->clear_asr_inhibit();                CYG_INSTRUMENT_CONDVAR(WOKE, this, self->get_wake_reason());    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mx, "Corrupt mutex");    switch( self->get_wake_reason() )    {    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.    // 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 ( !mx->lock() )        continue;    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mx, "Corrupt mutex");    CYG_ASSERT( mx->owner == self, "Not mutex owner");    CYG_REPORT_RETURN();    return result;}// -------------------------------------------------------------------------// Wake one threadvoidCyg_Condition_Variable::signal(void){    CYG_REPORT_FUNCTION();            CYG_ASSERTCLASS( this, "Bad this pointer");    // 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");    // 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");    // 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");        // 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_inner( Cyg_Mutex *mx, cyg_tick_count timeout ){    CYG_REPORT_FUNCTYPE("returning %d");    CYG_REPORT_FUNCARG1("timeout = %d", timeout);            CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mx, "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 );        mx->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 );    // Avoid calling ASRs during the following unlock.    self->set_asr_inhibit();            // Unlock the scheduler and switch threads    Cyg_Scheduler::unlock_reschedule();    // Allow ASRs again    self->clear_asr_inhibit();                    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mx, "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.    while ( !mx->lock() )        continue;        CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERTCLASS( mx, "Corrupt mutex");    CYG_REPORT_RETVAL(result);        return result;}#endif// -------------------------------------------------------------------------// EOF sync/mutex.cxx

⌨️ 快捷键说明

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