utalloc.c revision 151937
1/****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 4 * $Revision: 1.149 $ 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117#define __UTALLOC_C__ 118 119#include <contrib/dev/acpica/acpi.h> 120 121#define _COMPONENT ACPI_UTILITIES 122 ACPI_MODULE_NAME ("utalloc") 123 124/* Local prototypes */ 125 126static ACPI_DEBUG_MEM_BLOCK * 127AcpiUtFindAllocation ( 128 void *Allocation); 129 130static ACPI_STATUS 131AcpiUtTrackAllocation ( 132 ACPI_DEBUG_MEM_BLOCK *Address, 133 ACPI_SIZE Size, 134 UINT8 AllocType, 135 UINT32 Component, 136 char *Module, 137 UINT32 Line); 138 139static ACPI_STATUS 140AcpiUtRemoveAllocation ( 141 ACPI_DEBUG_MEM_BLOCK *Address, 142 UINT32 Component, 143 char *Module, 144 UINT32 Line); 145 146#ifdef ACPI_DBG_TRACK_ALLOCATIONS 147static ACPI_STATUS 148AcpiUtCreateList ( 149 char *ListName, 150 UINT16 ObjectSize, 151 ACPI_MEMORY_LIST **ReturnCache); 152#endif 153 154 155/******************************************************************************* 156 * 157 * FUNCTION: AcpiUtCreateCaches 158 * 159 * PARAMETERS: None 160 * 161 * RETURN: Status 162 * 163 * DESCRIPTION: Create all local caches 164 * 165 ******************************************************************************/ 166 167ACPI_STATUS 168AcpiUtCreateCaches ( 169 void) 170{ 171 ACPI_STATUS Status; 172 173 174#ifdef ACPI_DBG_TRACK_ALLOCATIONS 175 176 /* Memory allocation lists */ 177 178 Status = AcpiUtCreateList ("Acpi-Global", 0, 179 &AcpiGbl_GlobalList); 180 if (ACPI_FAILURE (Status)) 181 { 182 return (Status); 183 } 184 185 Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 186 &AcpiGbl_NsNodeList); 187 if (ACPI_FAILURE (Status)) 188 { 189 return (Status); 190 } 191#endif 192 193 /* Object Caches, for frequently used objects */ 194 195 Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE), 196 ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache); 197 if (ACPI_FAILURE (Status)) 198 { 199 return (Status); 200 } 201 202 Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON), 203 ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache); 204 if (ACPI_FAILURE (Status)) 205 { 206 return (Status); 207 } 208 209 Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED), 210 ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache); 211 if (ACPI_FAILURE (Status)) 212 { 213 return (Status); 214 } 215 216 Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT), 217 ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache); 218 if (ACPI_FAILURE (Status)) 219 { 220 return (Status); 221 } 222 223 return (AE_OK); 224} 225 226 227/******************************************************************************* 228 * 229 * FUNCTION: AcpiUtDeleteCaches 230 * 231 * PARAMETERS: None 232 * 233 * RETURN: Status 234 * 235 * DESCRIPTION: Purge and delete all local caches 236 * 237 ******************************************************************************/ 238 239ACPI_STATUS 240AcpiUtDeleteCaches ( 241 void) 242{ 243 244 (void) AcpiOsDeleteCache (AcpiGbl_StateCache); 245 AcpiGbl_StateCache = NULL; 246 247 (void) AcpiOsDeleteCache (AcpiGbl_OperandCache); 248 AcpiGbl_OperandCache = NULL; 249 250 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache); 251 AcpiGbl_PsNodeCache = NULL; 252 253 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache); 254 AcpiGbl_PsNodeExtCache = NULL; 255 256 return (AE_OK); 257} 258 259 260/******************************************************************************* 261 * 262 * FUNCTION: AcpiUtValidateBuffer 263 * 264 * PARAMETERS: Buffer - Buffer descriptor to be validated 265 * 266 * RETURN: Status 267 * 268 * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER 269 * 270 ******************************************************************************/ 271 272ACPI_STATUS 273AcpiUtValidateBuffer ( 274 ACPI_BUFFER *Buffer) 275{ 276 277 /* Obviously, the structure pointer must be valid */ 278 279 if (!Buffer) 280 { 281 return (AE_BAD_PARAMETER); 282 } 283 284 /* Special semantics for the length */ 285 286 if ((Buffer->Length == ACPI_NO_BUFFER) || 287 (Buffer->Length == ACPI_ALLOCATE_BUFFER) || 288 (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER)) 289 { 290 return (AE_OK); 291 } 292 293 /* Length is valid, the buffer pointer must be also */ 294 295 if (!Buffer->Pointer) 296 { 297 return (AE_BAD_PARAMETER); 298 } 299 300 return (AE_OK); 301} 302 303 304/******************************************************************************* 305 * 306 * FUNCTION: AcpiUtInitializeBuffer 307 * 308 * PARAMETERS: Buffer - Buffer to be validated 309 * RequiredLength - Length needed 310 * 311 * RETURN: Status 312 * 313 * DESCRIPTION: Validate that the buffer is of the required length or 314 * allocate a new buffer. Returned buffer is always zeroed. 315 * 316 ******************************************************************************/ 317 318ACPI_STATUS 319AcpiUtInitializeBuffer ( 320 ACPI_BUFFER *Buffer, 321 ACPI_SIZE RequiredLength) 322{ 323 ACPI_STATUS Status = AE_OK; 324 325 326 switch (Buffer->Length) 327 { 328 case ACPI_NO_BUFFER: 329 330 /* Set the exception and returned the required length */ 331 332 Status = AE_BUFFER_OVERFLOW; 333 break; 334 335 336 case ACPI_ALLOCATE_BUFFER: 337 338 /* Allocate a new buffer */ 339 340 Buffer->Pointer = AcpiOsAllocate (RequiredLength); 341 if (!Buffer->Pointer) 342 { 343 return (AE_NO_MEMORY); 344 } 345 346 /* Clear the buffer */ 347 348 ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); 349 break; 350 351 352 case ACPI_ALLOCATE_LOCAL_BUFFER: 353 354 /* Allocate a new buffer with local interface to allow tracking */ 355 356 Buffer->Pointer = ACPI_MEM_CALLOCATE (RequiredLength); 357 if (!Buffer->Pointer) 358 { 359 return (AE_NO_MEMORY); 360 } 361 break; 362 363 364 default: 365 366 /* Existing buffer: Validate the size of the buffer */ 367 368 if (Buffer->Length < RequiredLength) 369 { 370 Status = AE_BUFFER_OVERFLOW; 371 break; 372 } 373 374 /* Clear the buffer */ 375 376 ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); 377 break; 378 } 379 380 Buffer->Length = RequiredLength; 381 return (Status); 382} 383 384 385/******************************************************************************* 386 * 387 * FUNCTION: AcpiUtAllocate 388 * 389 * PARAMETERS: Size - Size of the allocation 390 * Component - Component type of caller 391 * Module - Source file name of caller 392 * Line - Line number of caller 393 * 394 * RETURN: Address of the allocated memory on success, NULL on failure. 395 * 396 * DESCRIPTION: The subsystem's equivalent of malloc. 397 * 398 ******************************************************************************/ 399 400void * 401AcpiUtAllocate ( 402 ACPI_SIZE Size, 403 UINT32 Component, 404 char *Module, 405 UINT32 Line) 406{ 407 void *Allocation; 408 409 410 ACPI_FUNCTION_TRACE_U32 ("UtAllocate", Size); 411 412 413 /* Check for an inadvertent size of zero bytes */ 414 415 if (!Size) 416 { 417 _ACPI_REPORT_ERROR (Module, Line, Component, 418 ("UtAllocate: Attempt to allocate zero bytes, allocating 1 byte\n")); 419 Size = 1; 420 } 421 422 Allocation = AcpiOsAllocate (Size); 423 if (!Allocation) 424 { 425 /* Report allocation error */ 426 427 _ACPI_REPORT_ERROR (Module, Line, Component, 428 ("UtAllocate: Could not allocate size %X\n", (UINT32) Size)); 429 430 return_PTR (NULL); 431 } 432 433 return_PTR (Allocation); 434} 435 436 437/******************************************************************************* 438 * 439 * FUNCTION: AcpiUtCallocate 440 * 441 * PARAMETERS: Size - Size of the allocation 442 * Component - Component type of caller 443 * Module - Source file name of caller 444 * Line - Line number of caller 445 * 446 * RETURN: Address of the allocated memory on success, NULL on failure. 447 * 448 * DESCRIPTION: Subsystem equivalent of calloc. 449 * 450 ******************************************************************************/ 451 452void * 453AcpiUtCallocate ( 454 ACPI_SIZE Size, 455 UINT32 Component, 456 char *Module, 457 UINT32 Line) 458{ 459 void *Allocation; 460 461 462 ACPI_FUNCTION_TRACE_U32 ("UtCallocate", Size); 463 464 465 /* Check for an inadvertent size of zero bytes */ 466 467 if (!Size) 468 { 469 _ACPI_REPORT_ERROR (Module, Line, Component, 470 ("UtCallocate: Attempt to allocate zero bytes, allocating 1 byte\n")); 471 Size = 1; 472 } 473 474 Allocation = AcpiOsAllocate (Size); 475 if (!Allocation) 476 { 477 /* Report allocation error */ 478 479 _ACPI_REPORT_ERROR (Module, Line, Component, 480 ("UtCallocate: Could not allocate size %X\n", (UINT32) Size)); 481 return_PTR (NULL); 482 } 483 484 /* Clear the memory block */ 485 486 ACPI_MEMSET (Allocation, 0, Size); 487 return_PTR (Allocation); 488} 489 490 491#ifdef ACPI_DBG_TRACK_ALLOCATIONS 492/* 493 * These procedures are used for tracking memory leaks in the subsystem, and 494 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. 495 * 496 * Each memory allocation is tracked via a doubly linked list. Each 497 * element contains the caller's component, module name, function name, and 498 * line number. AcpiUtAllocate and AcpiUtCallocate call 499 * AcpiUtTrackAllocation to add an element to the list; deletion 500 * occurs in the body of AcpiUtFree. 501 */ 502 503/******************************************************************************* 504 * 505 * FUNCTION: AcpiUtCreateList 506 * 507 * PARAMETERS: CacheName - Ascii name for the cache 508 * ObjectSize - Size of each cached object 509 * ReturnCache - Where the new cache object is returned 510 * 511 * RETURN: Status 512 * 513 * DESCRIPTION: Create a local memory list for tracking purposed 514 * 515 ******************************************************************************/ 516 517static ACPI_STATUS 518AcpiUtCreateList ( 519 char *ListName, 520 UINT16 ObjectSize, 521 ACPI_MEMORY_LIST **ReturnCache) 522{ 523 ACPI_MEMORY_LIST *Cache; 524 525 526 Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST)); 527 if (!Cache) 528 { 529 return (AE_NO_MEMORY); 530 } 531 532 ACPI_MEMSET (Cache, 0, sizeof (ACPI_MEMORY_LIST)); 533 534 Cache->ListName = ListName; 535 Cache->ObjectSize = ObjectSize; 536 537 *ReturnCache = Cache; 538 return (AE_OK); 539} 540 541 542/******************************************************************************* 543 * 544 * FUNCTION: AcpiUtAllocateAndTrack 545 * 546 * PARAMETERS: Size - Size of the allocation 547 * Component - Component type of caller 548 * Module - Source file name of caller 549 * Line - Line number of caller 550 * 551 * RETURN: Address of the allocated memory on success, NULL on failure. 552 * 553 * DESCRIPTION: The subsystem's equivalent of malloc. 554 * 555 ******************************************************************************/ 556 557void * 558AcpiUtAllocateAndTrack ( 559 ACPI_SIZE Size, 560 UINT32 Component, 561 char *Module, 562 UINT32 Line) 563{ 564 ACPI_DEBUG_MEM_BLOCK *Allocation; 565 ACPI_STATUS Status; 566 567 568 Allocation = AcpiUtAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER), 569 Component, Module, Line); 570 if (!Allocation) 571 { 572 return (NULL); 573 } 574 575 Status = AcpiUtTrackAllocation (Allocation, Size, 576 ACPI_MEM_MALLOC, Component, Module, Line); 577 if (ACPI_FAILURE (Status)) 578 { 579 AcpiOsFree (Allocation); 580 return (NULL); 581 } 582 583 AcpiGbl_GlobalList->TotalAllocated++; 584 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; 585 586 return ((void *) &Allocation->UserSpace); 587} 588 589 590/******************************************************************************* 591 * 592 * FUNCTION: AcpiUtCallocateAndTrack 593 * 594 * PARAMETERS: Size - Size of the allocation 595 * Component - Component type of caller 596 * Module - Source file name of caller 597 * Line - Line number of caller 598 * 599 * RETURN: Address of the allocated memory on success, NULL on failure. 600 * 601 * DESCRIPTION: Subsystem equivalent of calloc. 602 * 603 ******************************************************************************/ 604 605void * 606AcpiUtCallocateAndTrack ( 607 ACPI_SIZE Size, 608 UINT32 Component, 609 char *Module, 610 UINT32 Line) 611{ 612 ACPI_DEBUG_MEM_BLOCK *Allocation; 613 ACPI_STATUS Status; 614 615 616 Allocation = AcpiUtCallocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER), 617 Component, Module, Line); 618 if (!Allocation) 619 { 620 /* Report allocation error */ 621 622 _ACPI_REPORT_ERROR (Module, Line, Component, 623 ("UtCallocate: Could not allocate size %X\n", (UINT32) Size)); 624 return (NULL); 625 } 626 627 Status = AcpiUtTrackAllocation (Allocation, Size, 628 ACPI_MEM_CALLOC, Component, Module, Line); 629 if (ACPI_FAILURE (Status)) 630 { 631 AcpiOsFree (Allocation); 632 return (NULL); 633 } 634 635 AcpiGbl_GlobalList->TotalAllocated++; 636 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; 637 638 return ((void *) &Allocation->UserSpace); 639} 640 641 642/******************************************************************************* 643 * 644 * FUNCTION: AcpiUtFreeAndTrack 645 * 646 * PARAMETERS: Allocation - Address of the memory to deallocate 647 * Component - Component type of caller 648 * Module - Source file name of caller 649 * Line - Line number of caller 650 * 651 * RETURN: None 652 * 653 * DESCRIPTION: Frees the memory at Allocation 654 * 655 ******************************************************************************/ 656 657void 658AcpiUtFreeAndTrack ( 659 void *Allocation, 660 UINT32 Component, 661 char *Module, 662 UINT32 Line) 663{ 664 ACPI_DEBUG_MEM_BLOCK *DebugBlock; 665 ACPI_STATUS Status; 666 667 668 ACPI_FUNCTION_TRACE_PTR ("UtFree", Allocation); 669 670 671 if (NULL == Allocation) 672 { 673 _ACPI_REPORT_ERROR (Module, Line, Component, 674 ("AcpiUtFree: Attempt to delete a NULL address\n")); 675 676 return_VOID; 677 } 678 679 DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK, 680 (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER))); 681 682 AcpiGbl_GlobalList->TotalFreed++; 683 AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size; 684 685 Status = AcpiUtRemoveAllocation (DebugBlock, 686 Component, Module, Line); 687 if (ACPI_FAILURE (Status)) 688 { 689 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n", 690 AcpiFormatException (Status))); 691 } 692 693 AcpiOsFree (DebugBlock); 694 695 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Allocation)); 696 697 return_VOID; 698} 699 700 701/******************************************************************************* 702 * 703 * FUNCTION: AcpiUtFindAllocation 704 * 705 * PARAMETERS: Allocation - Address of allocated memory 706 * 707 * RETURN: A list element if found; NULL otherwise. 708 * 709 * DESCRIPTION: Searches for an element in the global allocation tracking list. 710 * 711 ******************************************************************************/ 712 713static ACPI_DEBUG_MEM_BLOCK * 714AcpiUtFindAllocation ( 715 void *Allocation) 716{ 717 ACPI_DEBUG_MEM_BLOCK *Element; 718 719 720 ACPI_FUNCTION_ENTRY (); 721 722 723 Element = AcpiGbl_GlobalList->ListHead; 724 725 /* Search for the address. */ 726 727 while (Element) 728 { 729 if (Element == Allocation) 730 { 731 return (Element); 732 } 733 734 Element = Element->Next; 735 } 736 737 return (NULL); 738} 739 740 741/******************************************************************************* 742 * 743 * FUNCTION: AcpiUtTrackAllocation 744 * 745 * PARAMETERS: Allocation - Address of allocated memory 746 * Size - Size of the allocation 747 * AllocType - MEM_MALLOC or MEM_CALLOC 748 * Component - Component type of caller 749 * Module - Source file name of caller 750 * Line - Line number of caller 751 * 752 * RETURN: None. 753 * 754 * DESCRIPTION: Inserts an element into the global allocation tracking list. 755 * 756 ******************************************************************************/ 757 758static ACPI_STATUS 759AcpiUtTrackAllocation ( 760 ACPI_DEBUG_MEM_BLOCK *Allocation, 761 ACPI_SIZE Size, 762 UINT8 AllocType, 763 UINT32 Component, 764 char *Module, 765 UINT32 Line) 766{ 767 ACPI_MEMORY_LIST *MemList; 768 ACPI_DEBUG_MEM_BLOCK *Element; 769 ACPI_STATUS Status = AE_OK; 770 771 772 ACPI_FUNCTION_TRACE_PTR ("UtTrackAllocation", Allocation); 773 774 775 MemList = AcpiGbl_GlobalList; 776 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 777 if (ACPI_FAILURE (Status)) 778 { 779 return_ACPI_STATUS (Status); 780 } 781 782 /* 783 * Search list for this address to make sure it is not already on the list. 784 * This will catch several kinds of problems. 785 */ 786 Element = AcpiUtFindAllocation (Allocation); 787 if (Element) 788 { 789 ACPI_REPORT_ERROR (( 790 "UtTrackAllocation: Allocation already present in list! (%p)\n", 791 Allocation)); 792 793 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", 794 Element, Allocation)); 795 796 goto UnlockAndExit; 797 } 798 799 /* Fill in the instance data. */ 800 801 Allocation->Size = (UINT32) Size; 802 Allocation->AllocType = AllocType; 803 Allocation->Component = Component; 804 Allocation->Line = Line; 805 806 ACPI_STRNCPY (Allocation->Module, Module, ACPI_MAX_MODULE_NAME); 807 Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0; 808 809 /* Insert at list head */ 810 811 if (MemList->ListHead) 812 { 813 ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Allocation; 814 } 815 816 Allocation->Next = MemList->ListHead; 817 Allocation->Previous = NULL; 818 819 MemList->ListHead = Allocation; 820 821 822UnlockAndExit: 823 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 824 return_ACPI_STATUS (Status); 825} 826 827 828/******************************************************************************* 829 * 830 * FUNCTION: AcpiUtRemoveAllocation 831 * 832 * PARAMETERS: Allocation - Address of allocated memory 833 * Component - Component type of caller 834 * Module - Source file name of caller 835 * Line - Line number of caller 836 * 837 * RETURN: 838 * 839 * DESCRIPTION: Deletes an element from the global allocation tracking list. 840 * 841 ******************************************************************************/ 842 843static ACPI_STATUS 844AcpiUtRemoveAllocation ( 845 ACPI_DEBUG_MEM_BLOCK *Allocation, 846 UINT32 Component, 847 char *Module, 848 UINT32 Line) 849{ 850 ACPI_MEMORY_LIST *MemList; 851 ACPI_STATUS Status; 852 853 854 ACPI_FUNCTION_TRACE ("UtRemoveAllocation"); 855 856 857 MemList = AcpiGbl_GlobalList; 858 if (NULL == MemList->ListHead) 859 { 860 /* No allocations! */ 861 862 _ACPI_REPORT_ERROR (Module, Line, Component, 863 ("UtRemoveAllocation: Empty allocation list, nothing to free!\n")); 864 865 return_ACPI_STATUS (AE_OK); 866 } 867 868 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 869 if (ACPI_FAILURE (Status)) 870 { 871 return_ACPI_STATUS (Status); 872 } 873 874 /* Unlink */ 875 876 if (Allocation->Previous) 877 { 878 (Allocation->Previous)->Next = Allocation->Next; 879 } 880 else 881 { 882 MemList->ListHead = Allocation->Next; 883 } 884 885 if (Allocation->Next) 886 { 887 (Allocation->Next)->Previous = Allocation->Previous; 888 } 889 890 /* Mark the segment as deleted */ 891 892 ACPI_MEMSET (&Allocation->UserSpace, 0xEA, Allocation->Size); 893 894 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", 895 Allocation->Size)); 896 897 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 898 return_ACPI_STATUS (Status); 899} 900 901 902/******************************************************************************* 903 * 904 * FUNCTION: AcpiUtDumpAllocationInfo 905 * 906 * PARAMETERS: 907 * 908 * RETURN: None 909 * 910 * DESCRIPTION: Print some info about the outstanding allocations. 911 * 912 ******************************************************************************/ 913 914void 915AcpiUtDumpAllocationInfo ( 916 void) 917{ 918/* 919 ACPI_MEMORY_LIST *MemList; 920*/ 921 922 ACPI_FUNCTION_TRACE ("UtDumpAllocationInfo"); 923 924/* 925 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 926 ("%30s: %4d (%3d Kb)\n", "Current allocations", 927 MemList->CurrentCount, 928 ROUND_UP_TO_1K (MemList->CurrentSize))); 929 930 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 931 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 932 MemList->MaxConcurrentCount, 933 ROUND_UP_TO_1K (MemList->MaxConcurrentSize))); 934 935 936 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 937 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 938 RunningObjectCount, 939 ROUND_UP_TO_1K (RunningObjectSize))); 940 941 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 942 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 943 RunningAllocCount, 944 ROUND_UP_TO_1K (RunningAllocSize))); 945 946 947 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 948 ("%30s: %4d (%3d Kb)\n", "Current Nodes", 949 AcpiGbl_CurrentNodeCount, 950 ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize))); 951 952 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 953 ("%30s: %4d (%3d Kb)\n", "Max Nodes", 954 AcpiGbl_MaxConcurrentNodeCount, 955 ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount * 956 sizeof (ACPI_NAMESPACE_NODE))))); 957*/ 958 return_VOID; 959} 960 961 962/******************************************************************************* 963 * 964 * FUNCTION: AcpiUtDumpAllocations 965 * 966 * PARAMETERS: Component - Component(s) to dump info for. 967 * Module - Module to dump info for. NULL means all. 968 * 969 * RETURN: None 970 * 971 * DESCRIPTION: Print a list of all outstanding allocations. 972 * 973 ******************************************************************************/ 974 975void 976AcpiUtDumpAllocations ( 977 UINT32 Component, 978 char *Module) 979{ 980 ACPI_DEBUG_MEM_BLOCK *Element; 981 ACPI_DESCRIPTOR *Descriptor; 982 UINT32 NumOutstanding = 0; 983 984 985 ACPI_FUNCTION_TRACE ("UtDumpAllocations"); 986 987 988 /* 989 * Walk the allocation list. 990 */ 991 if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY))) 992 { 993 return; 994 } 995 996 Element = AcpiGbl_GlobalList->ListHead; 997 while (Element) 998 { 999 if ((Element->Component & Component) && 1000 ((Module == NULL) || (0 == ACPI_STRCMP (Module, Element->Module)))) 1001 { 1002 /* Ignore allocated objects that are in a cache */ 1003 1004 Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace); 1005 if (Descriptor->DescriptorId != ACPI_DESC_TYPE_CACHED) 1006 { 1007 AcpiOsPrintf ("%p Len %04X %9.9s-%d [%s] ", 1008 Descriptor, Element->Size, Element->Module, 1009 Element->Line, AcpiUtGetDescriptorName (Descriptor)); 1010 1011 /* Most of the elements will be Operand objects. */ 1012 1013 switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor)) 1014 { 1015 case ACPI_DESC_TYPE_OPERAND: 1016 AcpiOsPrintf ("%12.12s R%hd", 1017 AcpiUtGetTypeName (Descriptor->Object.Common.Type), 1018 Descriptor->Object.Common.ReferenceCount); 1019 break; 1020 1021 case ACPI_DESC_TYPE_PARSER: 1022 AcpiOsPrintf ("AmlOpcode %04hX", 1023 Descriptor->Op.Asl.AmlOpcode); 1024 break; 1025 1026 case ACPI_DESC_TYPE_NAMED: 1027 AcpiOsPrintf ("%4.4s", 1028 AcpiUtGetNodeName (&Descriptor->Node)); 1029 break; 1030 1031 default: 1032 break; 1033 } 1034 1035 AcpiOsPrintf ( "\n"); 1036 NumOutstanding++; 1037 } 1038 } 1039 Element = Element->Next; 1040 } 1041 1042 (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 1043 1044 /* Print summary */ 1045 1046 if (!NumOutstanding) 1047 { 1048 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 1049 "No outstanding allocations\n")); 1050 } 1051 else 1052 { 1053 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 1054 "%d(%X) Outstanding allocations\n", 1055 NumOutstanding, NumOutstanding)); 1056 } 1057 1058 return_VOID; 1059} 1060 1061#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ 1062 1063