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;
 }
-
-