ACPI_STATUS AcpiExAcquireMutexObject ( UINT16 Timeout, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_THREAD_ID ThreadId) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc); if (!ObjDesc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Support for multiple acquires by the owning thread */ if (ObjDesc->Mutex.ThreadId == ThreadId) { /* * The mutex is already owned by this thread, just increment the * acquisition depth */ ObjDesc->Mutex.AcquisitionDepth++; return_ACPI_STATUS (AE_OK); } /* Acquire the mutex, wait if necessary. Special case for Global Lock */ if (ObjDesc == AcpiGbl_GlobalLockMutex) { Status = AcpiEvAcquireGlobalLock (Timeout); } else { Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex, Timeout); } if (ACPI_FAILURE (Status)) { /* Includes failure from a timeout on TimeDesc */ return_ACPI_STATUS (Status); } /* Acquired the mutex: update mutex object */ ObjDesc->Mutex.ThreadId = ThreadId; ObjDesc->Mutex.AcquisitionDepth = 1; ObjDesc->Mutex.OriginalSyncLevel = 0; ObjDesc->Mutex.OwnerThread = NULL; /* Used only for AML Acquire() */ return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiExAcquireMutex ( 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); } /* Sanity check: we 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 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); } /* Support for multiple acquires by the owning thread */ if (ObjDesc->Mutex.OwnerThread) { if (ObjDesc->Mutex.OwnerThread->ThreadId == WalkState->Thread->ThreadId) { /* * The mutex is already owned by this thread, just increment the * acquisition depth */ ObjDesc->Mutex.AcquisitionDepth++; return_ACPI_STATUS (AE_OK); } } /* Acquire the mutex, wait if necessary. Special case for Global Lock */ if (ObjDesc->Mutex.OsMutex == AcpiGbl_GlobalLockMutex) { Status = AcpiEvAcquireGlobalLock ((UINT16) TimeDesc->Integer.Value); } else { Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex, (UINT16) TimeDesc->Integer.Value); } if (ACPI_FAILURE (Status)) { /* Includes failure from a timeout on TimeDesc */ return_ACPI_STATUS (Status); } /* Have the mutex: update mutex and walk info and save the SyncLevel */ ObjDesc->Mutex.OwnerThread = WalkState->Thread; ObjDesc->Mutex.AcquisitionDepth = 1; 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 (AE_OK); }