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

📄 mutex.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      sync/mutex.cxx////      Mutex and condition variable implementation////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####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// -------------------------------------------------------------------------// Mutex protocol test macros.// If the dynamic protocol option is enabled, then these generate appropriate// tests on the protocol field. If there is no dynamic choice then they simply// result in empty statements.#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC#define IF_PROTOCOL_INHERIT if( protocol == INHERIT )#define IF_PROTOCOL_CEILING if( protocol == CEILING )#define IF_PROTOCOL_ACTIVE  if( protocol != NONE )#else#define IF_PROTOCOL_INHERIT#define IF_PROTOCOL_CEILING#define IF_PROTOCOL_ACTIVE#endif// -------------------------------------------------------------------------// ConstructorCyg_Mutex::Cyg_Mutex(){    CYG_REPORT_FUNCTION();            locked      = false;    owner       = NULL;#if defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT) && \    defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC)#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_INHERIT    protocol    = INHERIT;#endif    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_CEILING    protocol    = CEILING;    ceiling     = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY;#endif    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_NONE    protocol    = NONE;#endif#else // not (DYNAMIC and DEFAULT defined)#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY    // if there is a default priority ceiling defined, use that to initialize    // the ceiling.    ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY;    #else    // Otherwise set it to zero.    ceiling = 0;    #endif    #endif#endif // DYNAMIC and DEFAULT defined        CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Construct with defined protocol#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMICCyg_Mutex::Cyg_Mutex( cyg_protcol protocol_arg ){    CYG_REPORT_FUNCTION();            locked      = false;    owner       = NULL;    protocol    = protocol_arg;#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY    // if there is a default priority ceiling defined, use that to initialize    // the ceiling.    ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY;    #else    // Otherwise set it to zero.    ceiling = 0;    #endif    #endif        CYG_REPORT_RETURN();}#endif// -------------------------------------------------------------------------// 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_ASSERTScyg_boolCyg_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.    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL    IF_PROTOCOL_ACTIVE	self->count_mutex();#endif#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING        IF_PROTOCOL_CEILING        self->set_priority_ceiling(ceiling);#endif                           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_INVERSION_PROTOCOL_INHERIT        IF_PROTOCOL_INHERIT            owner->inherit_priority(self);#endif        CYG_INSTRUMENT_MUTEX(WAIT, this, 0);        // Allow other threads to run        Cyg_Scheduler::reschedule();                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;        CYG_INSTRUMENT_MUTEX(LOCKED, this, 0);    }    else    {#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL       IF_PROTOCOL_ACTIVE           self->uncount_mutex();#endif    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT        IF_PROTOCOL_INHERIT            self->disinherit_priority();#endif#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING        IF_PROTOCOL_CEILING            self->clear_priority_ceiling();#endif    }        // 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_INVERSION_PROTOCOL       IF_PROTOCOL_ACTIVE            self->count_mutex();#endif#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING        IF_PROTOCOL_CEILING            self->set_priority_ceiling(ceiling);        #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");            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");#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT        // Give the owner-to-be a chance to inherit from the remaining        // queue or the relinquishing thread:        IF_PROTOCOL_INHERIT            thread->relay_priority(owner, &queue);#endif        thread->set_wake_reason( Cyg_Thread::DONE );                thread->wake();        CYG_INSTRUMENT_MUTEX(WAKE, this, thread);            }#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL    IF_PROTOCOL_ACTIVE	owner->uncount_mutex();#endif    #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT    IF_PROTOCOL_INHERIT        owner->disinherit_priority();    #endif#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING

⌨️ 快捷键说明

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