1 /****************************************************************************** 2 * 3 * Module Name: uttrack - Memory allocation tracking routines (debug only) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, 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 #include "acpi.h" 56 #include "accommon.h" 57 58 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 59 60 #define _COMPONENT ACPI_UTILITIES 61 ACPI_MODULE_NAME ("uttrack") 62 63 64 /* Local prototypes */ 65 66 static ACPI_DEBUG_MEM_BLOCK * 67 AcpiUtFindAllocation ( 68 ACPI_DEBUG_MEM_BLOCK *Allocation); 69 70 static ACPI_STATUS 71 AcpiUtTrackAllocation ( 72 ACPI_DEBUG_MEM_BLOCK *Address, 73 ACPI_SIZE Size, 74 UINT8 AllocType, 75 UINT32 Component, 76 const char *Module, 77 UINT32 Line); 78 79 static ACPI_STATUS 80 AcpiUtRemoveAllocation ( 81 ACPI_DEBUG_MEM_BLOCK *Address, 82 UINT32 Component, 83 const char *Module, 84 UINT32 Line); 85 86 87 /******************************************************************************* 88 * 89 * FUNCTION: AcpiUtCreateList 90 * 91 * PARAMETERS: CacheName - Ascii name for the cache 92 * ObjectSize - Size of each cached object 93 * ReturnCache - Where the new cache object is returned 94 * 95 * RETURN: Status 96 * 97 * DESCRIPTION: Create a local memory list for tracking purposed 98 * 99 ******************************************************************************/ 100 101 ACPI_STATUS 102 AcpiUtCreateList ( 103 const char *ListName, 104 UINT16 ObjectSize, 105 ACPI_MEMORY_LIST **ReturnCache) 106 { 107 ACPI_MEMORY_LIST *Cache; 108 109 110 Cache = AcpiOsAllocateZeroed (sizeof (ACPI_MEMORY_LIST)); 111 if (!Cache) 112 { 113 return (AE_NO_MEMORY); 114 } 115 116 Cache->ListName = ListName; 117 Cache->ObjectSize = ObjectSize; 118 119 *ReturnCache = Cache; 120 return (AE_OK); 121 } 122 123 124 /******************************************************************************* 125 * 126 * FUNCTION: AcpiUtAllocateAndTrack 127 * 128 * PARAMETERS: Size - Size of the allocation 129 * Component - Component type of caller 130 * Module - Source file name of caller 131 * Line - Line number of caller 132 * 133 * RETURN: Address of the allocated memory on success, NULL on failure. 134 * 135 * DESCRIPTION: The subsystem's equivalent of malloc. 136 * 137 ******************************************************************************/ 138 139 void * 140 AcpiUtAllocateAndTrack ( 141 ACPI_SIZE Size, 142 UINT32 Component, 143 const char *Module, 144 UINT32 Line) 145 { 146 ACPI_DEBUG_MEM_BLOCK *Allocation; 147 ACPI_STATUS Status; 148 149 150 /* Check for an inadvertent size of zero bytes */ 151 152 if (!Size) 153 { 154 ACPI_WARNING ((Module, Line, 155 "Attempt to allocate zero bytes, allocating 1 byte")); 156 Size = 1; 157 } 158 159 Allocation = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER)); 160 if (!Allocation) 161 { 162 /* Report allocation error */ 163 164 ACPI_WARNING ((Module, Line, 165 "Could not allocate size %u", (UINT32) Size)); 166 167 return (NULL); 168 } 169 170 Status = AcpiUtTrackAllocation ( 171 Allocation, Size, ACPI_MEM_MALLOC, Component, Module, Line); 172 if (ACPI_FAILURE (Status)) 173 { 174 AcpiOsFree (Allocation); 175 return (NULL); 176 } 177 178 AcpiGbl_GlobalList->TotalAllocated++; 179 AcpiGbl_GlobalList->TotalSize += (UINT32) Size; 180 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; 181 182 if (AcpiGbl_GlobalList->CurrentTotalSize > 183 AcpiGbl_GlobalList->MaxOccupied) 184 { 185 AcpiGbl_GlobalList->MaxOccupied = 186 AcpiGbl_GlobalList->CurrentTotalSize; 187 } 188 189 return ((void *) &Allocation->UserSpace); 190 } 191 192 193 /******************************************************************************* 194 * 195 * FUNCTION: AcpiUtAllocateZeroedAndTrack 196 * 197 * PARAMETERS: Size - Size of the allocation 198 * Component - Component type of caller 199 * Module - Source file name of caller 200 * Line - Line number of caller 201 * 202 * RETURN: Address of the allocated memory on success, NULL on failure. 203 * 204 * DESCRIPTION: Subsystem equivalent of calloc. 205 * 206 ******************************************************************************/ 207 208 void * 209 AcpiUtAllocateZeroedAndTrack ( 210 ACPI_SIZE Size, 211 UINT32 Component, 212 const char *Module, 213 UINT32 Line) 214 { 215 ACPI_DEBUG_MEM_BLOCK *Allocation; 216 ACPI_STATUS Status; 217 218 219 /* Check for an inadvertent size of zero bytes */ 220 221 if (!Size) 222 { 223 ACPI_WARNING ((Module, Line, 224 "Attempt to allocate zero bytes, allocating 1 byte")); 225 Size = 1; 226 } 227 228 Allocation = AcpiOsAllocateZeroed ( 229 Size + sizeof (ACPI_DEBUG_MEM_HEADER)); 230 if (!Allocation) 231 { 232 /* Report allocation error */ 233 234 ACPI_ERROR ((Module, Line, 235 "Could not allocate size %u", (UINT32) Size)); 236 return (NULL); 237 } 238 239 Status = AcpiUtTrackAllocation (Allocation, Size, 240 ACPI_MEM_CALLOC, Component, Module, Line); 241 if (ACPI_FAILURE (Status)) 242 { 243 AcpiOsFree (Allocation); 244 return (NULL); 245 } 246 247 AcpiGbl_GlobalList->TotalAllocated++; 248 AcpiGbl_GlobalList->TotalSize += (UINT32) Size; 249 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; 250 251 if (AcpiGbl_GlobalList->CurrentTotalSize > 252 AcpiGbl_GlobalList->MaxOccupied) 253 { 254 AcpiGbl_GlobalList->MaxOccupied = 255 AcpiGbl_GlobalList->CurrentTotalSize; 256 } 257 258 return ((void *) &Allocation->UserSpace); 259 } 260 261 262 /******************************************************************************* 263 * 264 * FUNCTION: AcpiUtFreeAndTrack 265 * 266 * PARAMETERS: Allocation - Address of the memory to deallocate 267 * Component - Component type of caller 268 * Module - Source file name of caller 269 * Line - Line number of caller 270 * 271 * RETURN: None 272 * 273 * DESCRIPTION: Frees the memory at Allocation 274 * 275 ******************************************************************************/ 276 277 void 278 AcpiUtFreeAndTrack ( 279 void *Allocation, 280 UINT32 Component, 281 const char *Module, 282 UINT32 Line) 283 { 284 ACPI_DEBUG_MEM_BLOCK *DebugBlock; 285 ACPI_STATUS Status; 286 287 288 ACPI_FUNCTION_TRACE_PTR (UtFree, Allocation); 289 290 291 if (NULL == Allocation) 292 { 293 ACPI_ERROR ((Module, Line, 294 "Attempt to delete a NULL address")); 295 296 return_VOID; 297 } 298 299 DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK, 300 (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER))); 301 302 AcpiGbl_GlobalList->TotalFreed++; 303 AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size; 304 305 Status = AcpiUtRemoveAllocation (DebugBlock, Component, Module, Line); 306 if (ACPI_FAILURE (Status)) 307 { 308 ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory")); 309 } 310 311 AcpiOsFree (DebugBlock); 312 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n", 313 Allocation, DebugBlock)); 314 return_VOID; 315 } 316 317 318 /******************************************************************************* 319 * 320 * FUNCTION: AcpiUtFindAllocation 321 * 322 * PARAMETERS: Allocation - Address of allocated memory 323 * 324 * RETURN: Three cases: 325 * 1) List is empty, NULL is returned. 326 * 2) Element was found. Returns Allocation parameter. 327 * 3) Element was not found. Returns position where it should be 328 * inserted into the list. 329 * 330 * DESCRIPTION: Searches for an element in the global allocation tracking list. 331 * If the element is not found, returns the location within the 332 * list where the element should be inserted. 333 * 334 * Note: The list is ordered by larger-to-smaller addresses. 335 * 336 * This global list is used to detect memory leaks in ACPICA as 337 * well as other issues such as an attempt to release the same 338 * internal object more than once. Although expensive as far 339 * as cpu time, this list is much more helpful for finding these 340 * types of issues than using memory leak detectors outside of 341 * the ACPICA code. 342 * 343 ******************************************************************************/ 344 345 static ACPI_DEBUG_MEM_BLOCK * 346 AcpiUtFindAllocation ( 347 ACPI_DEBUG_MEM_BLOCK *Allocation) 348 { 349 ACPI_DEBUG_MEM_BLOCK *Element; 350 351 352 Element = AcpiGbl_GlobalList->ListHead; 353 if (!Element) 354 { 355 return (NULL); 356 } 357 358 /* 359 * Search for the address. 360 * 361 * Note: List is ordered by larger-to-smaller addresses, on the 362 * assumption that a new allocation usually has a larger address 363 * than previous allocations. 364 */ 365 while (Element > Allocation) 366 { 367 /* Check for end-of-list */ 368 369 if (!Element->Next) 370 { 371 return (Element); 372 } 373 374 Element = Element->Next; 375 } 376 377 if (Element == Allocation) 378 { 379 return (Element); 380 } 381 382 return (Element->Previous); 383 } 384 385 386 /******************************************************************************* 387 * 388 * FUNCTION: AcpiUtTrackAllocation 389 * 390 * PARAMETERS: Allocation - Address of allocated memory 391 * Size - Size of the allocation 392 * AllocType - MEM_MALLOC or MEM_CALLOC 393 * Component - Component type of caller 394 * Module - Source file name of caller 395 * Line - Line number of caller 396 * 397 * RETURN: Status 398 * 399 * DESCRIPTION: Inserts an element into the global allocation tracking list. 400 * 401 ******************************************************************************/ 402 403 static ACPI_STATUS 404 AcpiUtTrackAllocation ( 405 ACPI_DEBUG_MEM_BLOCK *Allocation, 406 ACPI_SIZE Size, 407 UINT8 AllocType, 408 UINT32 Component, 409 const char *Module, 410 UINT32 Line) 411 { 412 ACPI_MEMORY_LIST *MemList; 413 ACPI_DEBUG_MEM_BLOCK *Element; 414 ACPI_STATUS Status = AE_OK; 415 416 417 ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation); 418 419 420 if (AcpiGbl_DisableMemTracking) 421 { 422 return_ACPI_STATUS (AE_OK); 423 } 424 425 MemList = AcpiGbl_GlobalList; 426 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 427 if (ACPI_FAILURE (Status)) 428 { 429 return_ACPI_STATUS (Status); 430 } 431 432 /* 433 * Search the global list for this address to make sure it is not 434 * already present. This will catch several kinds of problems. 435 */ 436 Element = AcpiUtFindAllocation (Allocation); 437 if (Element == Allocation) 438 { 439 ACPI_ERROR ((AE_INFO, 440 "UtTrackAllocation: Allocation (%p) already present in global list!", 441 Allocation)); 442 goto UnlockAndExit; 443 } 444 445 /* Fill in the instance data */ 446 447 Allocation->Size = (UINT32) Size; 448 Allocation->AllocType = AllocType; 449 Allocation->Component = Component; 450 Allocation->Line = Line; 451 452 AcpiUtSafeStrncpy (Allocation->Module, (char *) Module, ACPI_MAX_MODULE_NAME); 453 454 if (!Element) 455 { 456 /* Insert at list head */ 457 458 if (MemList->ListHead) 459 { 460 ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = 461 Allocation; 462 } 463 464 Allocation->Next = MemList->ListHead; 465 Allocation->Previous = NULL; 466 467 MemList->ListHead = Allocation; 468 } 469 else 470 { 471 /* Insert after element */ 472 473 Allocation->Next = Element->Next; 474 Allocation->Previous = Element; 475 476 if (Element->Next) 477 { 478 (Element->Next)->Previous = Allocation; 479 } 480 481 Element->Next = Allocation; 482 } 483 484 485 UnlockAndExit: 486 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 487 return_ACPI_STATUS (Status); 488 } 489 490 491 /******************************************************************************* 492 * 493 * FUNCTION: AcpiUtRemoveAllocation 494 * 495 * PARAMETERS: Allocation - Address of allocated memory 496 * Component - Component type of caller 497 * Module - Source file name of caller 498 * Line - Line number of caller 499 * 500 * RETURN: Status 501 * 502 * DESCRIPTION: Deletes an element from the global allocation tracking list. 503 * 504 ******************************************************************************/ 505 506 static ACPI_STATUS 507 AcpiUtRemoveAllocation ( 508 ACPI_DEBUG_MEM_BLOCK *Allocation, 509 UINT32 Component, 510 const char *Module, 511 UINT32 Line) 512 { 513 ACPI_MEMORY_LIST *MemList; 514 ACPI_STATUS Status; 515 516 517 ACPI_FUNCTION_NAME (UtRemoveAllocation); 518 519 520 if (AcpiGbl_DisableMemTracking) 521 { 522 return (AE_OK); 523 } 524 525 MemList = AcpiGbl_GlobalList; 526 if (NULL == MemList->ListHead) 527 { 528 /* No allocations! */ 529 530 ACPI_ERROR ((Module, Line, 531 "Empty allocation list, nothing to free!")); 532 533 return (AE_OK); 534 } 535 536 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 537 if (ACPI_FAILURE (Status)) 538 { 539 return (Status); 540 } 541 542 /* Unlink */ 543 544 if (Allocation->Previous) 545 { 546 (Allocation->Previous)->Next = Allocation->Next; 547 } 548 else 549 { 550 MemList->ListHead = Allocation->Next; 551 } 552 553 if (Allocation->Next) 554 { 555 (Allocation->Next)->Previous = Allocation->Previous; 556 } 557 558 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n", 559 &Allocation->UserSpace, Allocation->Size)); 560 561 /* Mark the segment as deleted */ 562 563 memset (&Allocation->UserSpace, 0xEA, Allocation->Size); 564 565 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 566 return (Status); 567 } 568 569 570 /******************************************************************************* 571 * 572 * FUNCTION: AcpiUtDumpAllocationInfo 573 * 574 * PARAMETERS: None 575 * 576 * RETURN: None 577 * 578 * DESCRIPTION: Print some info about the outstanding allocations. 579 * 580 ******************************************************************************/ 581 582 void 583 AcpiUtDumpAllocationInfo ( 584 void) 585 { 586 /* 587 ACPI_MEMORY_LIST *MemList; 588 */ 589 590 ACPI_FUNCTION_TRACE (UtDumpAllocationInfo); 591 592 /* 593 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 594 ("%30s: %4d (%3d Kb)\n", "Current allocations", 595 MemList->CurrentCount, 596 ROUND_UP_TO_1K (MemList->CurrentSize))); 597 598 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 599 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 600 MemList->MaxConcurrentCount, 601 ROUND_UP_TO_1K (MemList->MaxConcurrentSize))); 602 603 604 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 605 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 606 RunningObjectCount, 607 ROUND_UP_TO_1K (RunningObjectSize))); 608 609 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 610 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 611 RunningAllocCount, 612 ROUND_UP_TO_1K (RunningAllocSize))); 613 614 615 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 616 ("%30s: %4d (%3d Kb)\n", "Current Nodes", 617 AcpiGbl_CurrentNodeCount, 618 ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize))); 619 620 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 621 ("%30s: %4d (%3d Kb)\n", "Max Nodes", 622 AcpiGbl_MaxConcurrentNodeCount, 623 ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount * 624 sizeof (ACPI_NAMESPACE_NODE))))); 625 */ 626 return_VOID; 627 } 628 629 630 /******************************************************************************* 631 * 632 * FUNCTION: AcpiUtDumpAllocations 633 * 634 * PARAMETERS: Component - Component(s) to dump info for. 635 * Module - Module to dump info for. NULL means all. 636 * 637 * RETURN: None 638 * 639 * DESCRIPTION: Print a list of all outstanding allocations. 640 * 641 ******************************************************************************/ 642 643 void 644 AcpiUtDumpAllocations ( 645 UINT32 Component, 646 const char *Module) 647 { 648 ACPI_DEBUG_MEM_BLOCK *Element; 649 ACPI_DESCRIPTOR *Descriptor; 650 UINT32 NumOutstanding = 0; 651 UINT8 DescriptorType; 652 653 654 ACPI_FUNCTION_TRACE (UtDumpAllocations); 655 656 657 if (AcpiGbl_DisableMemTracking) 658 { 659 return_VOID; 660 } 661 662 /* 663 * Walk the allocation list. 664 */ 665 if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY))) 666 { 667 return_VOID; 668 } 669 670 if (!AcpiGbl_GlobalList) 671 { 672 goto Exit; 673 } 674 675 Element = AcpiGbl_GlobalList->ListHead; 676 while (Element) 677 { 678 if ((Element->Component & Component) && 679 ((Module == NULL) || (0 == strcmp (Module, Element->Module)))) 680 { 681 Descriptor = ACPI_CAST_PTR ( 682 ACPI_DESCRIPTOR, &Element->UserSpace); 683 684 if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR)) 685 { 686 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%4.4u " 687 "[Not a Descriptor - too small]\n", 688 Descriptor, Element->Size, Element->Module, 689 Element->Line); 690 } 691 else 692 { 693 /* Ignore allocated objects that are in a cache */ 694 695 if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != 696 ACPI_DESC_TYPE_CACHED) 697 { 698 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%4.4u [%s] ", 699 Descriptor, Element->Size, Element->Module, 700 Element->Line, AcpiUtGetDescriptorName (Descriptor)); 701 702 /* Optional object hex dump */ 703 704 if (AcpiGbl_VerboseLeakDump) 705 { 706 AcpiOsPrintf ("\n"); 707 AcpiUtDumpBuffer ((UINT8 *) Descriptor, Element->Size, 708 DB_BYTE_DISPLAY, 0); 709 } 710 711 /* Validate the descriptor type using Type field and length */ 712 713 DescriptorType = 0; /* Not a valid descriptor type */ 714 715 switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor)) 716 { 717 case ACPI_DESC_TYPE_OPERAND: 718 719 if (Element->Size == sizeof (ACPI_OPERAND_OBJECT)) 720 { 721 DescriptorType = ACPI_DESC_TYPE_OPERAND; 722 } 723 break; 724 725 case ACPI_DESC_TYPE_PARSER: 726 727 if (Element->Size == sizeof (ACPI_PARSE_OBJECT)) 728 { 729 DescriptorType = ACPI_DESC_TYPE_PARSER; 730 } 731 break; 732 733 case ACPI_DESC_TYPE_NAMED: 734 735 if (Element->Size == sizeof (ACPI_NAMESPACE_NODE)) 736 { 737 DescriptorType = ACPI_DESC_TYPE_NAMED; 738 } 739 break; 740 741 default: 742 743 break; 744 } 745 746 /* Display additional info for the major descriptor types */ 747 748 switch (DescriptorType) 749 { 750 case ACPI_DESC_TYPE_OPERAND: 751 752 AcpiOsPrintf ("%12.12s RefCount 0x%04X\n", 753 AcpiUtGetTypeName (Descriptor->Object.Common.Type), 754 Descriptor->Object.Common.ReferenceCount); 755 break; 756 757 case ACPI_DESC_TYPE_PARSER: 758 759 AcpiOsPrintf ("AmlOpcode 0x%04X\n", 760 Descriptor->Op.Asl.AmlOpcode); 761 break; 762 763 case ACPI_DESC_TYPE_NAMED: 764 765 AcpiOsPrintf ("%4.4s\n", 766 AcpiUtGetNodeName (&Descriptor->Node)); 767 break; 768 769 default: 770 771 AcpiOsPrintf ( "\n"); 772 break; 773 } 774 } 775 } 776 777 NumOutstanding++; 778 } 779 780 Element = Element->Next; 781 } 782 783 Exit: 784 (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 785 786 /* Print summary */ 787 788 if (!NumOutstanding) 789 { 790 ACPI_INFO (("No outstanding allocations")); 791 } 792 else 793 { 794 ACPI_ERROR ((AE_INFO, "%u (0x%X) Outstanding cache allocations", 795 NumOutstanding, NumOutstanding)); 796 } 797 798 return_VOID; 799 } 800 801 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ 802