1 /******************************************************************************
   2  *
   3  * Module Name: uttrack - Memory allocation tracking routines (debug only)
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 /*
  45  * These procedures are used for tracking memory leaks in the subsystem, and
  46  * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
  47  *
  48  * Each memory allocation is tracked via a doubly linked list.  Each
  49  * element contains the caller's component, module name, function name, and
  50  * line number.  AcpiUtAllocate and AcpiUtAllocateZeroed call
  51  * AcpiUtTrackAllocation to add an element to the list; deletion
  52  * occurs in the body of AcpiUtFree.
  53  */
  54 
  55 #define __UTTRACK_C__
  56 
  57 #include "acpi.h"
  58 #include "accommon.h"
  59 
  60 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  61 
  62 #define _COMPONENT          ACPI_UTILITIES
  63         ACPI_MODULE_NAME    ("uttrack")
  64 
  65 /* Local prototypes */
  66 
  67 static ACPI_DEBUG_MEM_BLOCK *
  68 AcpiUtFindAllocation (
  69     void                    *Allocation);
  70 
  71 static ACPI_STATUS
  72 AcpiUtTrackAllocation (
  73     ACPI_DEBUG_MEM_BLOCK    *Address,
  74     ACPI_SIZE               Size,
  75     UINT8                   AllocType,
  76     UINT32                  Component,
  77     const char              *Module,
  78     UINT32                  Line);
  79 
  80 static ACPI_STATUS
  81 AcpiUtRemoveAllocation (
  82     ACPI_DEBUG_MEM_BLOCK    *Address,
  83     UINT32                  Component,
  84     const char              *Module,
  85     UINT32                  Line);
  86 
  87 
  88 /*******************************************************************************
  89  *
  90  * FUNCTION:    AcpiUtCreateList
  91  *
  92  * PARAMETERS:  CacheName       - Ascii name for the cache
  93  *              ObjectSize      - Size of each cached object
  94  *              ReturnCache     - Where the new cache object is returned
  95  *
  96  * RETURN:      Status
  97  *
  98  * DESCRIPTION: Create a local memory list for tracking purposed
  99  *
 100  ******************************************************************************/
 101 
 102 ACPI_STATUS
 103 AcpiUtCreateList (
 104     char                    *ListName,
 105     UINT16                  ObjectSize,
 106     ACPI_MEMORY_LIST        **ReturnCache)
 107 {
 108     ACPI_MEMORY_LIST        *Cache;
 109 
 110 
 111     Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST));
 112     if (!Cache)
 113     {
 114         return (AE_NO_MEMORY);
 115     }
 116 
 117     ACPI_MEMSET (Cache, 0, sizeof (ACPI_MEMORY_LIST));
 118 
 119     Cache->ListName   = ListName;
 120     Cache->ObjectSize = ObjectSize;
 121 
 122     *ReturnCache = Cache;
 123     return (AE_OK);
 124 }
 125 
 126 
 127 /*******************************************************************************
 128  *
 129  * FUNCTION:    AcpiUtAllocateAndTrack
 130  *
 131  * PARAMETERS:  Size                - Size of the allocation
 132  *              Component           - Component type of caller
 133  *              Module              - Source file name of caller
 134  *              Line                - Line number of caller
 135  *
 136  * RETURN:      Address of the allocated memory on success, NULL on failure.
 137  *
 138  * DESCRIPTION: The subsystem's equivalent of malloc.
 139  *
 140  ******************************************************************************/
 141 
 142 void *
 143 AcpiUtAllocateAndTrack (
 144     ACPI_SIZE               Size,
 145     UINT32                  Component,
 146     const char              *Module,
 147     UINT32                  Line)
 148 {
 149     ACPI_DEBUG_MEM_BLOCK    *Allocation;
 150     ACPI_STATUS             Status;
 151 
 152 
 153     Allocation = AcpiUtAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER),
 154                     Component, Module, Line);
 155     if (!Allocation)
 156     {
 157         return (NULL);
 158     }
 159 
 160     Status = AcpiUtTrackAllocation (Allocation, Size,
 161                     ACPI_MEM_MALLOC, Component, Module, Line);
 162     if (ACPI_FAILURE (Status))
 163     {
 164         AcpiOsFree (Allocation);
 165         return (NULL);
 166     }
 167 
 168     AcpiGbl_GlobalList->TotalAllocated++;
 169     AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
 170     AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
 171     if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied)
 172     {
 173         AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize;
 174     }
 175 
 176     return ((void *) &Allocation->UserSpace);
 177 }
 178 
 179 
 180 /*******************************************************************************
 181  *
 182  * FUNCTION:    AcpiUtAllocateZeroedAndTrack
 183  *
 184  * PARAMETERS:  Size                - Size of the allocation
 185  *              Component           - Component type of caller
 186  *              Module              - Source file name of caller
 187  *              Line                - Line number of caller
 188  *
 189  * RETURN:      Address of the allocated memory on success, NULL on failure.
 190  *
 191  * DESCRIPTION: Subsystem equivalent of calloc.
 192  *
 193  ******************************************************************************/
 194 
 195 void *
 196 AcpiUtAllocateZeroedAndTrack (
 197     ACPI_SIZE               Size,
 198     UINT32                  Component,
 199     const char              *Module,
 200     UINT32                  Line)
 201 {
 202     ACPI_DEBUG_MEM_BLOCK    *Allocation;
 203     ACPI_STATUS             Status;
 204 
 205 
 206     Allocation = AcpiUtAllocateZeroed (Size + sizeof (ACPI_DEBUG_MEM_HEADER),
 207                     Component, Module, Line);
 208     if (!Allocation)
 209     {
 210         /* Report allocation error */
 211 
 212         ACPI_ERROR ((Module, Line,
 213             "Could not allocate size %u", (UINT32) Size));
 214         return (NULL);
 215     }
 216 
 217     Status = AcpiUtTrackAllocation (Allocation, Size,
 218                 ACPI_MEM_CALLOC, Component, Module, Line);
 219     if (ACPI_FAILURE (Status))
 220     {
 221         AcpiOsFree (Allocation);
 222         return (NULL);
 223     }
 224 
 225     AcpiGbl_GlobalList->TotalAllocated++;
 226     AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
 227     AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
 228     if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied)
 229     {
 230         AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize;
 231     }
 232 
 233     return ((void *) &Allocation->UserSpace);
 234 }
 235 
 236 
 237 /*******************************************************************************
 238  *
 239  * FUNCTION:    AcpiUtFreeAndTrack
 240  *
 241  * PARAMETERS:  Allocation          - Address of the memory to deallocate
 242  *              Component           - Component type of caller
 243  *              Module              - Source file name of caller
 244  *              Line                - Line number of caller
 245  *
 246  * RETURN:      None
 247  *
 248  * DESCRIPTION: Frees the memory at Allocation
 249  *
 250  ******************************************************************************/
 251 
 252 void
 253 AcpiUtFreeAndTrack (
 254     void                    *Allocation,
 255     UINT32                  Component,
 256     const char              *Module,
 257     UINT32                  Line)
 258 {
 259     ACPI_DEBUG_MEM_BLOCK    *DebugBlock;
 260     ACPI_STATUS             Status;
 261 
 262 
 263     ACPI_FUNCTION_TRACE_PTR (UtFree, Allocation);
 264 
 265 
 266     if (NULL == Allocation)
 267     {
 268         ACPI_ERROR ((Module, Line,
 269             "Attempt to delete a NULL address"));
 270 
 271         return_VOID;
 272     }
 273 
 274     DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK,
 275                     (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER)));
 276 
 277     AcpiGbl_GlobalList->TotalFreed++;
 278     AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size;
 279 
 280     Status = AcpiUtRemoveAllocation (DebugBlock,
 281                     Component, Module, Line);
 282     if (ACPI_FAILURE (Status))
 283     {
 284         ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory"));
 285     }
 286 
 287     AcpiOsFree (DebugBlock);
 288     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Allocation));
 289     return_VOID;
 290 }
 291 
 292 
 293 /*******************************************************************************
 294  *
 295  * FUNCTION:    AcpiUtFindAllocation
 296  *
 297  * PARAMETERS:  Allocation              - Address of allocated memory
 298  *
 299  * RETURN:      A list element if found; NULL otherwise.
 300  *
 301  * DESCRIPTION: Searches for an element in the global allocation tracking list.
 302  *
 303  ******************************************************************************/
 304 
 305 static ACPI_DEBUG_MEM_BLOCK *
 306 AcpiUtFindAllocation (
 307     void                    *Allocation)
 308 {
 309     ACPI_DEBUG_MEM_BLOCK    *Element;
 310 
 311 
 312     ACPI_FUNCTION_ENTRY ();
 313 
 314 
 315     Element = AcpiGbl_GlobalList->ListHead;
 316 
 317     /* Search for the address. */
 318 
 319     while (Element)
 320     {
 321         if (Element == Allocation)
 322         {
 323             return (Element);
 324         }
 325 
 326         Element = Element->Next;
 327     }
 328 
 329     return (NULL);
 330 }
 331 
 332 
 333 /*******************************************************************************
 334  *
 335  * FUNCTION:    AcpiUtTrackAllocation
 336  *
 337  * PARAMETERS:  Allocation          - Address of allocated memory
 338  *              Size                - Size of the allocation
 339  *              AllocType           - MEM_MALLOC or MEM_CALLOC
 340  *              Component           - Component type of caller
 341  *              Module              - Source file name of caller
 342  *              Line                - Line number of caller
 343  *
 344  * RETURN:      None.
 345  *
 346  * DESCRIPTION: Inserts an element into the global allocation tracking list.
 347  *
 348  ******************************************************************************/
 349 
 350 static ACPI_STATUS
 351 AcpiUtTrackAllocation (
 352     ACPI_DEBUG_MEM_BLOCK    *Allocation,
 353     ACPI_SIZE               Size,
 354     UINT8                   AllocType,
 355     UINT32                  Component,
 356     const char              *Module,
 357     UINT32                  Line)
 358 {
 359     ACPI_MEMORY_LIST        *MemList;
 360     ACPI_DEBUG_MEM_BLOCK    *Element;
 361     ACPI_STATUS             Status = AE_OK;
 362 
 363 
 364     ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation);
 365 
 366 
 367     if (AcpiGbl_DisableMemTracking)
 368     {
 369         return_ACPI_STATUS (AE_OK);
 370     }
 371 
 372     MemList = AcpiGbl_GlobalList;
 373     Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
 374     if (ACPI_FAILURE (Status))
 375     {
 376         return_ACPI_STATUS (Status);
 377     }
 378 
 379     /*
 380      * Search list for this address to make sure it is not already on the list.
 381      * This will catch several kinds of problems.
 382      */
 383     Element = AcpiUtFindAllocation (Allocation);
 384     if (Element)
 385     {
 386         ACPI_ERROR ((AE_INFO,
 387             "UtTrackAllocation: Allocation already present in list! (%p)",
 388             Allocation));
 389 
 390         ACPI_ERROR ((AE_INFO, "Element %p Address %p",
 391             Element, Allocation));
 392 
 393         goto UnlockAndExit;
 394     }
 395 
 396     /* Fill in the instance data. */
 397 
 398     Allocation->Size      = (UINT32) Size;
 399     Allocation->AllocType = AllocType;
 400     Allocation->Component = Component;
 401     Allocation->Line      = Line;
 402 
 403     ACPI_STRNCPY (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
 404     Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
 405 
 406     /* Insert at list head */
 407 
 408     if (MemList->ListHead)
 409     {
 410         ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Allocation;
 411     }
 412 
 413     Allocation->Next = MemList->ListHead;
 414     Allocation->Previous = NULL;
 415 
 416     MemList->ListHead = Allocation;
 417 
 418 
 419 UnlockAndExit:
 420     Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
 421     return_ACPI_STATUS (Status);
 422 }
 423 
 424 
 425 /*******************************************************************************
 426  *
 427  * FUNCTION:    AcpiUtRemoveAllocation
 428  *
 429  * PARAMETERS:  Allocation          - Address of allocated memory
 430  *              Component           - Component type of caller
 431  *              Module              - Source file name of caller
 432  *              Line                - Line number of caller
 433  *
 434  * RETURN:
 435  *
 436  * DESCRIPTION: Deletes an element from the global allocation tracking list.
 437  *
 438  ******************************************************************************/
 439 
 440 static ACPI_STATUS
 441 AcpiUtRemoveAllocation (
 442     ACPI_DEBUG_MEM_BLOCK    *Allocation,
 443     UINT32                  Component,
 444     const char              *Module,
 445     UINT32                  Line)
 446 {
 447     ACPI_MEMORY_LIST        *MemList;
 448     ACPI_STATUS             Status;
 449 
 450 
 451     ACPI_FUNCTION_TRACE (UtRemoveAllocation);
 452 
 453 
 454     if (AcpiGbl_DisableMemTracking)
 455     {
 456         return_ACPI_STATUS (AE_OK);
 457     }
 458 
 459     MemList = AcpiGbl_GlobalList;
 460     if (NULL == MemList->ListHead)
 461     {
 462         /* No allocations! */
 463 
 464         ACPI_ERROR ((Module, Line,
 465             "Empty allocation list, nothing to free!"));
 466 
 467         return_ACPI_STATUS (AE_OK);
 468     }
 469 
 470     Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
 471     if (ACPI_FAILURE (Status))
 472     {
 473         return_ACPI_STATUS (Status);
 474     }
 475 
 476     /* Unlink */
 477 
 478     if (Allocation->Previous)
 479     {
 480         (Allocation->Previous)->Next = Allocation->Next;
 481     }
 482     else
 483     {
 484         MemList->ListHead = Allocation->Next;
 485     }
 486 
 487     if (Allocation->Next)
 488     {
 489         (Allocation->Next)->Previous = Allocation->Previous;
 490     }
 491 
 492     /* Mark the segment as deleted */
 493 
 494     ACPI_MEMSET (&Allocation->UserSpace, 0xEA, Allocation->Size);
 495 
 496     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
 497         Allocation->Size));
 498 
 499     Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
 500     return_ACPI_STATUS (Status);
 501 }
 502 
 503 
 504 /*******************************************************************************
 505  *
 506  * FUNCTION:    AcpiUtDumpAllocationInfo
 507  *
 508  * PARAMETERS:
 509  *
 510  * RETURN:      None
 511  *
 512  * DESCRIPTION: Print some info about the outstanding allocations.
 513  *
 514  ******************************************************************************/
 515 
 516 void
 517 AcpiUtDumpAllocationInfo (
 518     void)
 519 {
 520 /*
 521     ACPI_MEMORY_LIST        *MemList;
 522 */
 523 
 524     ACPI_FUNCTION_TRACE (UtDumpAllocationInfo);
 525 
 526 /*
 527     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 528                     ("%30s: %4d (%3d Kb)\n", "Current allocations",
 529                     MemList->CurrentCount,
 530                     ROUND_UP_TO_1K (MemList->CurrentSize)));
 531 
 532     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 533                     ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
 534                     MemList->MaxConcurrentCount,
 535                     ROUND_UP_TO_1K (MemList->MaxConcurrentSize)));
 536 
 537 
 538     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 539                     ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
 540                     RunningObjectCount,
 541                     ROUND_UP_TO_1K (RunningObjectSize)));
 542 
 543     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 544                     ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
 545                     RunningAllocCount,
 546                     ROUND_UP_TO_1K (RunningAllocSize)));
 547 
 548 
 549     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 550                     ("%30s: %4d (%3d Kb)\n", "Current Nodes",
 551                     AcpiGbl_CurrentNodeCount,
 552                     ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize)));
 553 
 554     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 555                     ("%30s: %4d (%3d Kb)\n", "Max Nodes",
 556                     AcpiGbl_MaxConcurrentNodeCount,
 557                     ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount *
 558                         sizeof (ACPI_NAMESPACE_NODE)))));
 559 */
 560     return_VOID;
 561 }
 562 
 563 
 564 /*******************************************************************************
 565  *
 566  * FUNCTION:    AcpiUtDumpAllocations
 567  *
 568  * PARAMETERS:  Component           - Component(s) to dump info for.
 569  *              Module              - Module to dump info for.  NULL means all.
 570  *
 571  * RETURN:      None
 572  *
 573  * DESCRIPTION: Print a list of all outstanding allocations.
 574  *
 575  ******************************************************************************/
 576 
 577 void
 578 AcpiUtDumpAllocations (
 579     UINT32                  Component,
 580     const char              *Module)
 581 {
 582     ACPI_DEBUG_MEM_BLOCK    *Element;
 583     ACPI_DESCRIPTOR         *Descriptor;
 584     UINT32                  NumOutstanding = 0;
 585     UINT8                   DescriptorType;
 586 
 587 
 588     ACPI_FUNCTION_TRACE (UtDumpAllocations);
 589 
 590 
 591     if (AcpiGbl_DisableMemTracking)
 592     {
 593         return;
 594     }
 595 
 596     /*
 597      * Walk the allocation list.
 598      */
 599     if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY)))
 600     {
 601         return;
 602     }
 603 
 604     Element = AcpiGbl_GlobalList->ListHead;
 605     while (Element)
 606     {
 607         if ((Element->Component & Component) &&
 608             ((Module == NULL) || (0 == ACPI_STRCMP (Module, Element->Module))))
 609         {
 610             Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace);
 611 
 612             if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR))
 613             {
 614                 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u "
 615                     "[Not a Descriptor - too small]\n",
 616                     Descriptor, Element->Size, Element->Module,
 617                     Element->Line);
 618             }
 619             else
 620             {
 621                 /* Ignore allocated objects that are in a cache */
 622 
 623                 if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != ACPI_DESC_TYPE_CACHED)
 624                 {
 625                     AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ",
 626                         Descriptor, Element->Size, Element->Module,
 627                         Element->Line, AcpiUtGetDescriptorName (Descriptor));
 628 
 629                     /* Validate the descriptor type using Type field and length */
 630 
 631                     DescriptorType = 0; /* Not a valid descriptor type */
 632 
 633                     switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
 634                     {
 635                     case ACPI_DESC_TYPE_OPERAND:
 636                         if (Element->Size == sizeof (ACPI_DESC_TYPE_OPERAND))
 637                         {
 638                             DescriptorType = ACPI_DESC_TYPE_OPERAND;
 639                         }
 640                         break;
 641 
 642                     case ACPI_DESC_TYPE_PARSER:
 643                         if (Element->Size == sizeof (ACPI_DESC_TYPE_PARSER))
 644                         {
 645                             DescriptorType = ACPI_DESC_TYPE_PARSER;
 646                         }
 647                         break;
 648 
 649                     case ACPI_DESC_TYPE_NAMED:
 650                         if (Element->Size == sizeof (ACPI_DESC_TYPE_NAMED))
 651                         {
 652                             DescriptorType = ACPI_DESC_TYPE_NAMED;
 653                         }
 654                         break;
 655 
 656                     default:
 657                         break;
 658                     }
 659 
 660                     /* Display additional info for the major descriptor types */
 661 
 662                     switch (DescriptorType)
 663                     {
 664                     case ACPI_DESC_TYPE_OPERAND:
 665                         AcpiOsPrintf ("%12.12s  RefCount 0x%04X\n",
 666                             AcpiUtGetTypeName (Descriptor->Object.Common.Type),
 667                             Descriptor->Object.Common.ReferenceCount);
 668                         break;
 669 
 670                     case ACPI_DESC_TYPE_PARSER:
 671                         AcpiOsPrintf ("AmlOpcode 0x%04hX\n",
 672                             Descriptor->Op.Asl.AmlOpcode);
 673                         break;
 674 
 675                     case ACPI_DESC_TYPE_NAMED:
 676                         AcpiOsPrintf ("%4.4s\n",
 677                             AcpiUtGetNodeName (&Descriptor->Node));
 678                         break;
 679 
 680                     default:
 681                         AcpiOsPrintf ( "\n");
 682                         break;
 683                     }
 684                 }
 685             }
 686 
 687             NumOutstanding++;
 688         }
 689 
 690         Element = Element->Next;
 691     }
 692 
 693     (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
 694 
 695     /* Print summary */
 696 
 697     if (!NumOutstanding)
 698     {
 699         ACPI_INFO ((AE_INFO, "No outstanding allocations"));
 700     }
 701     else
 702     {
 703         ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations",
 704             NumOutstanding, NumOutstanding));
 705     }
 706 
 707     return_VOID;
 708 }
 709 
 710 #endif  /* ACPI_DBG_TRACK_ALLOCATIONS */
 711