1 /****************************************************************************** 2 * 3 * Module Name: uttrack - Memory allocation tracking routines (debug only) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 (block %p)\n", 311 Allocation, DebugBlock)); 312 return_VOID; 313 } 314 315 316 /******************************************************************************* 317 * 318 * FUNCTION: AcpiUtFindAllocation 319 * 320 * PARAMETERS: Allocation - Address of allocated memory 321 * 322 * RETURN: Three cases: 323 * 1) List is empty, NULL is returned. 324 * 2) Element was found. Returns Allocation parameter. 325 * 3) Element was not found. Returns position where it should be 326 * inserted into the list. 327 * 328 * DESCRIPTION: Searches for an element in the global allocation tracking list. 329 * If the element is not found, returns the location within the 330 * list where the element should be inserted. 331 * 332 * Note: The list is ordered by larger-to-smaller addresses. 333 * 334 * This global list is used to detect memory leaks in ACPICA as 335 * well as other issues such as an attempt to release the same 336 * internal object more than once. Although expensive as far 337 * as cpu time, this list is much more helpful for finding these 338 * types of issues than using memory leak detectors outside of 339 * the ACPICA code. 340 * 341 ******************************************************************************/ 342 343 static ACPI_DEBUG_MEM_BLOCK * 344 AcpiUtFindAllocation ( 345 ACPI_DEBUG_MEM_BLOCK *Allocation) 346 { 347 ACPI_DEBUG_MEM_BLOCK *Element; 348 349 350 Element = AcpiGbl_GlobalList->ListHead; 351 if (!Element) 352 { 353 return (NULL); 354 } 355 356 /* 357 * Search for the address. 358 * 359 * Note: List is ordered by larger-to-smaller addresses, on the 360 * assumption that a new allocation usually has a larger address 361 * than previous allocations. 362 */ 363 while (Element > Allocation) 364 { 365 /* Check for end-of-list */ 366 367 if (!Element->Next) 368 { 369 return (Element); 370 } 371 372 Element = Element->Next; 373 } 374 375 if (Element == Allocation) 376 { 377 return (Element); 378 } 379 380 return (Element->Previous); 381 } 382 383 384 /******************************************************************************* 385 * 386 * FUNCTION: AcpiUtTrackAllocation 387 * 388 * PARAMETERS: Allocation - Address of allocated memory 389 * Size - Size of the allocation 390 * AllocType - MEM_MALLOC or MEM_CALLOC 391 * Component - Component type of caller 392 * Module - Source file name of caller 393 * Line - Line number of caller 394 * 395 * RETURN: Status 396 * 397 * DESCRIPTION: Inserts an element into the global allocation tracking list. 398 * 399 ******************************************************************************/ 400 401 static ACPI_STATUS 402 AcpiUtTrackAllocation ( 403 ACPI_DEBUG_MEM_BLOCK *Allocation, 404 ACPI_SIZE Size, 405 UINT8 AllocType, 406 UINT32 Component, 407 const char *Module, 408 UINT32 Line) 409 { 410 ACPI_MEMORY_LIST *MemList; 411 ACPI_DEBUG_MEM_BLOCK *Element; 412 ACPI_STATUS Status = AE_OK; 413 414 415 ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation); 416 417 418 if (AcpiGbl_DisableMemTracking) 419 { 420 return_ACPI_STATUS (AE_OK); 421 } 422 423 MemList = AcpiGbl_GlobalList; 424 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 425 if (ACPI_FAILURE (Status)) 426 { 427 return_ACPI_STATUS (Status); 428 } 429 430 /* 431 * Search the global list for this address to make sure it is not 432 * already present. This will catch several kinds of problems. 433 */ 434 Element = AcpiUtFindAllocation (Allocation); 435 if (Element == Allocation) 436 { 437 ACPI_ERROR ((AE_INFO, 438 "UtTrackAllocation: Allocation (%p) already present in global list!", 439 Allocation)); 440 goto UnlockAndExit; 441 } 442 443 /* Fill in the instance data */ 444 445 Allocation->Size = (UINT32) Size; 446 Allocation->AllocType = AllocType; 447 Allocation->Component = Component; 448 Allocation->Line = Line; 449 450 ACPI_STRNCPY (Allocation->Module, Module, ACPI_MAX_MODULE_NAME); 451 Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0; 452 453 if (!Element) 454 { 455 /* Insert at list head */ 456 457 if (MemList->ListHead) 458 { 459 ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Allocation; 460 } 461 462 Allocation->Next = MemList->ListHead; 463 Allocation->Previous = NULL; 464 465 MemList->ListHead = Allocation; 466 } 467 else 468 { 469 /* Insert after element */ 470 471 Allocation->Next = Element->Next; 472 Allocation->Previous = Element; 473 474 if (Element->Next) 475 { 476 (Element->Next)->Previous = Allocation; 477 } 478 479 Element->Next = Allocation; 480 } 481 482 483 UnlockAndExit: 484 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 485 return_ACPI_STATUS (Status); 486 } 487 488 489 /******************************************************************************* 490 * 491 * FUNCTION: AcpiUtRemoveAllocation 492 * 493 * PARAMETERS: Allocation - Address of allocated memory 494 * Component - Component type of caller 495 * Module - Source file name of caller 496 * Line - Line number of caller 497 * 498 * RETURN: Status 499 * 500 * DESCRIPTION: Deletes an element from the global allocation tracking list. 501 * 502 ******************************************************************************/ 503 504 static ACPI_STATUS 505 AcpiUtRemoveAllocation ( 506 ACPI_DEBUG_MEM_BLOCK *Allocation, 507 UINT32 Component, 508 const char *Module, 509 UINT32 Line) 510 { 511 ACPI_MEMORY_LIST *MemList; 512 ACPI_STATUS Status; 513 514 515 ACPI_FUNCTION_NAME (UtRemoveAllocation); 516 517 518 if (AcpiGbl_DisableMemTracking) 519 { 520 return (AE_OK); 521 } 522 523 MemList = AcpiGbl_GlobalList; 524 if (NULL == MemList->ListHead) 525 { 526 /* No allocations! */ 527 528 ACPI_ERROR ((Module, Line, 529 "Empty allocation list, nothing to free!")); 530 531 return (AE_OK); 532 } 533 534 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 535 if (ACPI_FAILURE (Status)) 536 { 537 return (Status); 538 } 539 540 /* Unlink */ 541 542 if (Allocation->Previous) 543 { 544 (Allocation->Previous)->Next = Allocation->Next; 545 } 546 else 547 { 548 MemList->ListHead = Allocation->Next; 549 } 550 551 if (Allocation->Next) 552 { 553 (Allocation->Next)->Previous = Allocation->Previous; 554 } 555 556 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n", 557 &Allocation->UserSpace, Allocation->Size)); 558 559 /* Mark the segment as deleted */ 560 561 ACPI_MEMSET (&Allocation->UserSpace, 0xEA, Allocation->Size); 562 563 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 564 return (Status); 565 } 566 567 568 /******************************************************************************* 569 * 570 * FUNCTION: AcpiUtDumpAllocationInfo 571 * 572 * PARAMETERS: None 573 * 574 * RETURN: None 575 * 576 * DESCRIPTION: Print some info about the outstanding allocations. 577 * 578 ******************************************************************************/ 579 580 void 581 AcpiUtDumpAllocationInfo ( 582 void) 583 { 584 /* 585 ACPI_MEMORY_LIST *MemList; 586 */ 587 588 ACPI_FUNCTION_TRACE (UtDumpAllocationInfo); 589 590 /* 591 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 592 ("%30s: %4d (%3d Kb)\n", "Current allocations", 593 MemList->CurrentCount, 594 ROUND_UP_TO_1K (MemList->CurrentSize))); 595 596 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 597 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 598 MemList->MaxConcurrentCount, 599 ROUND_UP_TO_1K (MemList->MaxConcurrentSize))); 600 601 602 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 603 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 604 RunningObjectCount, 605 ROUND_UP_TO_1K (RunningObjectSize))); 606 607 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 608 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 609 RunningAllocCount, 610 ROUND_UP_TO_1K (RunningAllocSize))); 611 612 613 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 614 ("%30s: %4d (%3d Kb)\n", "Current Nodes", 615 AcpiGbl_CurrentNodeCount, 616 ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize))); 617 618 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 619 ("%30s: %4d (%3d Kb)\n", "Max Nodes", 620 AcpiGbl_MaxConcurrentNodeCount, 621 ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount * 622 sizeof (ACPI_NAMESPACE_NODE))))); 623 */ 624 return_VOID; 625 } 626 627 628 /******************************************************************************* 629 * 630 * FUNCTION: AcpiUtDumpAllocations 631 * 632 * PARAMETERS: Component - Component(s) to dump info for. 633 * Module - Module to dump info for. NULL means all. 634 * 635 * RETURN: None 636 * 637 * DESCRIPTION: Print a list of all outstanding allocations. 638 * 639 ******************************************************************************/ 640 641 void 642 AcpiUtDumpAllocations ( 643 UINT32 Component, 644 const char *Module) 645 { 646 ACPI_DEBUG_MEM_BLOCK *Element; 647 ACPI_DESCRIPTOR *Descriptor; 648 UINT32 NumOutstanding = 0; 649 UINT8 DescriptorType; 650 651 652 ACPI_FUNCTION_TRACE (UtDumpAllocations); 653 654 655 if (AcpiGbl_DisableMemTracking) 656 { 657 return_VOID; 658 } 659 660 /* 661 * Walk the allocation list. 662 */ 663 if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY))) 664 { 665 return_VOID; 666 } 667 668 Element = AcpiGbl_GlobalList->ListHead; 669 while (Element) 670 { 671 if ((Element->Component & Component) && 672 ((Module == NULL) || (0 == ACPI_STRCMP (Module, Element->Module)))) 673 { 674 Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace); 675 676 if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR)) 677 { 678 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u " 679 "[Not a Descriptor - too small]\n", 680 Descriptor, Element->Size, Element->Module, 681 Element->Line); 682 } 683 else 684 { 685 /* Ignore allocated objects that are in a cache */ 686 687 if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != ACPI_DESC_TYPE_CACHED) 688 { 689 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ", 690 Descriptor, Element->Size, Element->Module, 691 Element->Line, AcpiUtGetDescriptorName (Descriptor)); 692 693 /* Validate the descriptor type using Type field and length */ 694 695 DescriptorType = 0; /* Not a valid descriptor type */ 696 697 switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor)) 698 { 699 case ACPI_DESC_TYPE_OPERAND: 700 701 if (Element->Size == sizeof (ACPI_OPERAND_OBJECT)) 702 { 703 DescriptorType = ACPI_DESC_TYPE_OPERAND; 704 } 705 break; 706 707 case ACPI_DESC_TYPE_PARSER: 708 709 if (Element->Size == sizeof (ACPI_PARSE_OBJECT)) 710 { 711 DescriptorType = ACPI_DESC_TYPE_PARSER; 712 } 713 break; 714 715 case ACPI_DESC_TYPE_NAMED: 716 717 if (Element->Size == sizeof (ACPI_NAMESPACE_NODE)) 718 { 719 DescriptorType = ACPI_DESC_TYPE_NAMED; 720 } 721 break; 722 723 default: 724 725 break; 726 } 727 728 /* Display additional info for the major descriptor types */ 729 730 switch (DescriptorType) 731 { 732 case ACPI_DESC_TYPE_OPERAND: 733 734 AcpiOsPrintf ("%12.12s RefCount 0x%04X\n", 735 AcpiUtGetTypeName (Descriptor->Object.Common.Type), 736 Descriptor->Object.Common.ReferenceCount); 737 break; 738 739 case ACPI_DESC_TYPE_PARSER: 740 741 AcpiOsPrintf ("AmlOpcode 0x%04hX\n", 742 Descriptor->Op.Asl.AmlOpcode); 743 break; 744 745 case ACPI_DESC_TYPE_NAMED: 746 747 AcpiOsPrintf ("%4.4s\n", 748 AcpiUtGetNodeName (&Descriptor->Node)); 749 break; 750 751 default: 752 753 AcpiOsPrintf ( "\n"); 754 break; 755 } 756 } 757 } 758 759 NumOutstanding++; 760 } 761 762 Element = Element->Next; 763 } 764 765 (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 766 767 /* Print summary */ 768 769 if (!NumOutstanding) 770 { 771 ACPI_INFO ((AE_INFO, "No outstanding allocations")); 772 } 773 else 774 { 775 ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations", 776 NumOutstanding, NumOutstanding)); 777 } 778 779 return_VOID; 780 } 781 782 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */