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