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

📄 exmutex.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************* * * FUNCTION:    AcpiExAcquireMutex * * PARAMETERS:  TimeDesc            - Timeout integer *              ObjDesc             - Mutex object *              WalkState           - Current method execution state * * RETURN:      Status * * DESCRIPTION: Acquire an AML mutex * ******************************************************************************/ACPI_STATUSAcpiExAcquireMutex (    ACPI_OPERAND_OBJECT     *TimeDesc,    ACPI_OPERAND_OBJECT     *ObjDesc,    ACPI_WALK_STATE         *WalkState){    ACPI_STATUS             Status;    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);    if (!ObjDesc)    {        return_ACPI_STATUS (AE_BAD_PARAMETER);    }    /* Must have a valid thread ID */    if (!WalkState->Thread)    {        ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info",            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));        return_ACPI_STATUS (AE_AML_INTERNAL);    }    /*     * Current sync level must be less than or equal to the sync level of the     * mutex. This mechanism provides some deadlock prevention     */    if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)    {        ACPI_ERROR ((AE_INFO,            "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)",            AcpiUtGetNodeName (ObjDesc->Mutex.Node),            WalkState->Thread->CurrentSyncLevel));        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);    }    Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,                ObjDesc, WalkState->Thread->ThreadId);    if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)    {        /* Save Thread object, original/current sync levels */        ObjDesc->Mutex.OwnerThread = WalkState->Thread;        ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel;        WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel;        /* Link the mutex to the current thread for force-unlock at method exit */        AcpiExLinkMutex (ObjDesc, WalkState->Thread);    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiExReleaseMutexObject * * PARAMETERS:  ObjDesc             - The object descriptor for this op * * RETURN:      Status * * DESCRIPTION: Release a previously acquired Mutex, low level interface. *              Provides a common path that supports multiple releases (after *              previous multiple acquires) by the same thread. * * MUTEX:       Interpreter must be locked * * NOTE: This interface is called from three places: * 1) From AcpiExReleaseMutex, via an AML Acquire() operator * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the *    global lock * 3) From the external interface, AcpiReleaseGlobalLock * ******************************************************************************/ACPI_STATUSAcpiExReleaseMutexObject (    ACPI_OPERAND_OBJECT     *ObjDesc){    ACPI_STATUS             Status = AE_OK;    ACPI_FUNCTION_TRACE (ExReleaseMutexObject);    if (ObjDesc->Mutex.AcquisitionDepth == 0)    {        return (AE_NOT_ACQUIRED);    }    /* Match multiple Acquires with multiple Releases */    ObjDesc->Mutex.AcquisitionDepth--;    if (ObjDesc->Mutex.AcquisitionDepth != 0)    {        /* Just decrement the depth and return */        return_ACPI_STATUS (AE_OK);    }    if (ObjDesc->Mutex.OwnerThread)    {        /* Unlink the mutex from the owner's list */        AcpiExUnlinkMutex (ObjDesc);        ObjDesc->Mutex.OwnerThread = NULL;    }    /* Release the mutex, special case for Global Lock */    if (ObjDesc == AcpiGbl_GlobalLockMutex)    {        Status = AcpiEvReleaseGlobalLock ();    }    else    {        AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);    }    /* Clear mutex info */    ObjDesc->Mutex.ThreadId = 0;    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiExReleaseMutex * * PARAMETERS:  ObjDesc             - The object descriptor for this op *              WalkState           - Current method execution state * * RETURN:      Status * * DESCRIPTION: Release a previously acquired Mutex. * ******************************************************************************/ACPI_STATUSAcpiExReleaseMutex (    ACPI_OPERAND_OBJECT     *ObjDesc,    ACPI_WALK_STATE         *WalkState){    ACPI_STATUS             Status = AE_OK;    ACPI_FUNCTION_TRACE (ExReleaseMutex);    if (!ObjDesc)    {        return_ACPI_STATUS (AE_BAD_PARAMETER);    }    /* The mutex must have been previously acquired in order to release it */    if (!ObjDesc->Mutex.OwnerThread)    {        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));        return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);    }    /*     * The Mutex is owned, but this thread must be the owner.     * Special case for Global Lock, any thread can release     */    if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&        (ObjDesc != AcpiGbl_GlobalLockMutex))    {        ACPI_ERROR ((AE_INFO,            "Thread %X cannot release Mutex [%4.4s] acquired by thread %X",            WalkState->Thread->ThreadId,            AcpiUtGetNodeName (ObjDesc->Mutex.Node),            ObjDesc->Mutex.OwnerThread->ThreadId));        return_ACPI_STATUS (AE_AML_NOT_OWNER);    }    /* Must have a valid thread ID */    if (!WalkState->Thread)    {        ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));        return_ACPI_STATUS (AE_AML_INTERNAL);    }    /*     * The sync level of the mutex must be less than or equal to the current     * sync level     */    if (ObjDesc->Mutex.SyncLevel > WalkState->Thread->CurrentSyncLevel)    {        ACPI_ERROR ((AE_INFO,            "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",            AcpiUtGetNodeName (ObjDesc->Mutex.Node),            ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);    }    Status = AcpiExReleaseMutexObject (ObjDesc);    if (ObjDesc->Mutex.AcquisitionDepth == 0)    {        /* Restore the original SyncLevel */        WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiExReleaseAllMutexes * * PARAMETERS:  Thread          - Current executing thread object * * RETURN:      Status * * DESCRIPTION: Release all mutexes held by this thread * * NOTE: This function is called as the thread is exiting the interpreter. * Mutexes are not released when an individual control method is exited, but * only when the parent thread actually exits the interpreter. This allows one * method to acquire a mutex, and a different method to release it, as long as * this is performed underneath a single parent control method. * ******************************************************************************/voidAcpiExReleaseAllMutexes (    ACPI_THREAD_STATE       *Thread){    ACPI_OPERAND_OBJECT     *Next = Thread->AcquiredMutexList;    ACPI_OPERAND_OBJECT     *ObjDesc;    ACPI_FUNCTION_ENTRY ();    /* Traverse the list of owned mutexes, releasing each one */    while (Next)    {        ObjDesc = Next;        Next = ObjDesc->Mutex.Next;        ObjDesc->Mutex.Prev = NULL;        ObjDesc->Mutex.Next = NULL;        ObjDesc->Mutex.AcquisitionDepth = 0;        /* Release the mutex, special case for Global Lock */        if (ObjDesc == AcpiGbl_GlobalLockMutex)        {            /* Ignore errors */            (void) AcpiEvReleaseGlobalLock ();        }        else        {            AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);        }        /* Mark mutex unowned */        ObjDesc->Mutex.OwnerThread = NULL;        ObjDesc->Mutex.ThreadId = 0;        /* Update Thread SyncLevel (Last mutex is the important one) */        Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;    }}

⌨️ 快捷键说明

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