mirror of
https://github.com/acpica/acpica/
synced 2025-01-13 12:59:18 +03:00
Update for mutiple global lock acquisitions by same thread.
Allows AcpiAcquireGlobalLock external interface to be called multiple times by the same thread. Allows use of AML fields that require the global lock while the running AML is already holding the global lock.
This commit is contained in:
parent
95572d1ea5
commit
7c7d01c61e
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: dsmethod - Parser/Interpreter interface - control method parsing
|
||||
* $Revision: 1.134 $
|
||||
* $Revision: 1.135 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -329,8 +329,8 @@ AcpiDsBeginMethodExecution (
|
||||
* recursive call.
|
||||
*/
|
||||
if (!WalkState ||
|
||||
!ObjDesc->Method.Mutex->Mutex.OwnerThread ||
|
||||
(WalkState->Thread != ObjDesc->Method.Mutex->Mutex.OwnerThread))
|
||||
!ObjDesc->Method.Mutex->Mutex.ThreadId ||
|
||||
(WalkState->Thread->ThreadId != ObjDesc->Method.Mutex->Mutex.ThreadId))
|
||||
{
|
||||
/*
|
||||
* Acquire the method mutex. This releases the interpreter if we
|
||||
@ -350,7 +350,7 @@ AcpiDsBeginMethodExecution (
|
||||
ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
|
||||
WalkState->Thread->CurrentSyncLevel;
|
||||
|
||||
ObjDesc->Method.Mutex->Mutex.OwnerThread = WalkState->Thread;
|
||||
ObjDesc->Method.Mutex->Mutex.ThreadId = WalkState->Thread->ThreadId;
|
||||
WalkState->Thread->CurrentSyncLevel = ObjDesc->Method.SyncLevel;
|
||||
}
|
||||
else
|
||||
@ -687,7 +687,7 @@ AcpiDsTerminateControlMethod (
|
||||
MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel;
|
||||
|
||||
AcpiOsReleaseMutex (MethodDesc->Method.Mutex->Mutex.OsMutex);
|
||||
MethodDesc->Method.Mutex->Mutex.OwnerThread = NULL;
|
||||
MethodDesc->Method.Mutex->Mutex.ThreadId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: evmisc - Miscellaneous event manager support functions
|
||||
* $Revision: 1.101 $
|
||||
* $Revision: 1.102 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -559,7 +559,8 @@ AcpiEvAcquireGlobalLock (
|
||||
* Only one thread can acquire the GL at a time, the GlobalLockMutex
|
||||
* enforces this. This interface releases the interpreter if we must wait.
|
||||
*/
|
||||
Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex, Timeout);
|
||||
Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
|
||||
Timeout);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return_ACPI_STATUS (Status);
|
||||
@ -660,7 +661,7 @@ AcpiEvReleaseGlobalLock (
|
||||
|
||||
/* Release the local GL mutex */
|
||||
|
||||
AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex);
|
||||
AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: evxface - External interfaces for ACPI events
|
||||
* $Revision: 1.163 $
|
||||
* $Revision: 1.164 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -891,6 +891,12 @@ ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
|
||||
*
|
||||
* DESCRIPTION: Acquire the ACPI Global Lock
|
||||
*
|
||||
* Note: Allows callers with the same thread ID to acquire the global lock
|
||||
* multiple times. In other words, externally, the behavior of the global lock
|
||||
* is identical to an AML mutex. On the first acquire, a new handle is
|
||||
* returned. On any subsequent calls to acquire by the same thread, the same
|
||||
* handle is returned.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
ACPI_STATUS
|
||||
@ -909,15 +915,27 @@ AcpiAcquireGlobalLock (
|
||||
/* Must lock interpreter to prevent race conditions */
|
||||
|
||||
AcpiExEnterInterpreter ();
|
||||
Status = AcpiEvAcquireGlobalLock (Timeout);
|
||||
AcpiExExitInterpreter ();
|
||||
|
||||
Status = AcpiExAcquireMutexObject (Timeout,
|
||||
AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
|
||||
|
||||
if (ACPI_SUCCESS (Status))
|
||||
{
|
||||
AcpiGbl_GlobalLockHandle++;
|
||||
/*
|
||||
* If this was the first acquisition of the Global Lock by this thread,
|
||||
* create a new handle. Otherwise, return the existing handle.
|
||||
*/
|
||||
if (AcpiGbl_GlobalLockMutex->Mutex.AcquisitionDepth == 1)
|
||||
{
|
||||
AcpiGbl_GlobalLockHandle++;
|
||||
}
|
||||
|
||||
/* Return the global lock handle */
|
||||
|
||||
*Handle = AcpiGbl_GlobalLockHandle;
|
||||
}
|
||||
|
||||
AcpiExExitInterpreter ();
|
||||
return (Status);
|
||||
}
|
||||
|
||||
@ -948,7 +966,7 @@ AcpiReleaseGlobalLock (
|
||||
return (AE_NOT_ACQUIRED);
|
||||
}
|
||||
|
||||
Status = AcpiEvReleaseGlobalLock ();
|
||||
Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: exfield - ACPI AML (p-code) execution - field manipulation
|
||||
* $Revision: 1.129 $
|
||||
* $Revision: 1.130 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -151,7 +151,6 @@ AcpiExReadDataFromField (
|
||||
ACPI_OPERAND_OBJECT *BufferDesc;
|
||||
ACPI_SIZE Length;
|
||||
void *Buffer;
|
||||
BOOLEAN Locked;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR (ExReadDataFromField, ObjDesc);
|
||||
@ -198,7 +197,7 @@ AcpiExReadDataFromField (
|
||||
|
||||
/* Lock entire transaction if requested */
|
||||
|
||||
Locked = AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
|
||||
/*
|
||||
* Perform the read.
|
||||
@ -207,7 +206,7 @@ AcpiExReadDataFromField (
|
||||
Status = AcpiExAccessRegion (ObjDesc, 0,
|
||||
ACPI_CAST_PTR (ACPI_INTEGER, BufferDesc->Buffer.Pointer),
|
||||
ACPI_READ | (ObjDesc->Field.Attribute << 16));
|
||||
AcpiExReleaseGlobalLock (Locked);
|
||||
AcpiExReleaseGlobalLock ();
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
@ -259,12 +258,12 @@ AcpiExReadDataFromField (
|
||||
|
||||
/* Lock entire transaction if requested */
|
||||
|
||||
Locked = AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
|
||||
/* Read from the field */
|
||||
|
||||
Status = AcpiExExtractFromField (ObjDesc, Buffer, (UINT32) Length);
|
||||
AcpiExReleaseGlobalLock (Locked);
|
||||
AcpiExReleaseGlobalLock ();
|
||||
|
||||
|
||||
Exit:
|
||||
@ -306,7 +305,6 @@ AcpiExWriteDataToField (
|
||||
UINT32 RequiredLength;
|
||||
void *Buffer;
|
||||
void *NewBuffer;
|
||||
BOOLEAN Locked;
|
||||
ACPI_OPERAND_OBJECT *BufferDesc;
|
||||
|
||||
|
||||
@ -373,7 +371,7 @@ AcpiExWriteDataToField (
|
||||
|
||||
/* Lock entire transaction if requested */
|
||||
|
||||
Locked = AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
|
||||
/*
|
||||
* Perform the write (returns status and perhaps data in the
|
||||
@ -383,7 +381,7 @@ AcpiExWriteDataToField (
|
||||
Status = AcpiExAccessRegion (ObjDesc, 0,
|
||||
(ACPI_INTEGER *) Buffer,
|
||||
ACPI_WRITE | (ObjDesc->Field.Attribute << 16));
|
||||
AcpiExReleaseGlobalLock (Locked);
|
||||
AcpiExReleaseGlobalLock ();
|
||||
|
||||
*ResultDesc = BufferDesc;
|
||||
return_ACPI_STATUS (Status);
|
||||
@ -457,12 +455,12 @@ AcpiExWriteDataToField (
|
||||
|
||||
/* Lock entire transaction if requested */
|
||||
|
||||
Locked = AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
|
||||
|
||||
/* Write to the field */
|
||||
|
||||
Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length);
|
||||
AcpiExReleaseGlobalLock (Locked);
|
||||
AcpiExReleaseGlobalLock ();
|
||||
|
||||
/* Free temporary buffer if we used one */
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: exmutex - ASL Mutex Acquire/Release functions
|
||||
* $Revision: 1.36 $
|
||||
* $Revision: 1.37 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -215,6 +215,75 @@ AcpiExLinkMutex (
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiExAcquireMutexObject
|
||||
*
|
||||
* PARAMETERS: TimeDesc - Timeout in milliseconds
|
||||
* ObjDesc - Mutex object
|
||||
* Thread - Current thread state
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Acquire an AML mutex, low-level interface
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
ACPI_STATUS
|
||||
AcpiExAcquireMutexObject (
|
||||
UINT16 Timeout,
|
||||
ACPI_OPERAND_OBJECT *ObjDesc,
|
||||
ACPI_THREAD_ID ThreadId)
|
||||
{
|
||||
ACPI_STATUS Status;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
|
||||
|
||||
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Have the mutex: update mutex and save the SyncLevel */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiExAcquireMutex
|
||||
@ -256,7 +325,7 @@ AcpiExAcquireMutex (
|
||||
}
|
||||
|
||||
/*
|
||||
* Current Sync must be less than or equal to the sync level of the
|
||||
* 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)
|
||||
@ -268,53 +337,76 @@ AcpiExAcquireMutex (
|
||||
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
|
||||
}
|
||||
|
||||
/* Support for multiple acquires by the owning thread */
|
||||
Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,
|
||||
ObjDesc, WalkState->Thread->ThreadId);
|
||||
if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
|
||||
{
|
||||
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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
ACPI_STATUS
|
||||
AcpiExReleaseMutexObject (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc)
|
||||
{
|
||||
ACPI_STATUS Status = AE_OK;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
/* Unlink the mutex from the owner's list */
|
||||
|
||||
AcpiExUnlinkMutex (ObjDesc);
|
||||
ObjDesc->Mutex.OwnerThread = NULL;
|
||||
}
|
||||
|
||||
/* Acquire the mutex, wait if necessary. Special case for Global Lock */
|
||||
/* Release the mutex, special case for Global Lock */
|
||||
|
||||
if (ObjDesc->Mutex.OsMutex == AcpiGbl_GlobalLockMutex)
|
||||
if (ObjDesc == AcpiGbl_GlobalLockMutex)
|
||||
{
|
||||
Status = AcpiEvAcquireGlobalLock ((UINT16) TimeDesc->Integer.Value);
|
||||
Status = AcpiEvReleaseGlobalLock ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex,
|
||||
(UINT16) TimeDesc->Integer.Value);
|
||||
AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
|
||||
}
|
||||
|
||||
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);
|
||||
ObjDesc->Mutex.ThreadId = 0;
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
|
||||
@ -356,21 +448,12 @@ AcpiExReleaseMutex (
|
||||
return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
|
||||
}
|
||||
|
||||
/* Sanity check: we 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) &&
|
||||
(ObjDesc->Mutex.OsMutex != AcpiGbl_GlobalLockMutex))
|
||||
(ObjDesc != AcpiGbl_GlobalLockMutex))
|
||||
{
|
||||
ACPI_ERROR ((AE_INFO,
|
||||
"Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
|
||||
@ -380,6 +463,15 @@ AcpiExReleaseMutex (
|
||||
return_ACPI_STATUS (AE_AML_NOT_OWNER);
|
||||
}
|
||||
|
||||
/* Sanity check: we 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
|
||||
@ -392,36 +484,11 @@ AcpiExReleaseMutex (
|
||||
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
|
||||
}
|
||||
|
||||
/* Match multiple Acquires with multiple Releases */
|
||||
Status = AcpiExReleaseMutexObject (ObjDesc);
|
||||
|
||||
ObjDesc->Mutex.AcquisitionDepth--;
|
||||
if (ObjDesc->Mutex.AcquisitionDepth != 0)
|
||||
{
|
||||
/* Just decrement the depth and return */
|
||||
/* Restore SyncLevel */
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
/* Unlink the mutex from the owner's list */
|
||||
|
||||
AcpiExUnlinkMutex (ObjDesc);
|
||||
|
||||
/* Release the mutex, special case for Global Lock */
|
||||
|
||||
if (ObjDesc->Mutex.OsMutex == AcpiGbl_GlobalLockMutex)
|
||||
{
|
||||
Status = AcpiEvReleaseGlobalLock ();
|
||||
}
|
||||
else
|
||||
{
|
||||
AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
|
||||
}
|
||||
|
||||
/* Update the mutex and restore SyncLevel */
|
||||
|
||||
ObjDesc->Mutex.OwnerThread = NULL;
|
||||
WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
|
||||
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
@ -468,7 +535,7 @@ AcpiExReleaseAllMutexes (
|
||||
|
||||
/* Release the mutex, special case for Global Lock */
|
||||
|
||||
if (ObjDesc->Mutex.OsMutex == AcpiGbl_GlobalLockMutex)
|
||||
if (ObjDesc == AcpiGbl_GlobalLockMutex)
|
||||
{
|
||||
/* Ignore errors */
|
||||
|
||||
@ -482,6 +549,7 @@ AcpiExReleaseAllMutexes (
|
||||
/* Mark mutex unowned */
|
||||
|
||||
ObjDesc->Mutex.OwnerThread = NULL;
|
||||
ObjDesc->Mutex.ThreadId = 0;
|
||||
|
||||
/* Update Thread SyncLevel (Last mutex is the important one) */
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: exutils - interpreter/scanner utilities
|
||||
* $Revision: 1.126 $
|
||||
* $Revision: 1.127 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -346,44 +346,42 @@ AcpiExTruncateFor32bitTable (
|
||||
* PARAMETERS: FieldFlags - Flags with Lock rule:
|
||||
* AlwaysLock or NeverLock
|
||||
*
|
||||
* RETURN: TRUE/FALSE indicating whether the lock was actually acquired
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Obtain the global lock and keep track of this fact via two
|
||||
* methods. A global variable keeps the state of the lock, and
|
||||
* the state is returned to the caller.
|
||||
* DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
|
||||
* flags specifiy that it is to be obtained before field access.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
void
|
||||
AcpiExAcquireGlobalLock (
|
||||
UINT32 FieldFlags)
|
||||
{
|
||||
BOOLEAN Locked = FALSE;
|
||||
ACPI_STATUS Status;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE (ExAcquireGlobalLock);
|
||||
|
||||
|
||||
/* Only attempt lock if the AlwaysLock bit is set */
|
||||
/* Only use the lock if the AlwaysLock bit is set */
|
||||
|
||||
if (FieldFlags & AML_FIELD_LOCK_RULE_MASK)
|
||||
if (!(FieldFlags & AML_FIELD_LOCK_RULE_MASK))
|
||||
{
|
||||
/* We should attempt to get the lock, wait forever */
|
||||
|
||||
Status = AcpiEvAcquireGlobalLock (ACPI_WAIT_FOREVER);
|
||||
if (ACPI_SUCCESS (Status))
|
||||
{
|
||||
Locked = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ACPI_EXCEPTION ((AE_INFO, Status,
|
||||
"Could not acquire Global Lock"));
|
||||
}
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
return_UINT8 (Locked);
|
||||
/* Attempt to get the global lock, wait forever */
|
||||
|
||||
Status = AcpiExAcquireMutexObject (ACPI_WAIT_FOREVER,
|
||||
AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
|
||||
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
ACPI_EXCEPTION ((AE_INFO, Status,
|
||||
"Could not acquire Global Lock"));
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
|
||||
@ -391,18 +389,17 @@ AcpiExAcquireGlobalLock (
|
||||
*
|
||||
* FUNCTION: AcpiExReleaseGlobalLock
|
||||
*
|
||||
* PARAMETERS: LockedByMe - Return value from corresponding call to
|
||||
* AcquireGlobalLock.
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Release the global lock if it is locked.
|
||||
* DESCRIPTION: Release the ACPI hardware Global Lock
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
AcpiExReleaseGlobalLock (
|
||||
BOOLEAN LockedByMe)
|
||||
void)
|
||||
{
|
||||
ACPI_STATUS Status;
|
||||
|
||||
@ -410,20 +407,15 @@ AcpiExReleaseGlobalLock (
|
||||
ACPI_FUNCTION_TRACE (ExReleaseGlobalLock);
|
||||
|
||||
|
||||
/* Only attempt unlock if the caller locked it */
|
||||
/* Release the global lock */
|
||||
|
||||
if (LockedByMe)
|
||||
Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
/* OK, now release the lock */
|
||||
/* Report the error, but there isn't much else we can do */
|
||||
|
||||
Status = AcpiEvReleaseGlobalLock ();
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
/* Report the error, but there isn't much else we can do */
|
||||
|
||||
ACPI_EXCEPTION ((AE_INFO, Status,
|
||||
"Could not release ACPI Global Lock"));
|
||||
}
|
||||
ACPI_EXCEPTION ((AE_INFO, Status,
|
||||
"Could not release Global Lock"));
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Module Name: nsaccess - Top-level functions for accessing ACPI namespace
|
||||
* $Revision: 1.205 $
|
||||
* $Revision: 1.206 $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -294,7 +294,7 @@ AcpiNsRootInitialize (
|
||||
|
||||
if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0)
|
||||
{
|
||||
AcpiGbl_GlobalLockMutex = ObjDesc->Mutex.OsMutex;
|
||||
AcpiGbl_GlobalLockMutex = ObjDesc;
|
||||
|
||||
/* Create additional counting semaphore for global lock */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Module Name: utdelete - object deletion and reference count utilities
|
||||
* $Revision: 1.122 $
|
||||
* $Revision: 1.123 $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -247,7 +247,7 @@ AcpiUtDeleteInternalObj (
|
||||
"***** Mutex %p, OS Mutex %p\n",
|
||||
Object, Object->Mutex.OsMutex));
|
||||
|
||||
if (Object->Mutex.OsMutex == AcpiGbl_GlobalLockMutex)
|
||||
if (Object == AcpiGbl_GlobalLockMutex)
|
||||
{
|
||||
/* Global Lock has extra semaphore */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acglobal.h - Declarations for global variables
|
||||
* $Revision: 1.192 $
|
||||
* $Revision: 1.193 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -251,10 +251,14 @@ ACPI_EXTERN UINT8 AcpiGbl_IntegerNybbleWidth;
|
||||
ACPI_EXTERN ACPI_MUTEX_INFO AcpiGbl_MutexInfo[ACPI_NUM_MUTEX];
|
||||
|
||||
/*
|
||||
* Global lock semaphore works in conjunction with the actual HW global lock
|
||||
* Global lock mutex is an actual AML mutex object
|
||||
* Global lock semaphore works in conjunction with the HW global lock
|
||||
*/
|
||||
ACPI_EXTERN ACPI_MUTEX AcpiGbl_GlobalLockMutex;
|
||||
ACPI_EXTERN ACPI_OPERAND_OBJECT *AcpiGbl_GlobalLockMutex;
|
||||
ACPI_EXTERN ACPI_SEMAPHORE AcpiGbl_GlobalLockSemaphore;
|
||||
ACPI_EXTERN UINT16 AcpiGbl_GlobalLockHandle;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_GlobalLockAcquired;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_GlobalLockPresent;
|
||||
|
||||
/*
|
||||
* Spinlocks are used for interfaces that can be possibly called at
|
||||
@ -295,22 +299,22 @@ ACPI_EXTERN ACPI_EXCEPTION_HANDLER AcpiGbl_ExceptionHandler;
|
||||
ACPI_EXTERN ACPI_INIT_HANDLER AcpiGbl_InitHandler;
|
||||
ACPI_EXTERN ACPI_WALK_STATE *AcpiGbl_BreakpointWalk;
|
||||
|
||||
/* Owner ID support */
|
||||
|
||||
ACPI_EXTERN UINT32 AcpiGbl_OwnerIdMask[ACPI_NUM_OWNERID_MASKS];
|
||||
ACPI_EXTERN UINT8 AcpiGbl_LastOwnerIdIndex;
|
||||
ACPI_EXTERN UINT8 AcpiGbl_NextOwnerIdOffset;
|
||||
|
||||
/* Misc */
|
||||
|
||||
ACPI_EXTERN UINT32 AcpiGbl_OriginalMode;
|
||||
ACPI_EXTERN UINT32 AcpiGbl_RsdpOriginalLocation;
|
||||
ACPI_EXTERN UINT32 AcpiGbl_NsLookupCount;
|
||||
ACPI_EXTERN UINT32 AcpiGbl_PsFindCount;
|
||||
ACPI_EXTERN UINT32 AcpiGbl_OwnerIdMask[ACPI_NUM_OWNERID_MASKS];
|
||||
ACPI_EXTERN UINT16 AcpiGbl_Pm1EnableRegisterSave;
|
||||
ACPI_EXTERN UINT16 AcpiGbl_GlobalLockHandle;
|
||||
ACPI_EXTERN UINT8 AcpiGbl_LastOwnerIdIndex;
|
||||
ACPI_EXTERN UINT8 AcpiGbl_NextOwnerIdOffset;
|
||||
ACPI_EXTERN UINT8 AcpiGbl_DebuggerConfiguration;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_GlobalLockAcquired;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_StepToNextCall;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_AcpiHardwarePresent;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_GlobalLockPresent;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_EventsInitialized;
|
||||
ACPI_EXTERN BOOLEAN AcpiGbl_SystemAwakeAndRunning;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acinterp.h - Interpreter subcomponent prototypes and defines
|
||||
* $Revision: 1.169 $
|
||||
* $Revision: 1.170 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -380,11 +380,21 @@ AcpiExAcquireMutex (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc,
|
||||
ACPI_WALK_STATE *WalkState);
|
||||
|
||||
ACPI_STATUS
|
||||
AcpiExAcquireMutexObject (
|
||||
UINT16 Timeout,
|
||||
ACPI_OPERAND_OBJECT *ObjDesc,
|
||||
ACPI_THREAD_ID ThreadId);
|
||||
|
||||
ACPI_STATUS
|
||||
AcpiExReleaseMutex (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc,
|
||||
ACPI_WALK_STATE *WalkState);
|
||||
|
||||
ACPI_STATUS
|
||||
AcpiExReleaseMutexObject (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc);
|
||||
|
||||
void
|
||||
AcpiExReleaseAllMutexes (
|
||||
ACPI_THREAD_STATE *Thread);
|
||||
@ -685,13 +695,13 @@ void
|
||||
AcpiExTruncateFor32bitTable (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc);
|
||||
|
||||
BOOLEAN
|
||||
void
|
||||
AcpiExAcquireGlobalLock (
|
||||
UINT32 Rule);
|
||||
|
||||
void
|
||||
AcpiExReleaseGlobalLock (
|
||||
BOOLEAN Locked);
|
||||
void);
|
||||
|
||||
void
|
||||
AcpiExEisaIdToString (
|
||||
|
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only)
|
||||
* $Revision: 1.142 $
|
||||
* $Revision: 1.143 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -257,8 +257,9 @@ typedef struct acpi_object_mutex
|
||||
ACPI_OBJECT_COMMON_HEADER
|
||||
UINT8 SyncLevel; /* 0-15, specified in Mutex() call */
|
||||
UINT16 AcquisitionDepth; /* Allow multiple Acquires, same thread */
|
||||
struct acpi_thread_state *OwnerThread; /* Current owner of the mutex */
|
||||
ACPI_MUTEX OsMutex; /* Actual OS synchronization object */
|
||||
ACPI_THREAD_ID ThreadId; /* Current owner of the mutex */
|
||||
struct acpi_thread_state *OwnerThread; /* Current owner of the mutex */
|
||||
union acpi_operand_object *Prev; /* Link for list of acquired mutexes */
|
||||
union acpi_operand_object *Next; /* Link for list of acquired mutexes */
|
||||
ACPI_NAMESPACE_NODE *Node; /* Containing namespace node */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: aeexec - Support routines for AcpiExec utility
|
||||
* $Revision: 1.117 $
|
||||
* $Revision: 1.118 $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -1051,7 +1051,8 @@ AeMiscellaneousTests (
|
||||
char Buffer[32];
|
||||
ACPI_VENDOR_UUID Uuid = {0, {ACPI_INIT_UUID (0,0,0,0,0,0,0,0,0,0,0)}};
|
||||
ACPI_STATUS Status;
|
||||
UINT32 LockHandle;
|
||||
UINT32 LockHandle1;
|
||||
UINT32 LockHandle2;
|
||||
|
||||
|
||||
ReturnBuf.Length = 32;
|
||||
@ -1107,19 +1108,28 @@ AeMiscellaneousTests (
|
||||
|
||||
/* Test global lock */
|
||||
|
||||
Status = AcpiAcquireGlobalLock (0xFFFF, &LockHandle);
|
||||
Status = AcpiAcquireGlobalLock (0xFFFF, &LockHandle1);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiOsPrintf ("Could not get GlobalLock, %X\n", Status);
|
||||
}
|
||||
|
||||
Status = AcpiAcquireGlobalLock (0x5, &LockHandle); /* Should fail */
|
||||
Status = AcpiAcquireGlobalLock (0x5, &LockHandle2);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiOsPrintf ("Could not get GlobalLock, %X\n", Status);
|
||||
}
|
||||
|
||||
Status = AcpiReleaseGlobalLock (LockHandle);
|
||||
Status = AcpiReleaseGlobalLock (LockHandle1);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiOsPrintf ("Could not release GlobalLock, %X\n", Status);
|
||||
}
|
||||
|
||||
Status = AcpiReleaseGlobalLock (LockHandle2);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
AcpiOsPrintf ("Could not release GlobalLock, %X\n", Status);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user