Print this page
acpica-unix2-20130823
PANKOVs restructure
@@ -3,11 +3,11 @@
* Module Name: utdelete - object deletion and reference count utilities
*
******************************************************************************/
/*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -116,11 +116,10 @@
ObjPointer = Object->String.Pointer;
}
break;
-
case ACPI_TYPE_BUFFER:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
Object, Object->Buffer.Pointer));
@@ -132,11 +131,10 @@
ObjPointer = Object->Buffer.Pointer;
}
break;
-
case ACPI_TYPE_PACKAGE:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
Object->Package.Count));
@@ -148,11 +146,10 @@
/* Free the (variable length) element pointer array */
ObjPointer = Object->Package.Elements;
break;
-
/*
* These objects have a possible list of notify handlers.
* Device object also may have a GPE block.
*/
case ACPI_TYPE_DEVICE:
@@ -165,11 +162,11 @@
/*lint -fallthrough */
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_THERMAL:
- /* Walk the notify handler list for this object */
+ /* Walk the address handler list for this object */
HandlerDesc = Object->CommonNotify.Handler;
while (HandlerDesc)
{
NextDesc = HandlerDesc->AddressSpace.Next;
@@ -176,11 +173,10 @@
AcpiUtRemoveReference (HandlerDesc);
HandlerDesc = NextDesc;
}
break;
-
case ACPI_TYPE_MUTEX:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"***** Mutex %p, OS Mutex %p\n",
Object, Object->Mutex.OsMutex));
@@ -200,11 +196,10 @@
AcpiExUnlinkMutex (Object);
AcpiOsDeleteMutex (Object->Mutex.OsMutex);
}
break;
-
case ACPI_TYPE_EVENT:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"***** Event %p, OS Semaphore %p\n",
Object, Object->Event.OsSemaphore));
@@ -211,11 +206,10 @@
(void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
Object->Event.OsSemaphore = NULL;
break;
-
case ACPI_TYPE_METHOD:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"***** Method %p\n", Object));
@@ -227,16 +221,25 @@
AcpiUtDeleteObjectDesc (Object->Method.Mutex);
Object->Method.Mutex = NULL;
}
break;
-
case ACPI_TYPE_REGION:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"***** Region %p\n", Object));
+ /*
+ * Update AddressRange list. However, only permanent regions
+ * are installed in this list. (Not created within a method)
+ */
+ if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY))
+ {
+ AcpiUtRemoveAddressRange (Object->Region.SpaceId,
+ Object->Region.Node);
+ }
+
SecondDesc = AcpiNsGetSecondaryObject (Object);
if (SecondDesc)
{
/*
* Free the RegionContext if and only if the handler is one of the
@@ -286,11 +289,10 @@
AcpiUtDeleteObjectDesc (SecondDesc);
}
break;
-
case ACPI_TYPE_BUFFER_FIELD:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"***** Buffer Field %p\n", Object));
@@ -299,11 +301,10 @@
{
AcpiUtDeleteObjectDesc (SecondDesc);
}
break;
-
case ACPI_TYPE_LOCAL_BANK_FIELD:
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"***** Bank Field %p\n", Object));
@@ -312,12 +313,12 @@
{
AcpiUtDeleteObjectDesc (SecondDesc);
}
break;
-
default:
+
break;
}
/* Free any allocated memory (pointer within the object) found above */
@@ -356,11 +357,11 @@
ACPI_OPERAND_OBJECT **ObjList)
{
ACPI_OPERAND_OBJECT **InternalObj;
- ACPI_FUNCTION_TRACE (UtDeleteInternalObjectList);
+ ACPI_FUNCTION_ENTRY ();
/* Walk the null-terminated internal list */
for (InternalObj = ObjList; *InternalObj; InternalObj++)
@@ -369,34 +370,35 @@
}
/* Free the combined parameter pointer list and object array */
ACPI_FREE (ObjList);
- return_VOID;
+ return;
}
/*******************************************************************************
*
* 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
*
******************************************************************************/
static void
AcpiUtUpdateRefCount (
ACPI_OPERAND_OBJECT *Object,
UINT32 Action)
{
- UINT16 Count;
- UINT16 NewCount;
+ UINT16 OriginalCount;
+ UINT16 NewCount = 0;
+ ACPI_CPU_FLAGS LockFlags;
ACPI_FUNCTION_NAME (UtUpdateRefCount);
@@ -403,84 +405,89 @@
if (!Object)
{
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));
}
}
/*******************************************************************************
@@ -487,12 +494,11 @@
*
* FUNCTION: AcpiUtUpdateObjectReference
*
* 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
*
* DESCRIPTION: Increment the object reference count
*
@@ -511,15 +517,16 @@
UINT16 Action)
{
ACPI_STATUS Status = AE_OK;
ACPI_GENERIC_STATE *StateList = NULL;
ACPI_OPERAND_OBJECT *NextObject = NULL;
+ ACPI_OPERAND_OBJECT *PrevObject;
ACPI_GENERIC_STATE *State;
UINT32 i;
- ACPI_FUNCTION_TRACE_PTR (UtUpdateObjectReference, Object);
+ ACPI_FUNCTION_NAME (UtUpdateObjectReference);
while (Object)
{
/* Make sure that this isn't a namespace handle */
@@ -526,11 +533,11 @@
if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
{
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"Object %p is NS handle\n", Object));
- return_ACPI_STATUS (AE_OK);
+ return (AE_OK);
}
/*
* All sub-objects must have their reference count incremented also.
* Different object types have different subobjects.
@@ -539,15 +546,24 @@
{
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
case ACPI_TYPE_THERMAL:
-
- /* Update the notify objects for these types (if present) */
-
- AcpiUtUpdateRefCount (Object->CommonNotify.SystemNotify, Action);
- AcpiUtUpdateRefCount (Object->CommonNotify.DeviceNotify, Action);
+ /*
+ * Update the notify objects for these types (if present)
+ * Two lists, system and device notify handlers.
+ */
+ for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
+ {
+ PrevObject = Object->CommonNotify.NotifyList[i];
+ while (PrevObject)
+ {
+ NextObject = PrevObject->Notify.Next[i];
+ AcpiUtUpdateRefCount (PrevObject, Action);
+ PrevObject = NextObject;
+ }
+ }
break;
case ACPI_TYPE_PACKAGE:
/*
* We must update all the sub-objects of the package,
@@ -554,21 +570,47 @@
* each of whom may have their own sub-objects.
*/
for (i = 0; i < Object->Package.Count; i++)
{
/*
- * Push each element onto the stack for later processing.
- * Note: There can be null elements within the package,
- * these are simply ignored
+ * Null package elements are legal and can be simply
+ * ignored.
*/
+ NextObject = Object->Package.Elements[i];
+ if (!NextObject)
+ {
+ continue;
+ }
+
+ switch (NextObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ case ACPI_TYPE_STRING:
+ case ACPI_TYPE_BUFFER:
+ /*
+ * For these very simple sub-objects, we can just
+ * update the reference count here and continue.
+ * Greatly increases performance of this operation.
+ */
+ AcpiUtUpdateRefCount (NextObject, Action);
+ break;
+
+ default:
+ /*
+ * For complex sub-objects, push them onto the stack
+ * for later processing (this eliminates recursion.)
+ */
Status = AcpiUtCreateUpdateStateAndPush (
- Object->Package.Elements[i], Action, &StateList);
+ NextObject, Action, &StateList);
if (ACPI_FAILURE (Status))
{
goto ErrorExit;
}
+ break;
}
+ }
+ NextObject = NULL;
break;
case ACPI_TYPE_BUFFER_FIELD:
NextObject = Object->BufferField.BufferObj;
@@ -614,10 +656,11 @@
}
break;
case ACPI_TYPE_REGION:
default:
+
break; /* No subobjects for all other types */
}
/*
* Now we can update the count in the main object. This can only
@@ -640,11 +683,11 @@
Object = State->Update.Object;
AcpiUtDeleteGenericState (State);
}
}
- return_ACPI_STATUS (AE_OK);
+ return (AE_OK);
ErrorExit:
ACPI_EXCEPTION ((AE_INFO, Status,
@@ -656,11 +699,11 @@
{
State = AcpiUtPopGenericState (&StateList);
AcpiUtDeleteGenericState (State);
}
- return_ACPI_STATUS (Status);
+ return (Status);
}
/*******************************************************************************
*
@@ -678,28 +721,28 @@
void
AcpiUtAddReference (
ACPI_OPERAND_OBJECT *Object)
{
- ACPI_FUNCTION_TRACE_PTR (UtAddReference, Object);
+ ACPI_FUNCTION_NAME (UtAddReference);
/* Ensure that we have a valid object */
if (!AcpiUtValidInternalObject (Object))
{
- return_VOID;
+ return;
}
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"Obj %p Current Refs=%X [To Be Incremented]\n",
Object, Object->Common.ReferenceCount));
/* Increment the reference count */
(void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
- return_VOID;
+ return;
}
/*******************************************************************************
*
@@ -716,30 +759,29 @@
void
AcpiUtRemoveReference (
ACPI_OPERAND_OBJECT *Object)
{
- ACPI_FUNCTION_TRACE_PTR (UtRemoveReference, Object);
+ ACPI_FUNCTION_NAME (UtRemoveReference);
/*
* 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))
{
- return_VOID;
+ return;
}
/* Ensure that we have a valid object */
if (!AcpiUtValidInternalObject (Object))
{
- return_VOID;
+ return;
}
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
"Obj %p Current Refs=%X [To Be Decremented]\n",
Object, Object->Common.ReferenceCount));
@@ -748,9 +790,7 @@
* Decrement the reference count, and only actually delete the object
* if the reference count becomes 0. (Must also decrement the ref count
* of all subobjects!)
*/
(void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
- return_VOID;
+ return;
}
-
-