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