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

📄 mutex.cxx

📁 ecos为实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      sync/mutex.cxx////      Mutex and condition variable implementation////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus.  Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    nickg// Contributors: nickg, jlarmour// Date:         1999-02-17// Purpose:      Mutex implementation// Description:  This file contains the implementations of the mutex//               and condition variable classes.////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/kernel.h>#include <cyg/kernel/ktypes.h>         // base kernel types#include <cyg/infra/cyg_trac.h>        // tracing macros#include <cyg/infra/cyg_ass.h>         // assertion macros#include <cyg/kernel/instrmnt.h>       // instrumentation#include <cyg/kernel/mutex.hxx>        // our header#include <cyg/kernel/thread.inl>       // thread inlines#include <cyg/kernel/sched.inl>        // scheduler inlines#include <cyg/kernel/clock.inl>        // clock inlines// -------------------------------------------------------------------------// ConstructorCyg_Mutex::Cyg_Mutex(){    CYG_REPORT_FUNCTION();            locked      = false;    owner       = NULL;    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// DestructorCyg_Mutex::~Cyg_Mutex(){    CYG_REPORT_FUNCTION();            CYG_ASSERT( owner == NULL, "Deleting mutex with owner");    CYG_ASSERT( queue.empty(), "Deleting mutex with waiting threads");    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------#ifdef CYGDBG_USE_ASSERTSboolCyg_Mutex::check_this( cyg_assert_class_zeal zeal) const{//    CYG_REPORT_FUNCTION();            // check that we have a non-NULL pointer first    if( this == NULL ) return false;        switch( zeal )    {    case cyg_system_test:    case cyg_extreme:    case cyg_thorough:    case cyg_quick:    case cyg_trivial:        if(  locked && owner == NULL ) return false;        if( !locked && owner != NULL ) return false;            case cyg_none:    default:        break;    };    return true;}#endif// -------------------------------------------------------------------------// Lock and/or waitcyg_boolCyg_Mutex::lock(void){    CYG_REPORT_FUNCTYPE("returning %d");    cyg_bool result = true;    Cyg_Thread *self = Cyg_Thread::self();        // Prevent preemption    Cyg_Scheduler::lock();    CYG_ASSERTCLASS( this, "Bad this pointer");        CYG_INSTRUMENT_MUTEX(LOCK, this, 0);    // Loop while the mutex is locked, sleeping each time around    // the loop. This copes with the possibility of a higher priority    // thread grabbing the mutex between the wakeup in unlock() and    // this thread actually starting.        while( locked && result )    {        CYG_ASSERT( self != owner, "Locking mutex I already own");                self->set_sleep_reason( Cyg_Thread::WAIT );                self->sleep();                queue.enqueue( self );#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE        owner->inherit_priority(self);    #endif        CYG_INSTRUMENT_MUTEX(WAIT, this, 0);        CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1, "Called with non-zero scheduler lock");                // Unlock scheduler and allow other threads        // to run        Cyg_Scheduler::unlock();        Cyg_Scheduler::lock();        CYG_ASSERTCLASS( this, "Bad this pointer");        switch( self->get_wake_reason() )        {        case Cyg_Thread::DESTRUCT:        case Cyg_Thread::BREAK:            result = false;            break;                    case Cyg_Thread::EXIT:                        self->exit();            break;        default:            break;        }    }    if( result )    {        locked      = true;        owner       = self;#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE        self->count_mutex();#endif        CYG_INSTRUMENT_MUTEX(LOCKED, this, 0);    }        // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    CYG_ASSERTCLASS( this, "Bad this pointer");        CYG_REPORT_RETVAL(result);    return result;}// -------------------------------------------------------------------------// Try to lock and return successcyg_boolCyg_Mutex::trylock(void){    CYG_REPORT_FUNCTYPE("returning %d");            CYG_ASSERTCLASS( this, "Bad this pointer");        cyg_bool result = true;        // Prevent preemption    Cyg_Scheduler::lock();    // If the mutex is not locked, grab it    // for ourself. Otherwise return failure.    if( !locked )    {        Cyg_Thread *self = Cyg_Thread::self();                locked  = true;        owner   = self;#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE        self->count_mutex();#endif    }    else result = false;    CYG_INSTRUMENT_MUTEX(TRY, this, result);        // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();        CYG_REPORT_RETVAL(result);    return result;    }// -------------------------------------------------------------------------// unlockvoidCyg_Mutex::unlock(void){    CYG_REPORT_FUNCTION();            // Prevent preemption    Cyg_Scheduler::lock();    CYG_INSTRUMENT_MUTEX(UNLOCK, this, 0);    CYG_ASSERTCLASS( this, "Bad this pointer");    CYG_ASSERT( locked, "Unlock mutex that is not locked");    CYG_ASSERT( owner == Cyg_Thread::self(), "Unlock mutex I do not own");        #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE    owner->uncount_mutex();    owner->disinherit_priority();    #endif        locked      = false;    owner       = NULL;        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_MUTEX(WAKE, this, thread);            }    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");        

⌨️ 快捷键说明

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