aboutsummaryrefslogtreecommitdiff
path: root/source/components/utilities/utdelete.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/components/utilities/utdelete.c')
-rw-r--r--source/components/utilities/utdelete.c96
1 files changed, 50 insertions, 46 deletions
diff --git a/source/components/utilities/utdelete.c b/source/components/utilities/utdelete.c
index a1007136a27d..f18d5564f9d9 100644
--- a/source/components/utilities/utdelete.c
+++ b/source/components/utilities/utdelete.c
@@ -390,11 +390,11 @@ AcpiUtDeleteInternalObjectList (
* FUNCTION: AcpiUtUpdateRefCount
*
* PARAMETERS: Object - Object whose ref count is to be updated
- * Action - What to do
+ * Action - What to do (REF_INCREMENT or REF_DECREMENT)
*
- * RETURN: New ref count
+ * RETURN: None. Sets new reference count within the object
*
- * DESCRIPTION: Modify the ref count and return it.
+ * DESCRIPTION: Modify the reference count for an internal acpi object
*
******************************************************************************/
@@ -403,8 +403,9 @@ AcpiUtUpdateRefCount (
ACPI_OPERAND_OBJECT *Object,
UINT32 Action)
{
- UINT16 Count;
- UINT16 NewCount;
+ UINT16 OriginalCount;
+ UINT16 NewCount = 0;
+ ACPI_CPU_FLAGS LockFlags;
ACPI_FUNCTION_NAME (UtUpdateRefCount);
@@ -415,80 +416,85 @@ AcpiUtUpdateRefCount (
return;
}
- Count = Object->Common.ReferenceCount;
- NewCount = Count;
-
/*
- * Perform the reference count action (increment, decrement, force delete)
+ * Always get the reference count lock. Note: Interpreter and/or
+ * Namespace is not always locked when this function is called.
*/
+ LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock);
+ OriginalCount = Object->Common.ReferenceCount;
+
+ /* Perform the reference count action (increment, decrement) */
+
switch (Action)
{
case REF_INCREMENT:
- NewCount++;
+ NewCount = OriginalCount + 1;
Object->Common.ReferenceCount = NewCount;
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+
+ /* The current reference count should never be zero here */
+
+ if (!OriginalCount)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Obj %p, Reference Count was zero before increment\n",
+ Object));
+ }
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, [Incremented]\n",
- Object, NewCount));
+ "Obj %p Type %.2X Refs %.2X [Incremented]\n",
+ Object, Object->Common.Type, NewCount));
break;
case REF_DECREMENT:
- if (Count < 1)
- {
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
- Object, NewCount));
+ /* The current reference count must be non-zero */
- NewCount = 0;
- }
- else
+ if (OriginalCount)
{
- NewCount--;
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, [Decremented]\n",
- Object, NewCount));
+ NewCount = OriginalCount - 1;
+ Object->Common.ReferenceCount = NewCount;
}
- if (Object->Common.Type == ACPI_TYPE_METHOD)
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+
+ if (!OriginalCount)
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Method Obj %p Refs=%X, [Decremented]\n", Object, NewCount));
+ ACPI_WARNING ((AE_INFO,
+ "Obj %p, Reference Count is already zero, cannot decrement\n",
+ Object));
}
- Object->Common.ReferenceCount = NewCount;
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Type %.2X Refs %.2X [Decremented]\n",
+ Object, Object->Common.Type, NewCount));
+
+ /* Actually delete the object on a reference count of zero */
+
if (NewCount == 0)
{
AcpiUtDeleteInternalObj (Object);
}
break;
- case REF_FORCE_DELETE:
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
- "Obj %p Refs=%X, Force delete! (Set to 0)\n", Object, Count));
-
- NewCount = 0;
- Object->Common.ReferenceCount = NewCount;
- AcpiUtDeleteInternalObj (Object);
- break;
-
default:
- ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action));
- break;
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+ ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)",
+ Action));
+ return;
}
/*
* Sanity check the reference count, for debug purposes only.
* (A deleted object will have a huge reference count)
*/
- if (Count > ACPI_MAX_REFERENCE_COUNT)
+ if (NewCount > ACPI_MAX_REFERENCE_COUNT)
{
ACPI_WARNING ((AE_INFO,
- "Large Reference Count (0x%X) in object %p", Count, Object));
+ "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
+ NewCount, Object, Object->Common.Type));
}
}
@@ -499,8 +505,7 @@ AcpiUtUpdateRefCount (
*
* PARAMETERS: Object - Increment ref count for this object
* and all sub-objects
- * Action - Either REF_INCREMENT or REF_DECREMENT or
- * REF_FORCE_DELETE
+ * Action - Either REF_INCREMENT or REF_DECREMENT
*
* RETURN: Status
*
@@ -771,7 +776,6 @@ AcpiUtRemoveReference (
/*
* Allow a NULL pointer to be passed in, just ignore it. This saves
* each caller from having to check. Also, ignore NS nodes.
- *
*/
if (!Object ||
(ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))