Project

General

Profile

Bug #1846 ยป exmutex.c.patch

eocallaghan, 09/19/2010 04:25 AM

View differences:

sys/contrib/dev/acpica-unix/executer/exmutex.c
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* All rights reserved.
*
* 2. License
......
(ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
/*
* Migrate the previous sync level associated with this mutex to the
* previous mutex on the list so that it may be preserved. This handles
* the case where several mutexes have been acquired at the same level,
* but are not released in opposite order.
* Migrate the previous sync level associated with this mutex to
* the previous mutex on the list so that it may be preserved.
* This handles the case where several mutexes have been acquired
* at the same level, but are not released in opposite order.
*/
(ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
ObjDesc->Mutex.OriginalSyncLevel;
......
*
* FUNCTION: AcpiExLinkMutex
*
* PARAMETERS: ObjDesc - The mutex to be linked
* Thread - Current executing thread object
* PARAMETERS: ObjDesc - The mutex to be linked
* Thread - Current executing thread object
*
* RETURN: None
*
......
*
* FUNCTION: AcpiExAcquireMutexObject
*
* PARAMETERS: TimeDesc - Timeout in milliseconds
* PARAMETERS: Timeout - Timeout in milliseconds
* ObjDesc - Mutex object
* Thread - Current thread state
* ThreadId - Current thread state
*
* RETURN: Status
*
......
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Must have a valid thread ID */
/* Must have a valid thread state struct */
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info",
ACPI_ERROR ((AE_INFO,
"Cannot acquire Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
......
if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
{
ACPI_ERROR ((AE_INFO,
"Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)",
"Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
WalkState->Thread->CurrentSyncLevel));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
......
{
ACPI_STATUS Status = AE_OK;
UINT8 PreviousSyncLevel;
ACPI_THREAD_STATE *OwnerThread;
ACPI_FUNCTION_TRACE (ExReleaseMutex);
......
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
OwnerThread = ObjDesc->Mutex.OwnerThread;
/* The mutex must have been previously acquired in order to release it */
if (!ObjDesc->Mutex.OwnerThread)
if (!OwnerThread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",
ACPI_ERROR ((AE_INFO,
"Cannot release Mutex [%4.4s], not acquired",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
}
/* 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 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) &&
if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
(ObjDesc != AcpiGbl_GlobalLockMutex))
{
ACPI_ERROR ((AE_INFO,
"Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
ACPI_CAST_PTR (void, WalkState->Thread->ThreadId),
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
ACPI_CAST_PTR (void, ObjDesc->Mutex.OwnerThread->ThreadId)));
ACPI_CAST_PTR (void, 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 equal to the current sync level. In
* other words, the current level means that at least one mutex at that
......
* different level can only mean that the mutex ordering rule is being
* violated. This behavior is clarified in ACPI 4.0 specification.
*/
if (ObjDesc->Mutex.SyncLevel != WalkState->Thread->CurrentSyncLevel)
if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
{
ACPI_ERROR ((AE_INFO,
"Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
"Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
AcpiUtGetNodeName (ObjDesc->Mutex.Node),
ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
......
* acquired, but are not released in reverse order.
*/
PreviousSyncLevel =
WalkState->Thread->AcquiredMutexList->Mutex.OriginalSyncLevel;
OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
Status = AcpiExReleaseMutexObject (ObjDesc);
if (ACPI_FAILURE (Status))
......
{
/* Restore the previous SyncLevel */
WalkState->Thread->CurrentSyncLevel = PreviousSyncLevel;
OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
}
return_ACPI_STATUS (Status);
}
......
*
* FUNCTION: AcpiExReleaseAllMutexes
*
* PARAMETERS: Thread - Current executing thread object
* PARAMETERS: Thread - Current executing thread object
*
* RETURN: Status
*
......
Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
}
}
    (1-1/1)