utalloc.c revision 67754
1/****************************************************************************** 2 * 3 * Module Name: cmalloc - local memory allocation routines 4 * $Revision: 76 $ 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 13 * 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 __CMALLOC_C__ 118 119#include "acpi.h" 120#include "acparser.h" 121#include "acinterp.h" 122#include "acnamesp.h" 123#include "acglobal.h" 124 125#define _COMPONENT MISCELLANEOUS 126 MODULE_NAME ("cmalloc") 127 128 129#ifdef ACPI_DEBUG 130/* 131 * Most of this code is for tracking memory leaks in the subsystem, and it 132 * gets compiled out when the ACPI_DEBUG flag is not set. 133 * Every memory allocation is kept track of in a doubly linked list. Each 134 * element contains the caller's component, module name, function name, and 135 * line number. _CmAllocate and _CmCallocate call AcpiCmAddElementToAllocList 136 * to add an element to the list; deletion occurs in the bosy of _CmFree. 137 */ 138 139 140/***************************************************************************** 141 * 142 * FUNCTION: AcpiCmSearchAllocList 143 * 144 * PARAMETERS: Address - Address of allocated memory 145 * 146 * RETURN: A list element if found; NULL otherwise. 147 * 148 * DESCRIPTION: Searches for an element in the global allocation tracking list. 149 * 150 ****************************************************************************/ 151 152ALLOCATION_INFO * 153AcpiCmSearchAllocList ( 154 void *Address) 155{ 156 ALLOCATION_INFO *Element = AcpiGbl_HeadAllocPtr; 157 158 159 /* Search for the address. */ 160 161 while (Element) 162 { 163 if (Element->Address == Address) 164 { 165 return (Element); 166 } 167 168 Element = Element->Next; 169 } 170 171 return (NULL); 172} 173 174 175/***************************************************************************** 176 * 177 * FUNCTION: AcpiCmAddElementToAllocList 178 * 179 * PARAMETERS: Address - Address of allocated memory 180 * Size - Size of the allocation 181 * AllocType - MEM_MALLOC or MEM_CALLOC 182 * Component - Component type of caller 183 * Module - Source file name of caller 184 * Line - Line number of caller 185 * 186 * RETURN: None. 187 * 188 * DESCRIPTION: Inserts an element into the global allocation tracking list. 189 * 190 ****************************************************************************/ 191 192ACPI_STATUS 193AcpiCmAddElementToAllocList ( 194 void *Address, 195 UINT32 Size, 196 UINT8 AllocType, 197 UINT32 Component, 198 NATIVE_CHAR *Module, 199 UINT32 Line) 200{ 201 ALLOCATION_INFO *Element; 202 ACPI_STATUS Status = AE_OK; 203 204 205 FUNCTION_TRACE_PTR ("CmAddElementToAllocList", Address); 206 207 208 AcpiCmAcquireMutex (ACPI_MTX_MEMORY); 209 210 /* Keep track of the running total of all allocations. */ 211 212 AcpiGbl_CurrentAllocCount++; 213 AcpiGbl_RunningAllocCount++; 214 215 if (AcpiGbl_MaxConcurrentAllocCount < AcpiGbl_CurrentAllocCount) 216 { 217 AcpiGbl_MaxConcurrentAllocCount = AcpiGbl_CurrentAllocCount; 218 } 219 220 AcpiGbl_CurrentAllocSize += Size; 221 AcpiGbl_RunningAllocSize += Size; 222 223 if (AcpiGbl_MaxConcurrentAllocSize < AcpiGbl_CurrentAllocSize) 224 { 225 AcpiGbl_MaxConcurrentAllocSize = AcpiGbl_CurrentAllocSize; 226 } 227 228 /* If the head pointer is null, create the first element and fill it in. */ 229 230 if (NULL == AcpiGbl_HeadAllocPtr) 231 { 232 AcpiGbl_HeadAllocPtr = 233 (ALLOCATION_INFO *) AcpiOsCallocate (sizeof (ALLOCATION_INFO)); 234 235 if (!AcpiGbl_HeadAllocPtr) 236 { 237 DEBUG_PRINT (ACPI_ERROR, 238 ("Could not allocate memory info block\n")); 239 Status = AE_NO_MEMORY; 240 goto UnlockAndExit; 241 } 242 243 AcpiGbl_TailAllocPtr = AcpiGbl_HeadAllocPtr; 244 } 245 246 else 247 { 248 AcpiGbl_TailAllocPtr->Next = 249 (ALLOCATION_INFO *) AcpiOsCallocate (sizeof (ALLOCATION_INFO)); 250 if (!AcpiGbl_TailAllocPtr->Next) 251 { 252 DEBUG_PRINT (ACPI_ERROR, 253 ("Could not allocate memory info block\n")); 254 Status = AE_NO_MEMORY; 255 goto UnlockAndExit; 256 } 257 258 /* error check */ 259 260 AcpiGbl_TailAllocPtr->Next->Previous = AcpiGbl_TailAllocPtr; 261 AcpiGbl_TailAllocPtr = AcpiGbl_TailAllocPtr->Next; 262 } 263 264 /* 265 * Search list for this address to make sure it is not already on the list. 266 * This will catch several kinds of problems. 267 */ 268 269 Element = AcpiCmSearchAllocList (Address); 270 if (Element) 271 { 272 REPORT_ERROR (("CmAddElementToAllocList: Address already present in list!\n")); 273 274 DEBUG_PRINT (ACPI_ERROR, ("Element %p Address %p\n", Element, Address)); 275 276 BREAKPOINT3; 277 } 278 279 /* Fill in the instance data. */ 280 281 AcpiGbl_TailAllocPtr->Address = Address; 282 AcpiGbl_TailAllocPtr->Size = Size; 283 AcpiGbl_TailAllocPtr->AllocType = AllocType; 284 AcpiGbl_TailAllocPtr->Component = Component; 285 AcpiGbl_TailAllocPtr->Line = Line; 286 287 STRNCPY (AcpiGbl_TailAllocPtr->Module, Module, MAX_MODULE_NAME); 288 289 290UnlockAndExit: 291 AcpiCmReleaseMutex (ACPI_MTX_MEMORY); 292 return_ACPI_STATUS (Status); 293} 294 295 296/***************************************************************************** 297 * 298 * FUNCTION: AcpiCmDeleteElementFromAllocList 299 * 300 * PARAMETERS: Address - Address of allocated memory 301 * Component - Component type of caller 302 * Module - Source file name of caller 303 * Line - Line number of caller 304 * 305 * RETURN: 306 * 307 * DESCRIPTION: Deletes an element from the global allocation tracking list. 308 * 309 ****************************************************************************/ 310 311void 312AcpiCmDeleteElementFromAllocList ( 313 void *Address, 314 UINT32 Component, 315 NATIVE_CHAR *Module, 316 UINT32 Line) 317{ 318 ALLOCATION_INFO *Element; 319 UINT32 *DwordPtr; 320 UINT32 DwordLen; 321 UINT32 Size; 322 UINT32 i; 323 324 325 FUNCTION_TRACE ("CmDeleteElementFromAllocList"); 326 327 if (NULL == AcpiGbl_HeadAllocPtr) 328 { 329 /* Boy we got problems. */ 330 331 _REPORT_ERROR (Module, Line, Component, 332 ("CmDeleteElementFromAllocList: Empty allocation list, nothing to free!\n")); 333 334 return_VOID; 335 } 336 337 338 AcpiCmAcquireMutex (ACPI_MTX_MEMORY); 339 340 /* Keep track of the amount of memory allocated. */ 341 342 Size = 0; 343 AcpiGbl_CurrentAllocCount--; 344 345 if (AcpiGbl_HeadAllocPtr == AcpiGbl_TailAllocPtr) 346 { 347 if (Address != AcpiGbl_HeadAllocPtr->Address) 348 { 349 _REPORT_ERROR (Module, Line, Component, 350 ("CmDeleteElementFromAllocList: Deleting non-allocated memory\n")); 351 352 goto Cleanup; 353 } 354 355 Size = AcpiGbl_HeadAllocPtr->Size; 356 357 AcpiOsFree (AcpiGbl_HeadAllocPtr); 358 AcpiGbl_HeadAllocPtr = NULL; 359 AcpiGbl_TailAllocPtr = NULL; 360 361 DEBUG_PRINT (TRACE_ALLOCATIONS, 362 ("_CmFree: Allocation list deleted. There are no outstanding allocations\n")); 363 364 goto Cleanup; 365 } 366 367 368 /* Search list for this address */ 369 370 Element = AcpiCmSearchAllocList (Address); 371 if (Element) 372 { 373 /* cases: head, tail, other */ 374 375 if (Element == AcpiGbl_HeadAllocPtr) 376 { 377 Element->Next->Previous = NULL; 378 AcpiGbl_HeadAllocPtr = Element->Next; 379 } 380 381 else 382 { 383 if (Element == AcpiGbl_TailAllocPtr) 384 { 385 Element->Previous->Next = NULL; 386 AcpiGbl_TailAllocPtr = Element->Previous; 387 } 388 389 else 390 { 391 Element->Previous->Next = Element->Next; 392 Element->Next->Previous = Element->Previous; 393 } 394 } 395 396 397 /* Mark the segment as deleted */ 398 399 if (Element->Size >= 4) 400 { 401 DwordLen = DIV_4 (Element->Size); 402 DwordPtr = (UINT32 *) Element->Address; 403 404 for (i = 0; i < DwordLen; i++) 405 { 406 DwordPtr[i] = 0x00DEAD00; 407 } 408 409 /* Set obj type, desc, and ref count fields to all ones */ 410 411 DwordPtr[0] = ACPI_UINT32_MAX; 412 if (Element->Size >= 8) 413 { 414 DwordPtr[1] = ACPI_UINT32_MAX; 415 } 416 } 417 418 Size = Element->Size; 419 420 MEMSET (Element, 0xEA, sizeof (ALLOCATION_INFO)); 421 422 423 if (Size == sizeof (ACPI_OPERAND_OBJECT)) 424 { 425 DEBUG_PRINT (TRACE_ALLOCATIONS, ("CmDelete: Freeing size 0x%X (ACPI_OPERAND_OBJECT)\n", Size)); 426 } 427 else 428 { 429 DEBUG_PRINT (TRACE_ALLOCATIONS, ("CmDelete: Freeing size 0x%X\n", Size)); 430 } 431 432 AcpiOsFree (Element); 433 } 434 435 else 436 { 437 _REPORT_ERROR (Module, Line, Component, 438 ("_CmFree: Entry not found in list\n")); 439 DEBUG_PRINT (ACPI_ERROR, 440 ("_CmFree: Entry %p was not found in allocation list\n", 441 Address)); 442 AcpiCmReleaseMutex (ACPI_MTX_MEMORY); 443 return_VOID; 444 } 445 446 447Cleanup: 448 449 AcpiGbl_CurrentAllocSize -= Size; 450 AcpiCmReleaseMutex (ACPI_MTX_MEMORY); 451 452 return_VOID; 453} 454 455 456/***************************************************************************** 457 * 458 * FUNCTION: AcpiCmDumpAllocationInfo 459 * 460 * PARAMETERS: 461 * 462 * RETURN: None 463 * 464 * DESCRIPTION: Print some info about the outstanding allocations. 465 * 466 ****************************************************************************/ 467 468void 469AcpiCmDumpAllocationInfo ( 470 void) 471{ 472 FUNCTION_TRACE ("CmDumpAllocationInfo"); 473 474 475 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 476 ("%30s: %4d (%3d Kb)\n", "Current allocations", 477 AcpiGbl_CurrentAllocCount, 478 (AcpiGbl_CurrentAllocSize + 1023) / 1024)); 479 480 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 481 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 482 AcpiGbl_MaxConcurrentAllocCount, 483 (AcpiGbl_MaxConcurrentAllocSize + 1023) / 1024)); 484 485 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 486 ("%30s: %4d (%3d Kb)\n", "Current Internal objects", 487 AcpiGbl_CurrentObjectCount, 488 (AcpiGbl_CurrentObjectSize + 1023) / 1024)); 489 490 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 491 ("%30s: %4d (%3d Kb)\n", "Max internal objects", 492 AcpiGbl_MaxConcurrentObjectCount, 493 (AcpiGbl_MaxConcurrentObjectSize + 1023) / 1024)); 494 495 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 496 ("%30s: %4d (%3d Kb)\n", "Current Nodes", 497 AcpiGbl_CurrentNodeCount, 498 (AcpiGbl_CurrentNodeSize + 1023) / 1024)); 499 500 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 501 ("%30s: %4d (%3d Kb)\n", "Max Nodes", 502 AcpiGbl_MaxConcurrentNodeCount, 503 ((AcpiGbl_MaxConcurrentNodeCount * sizeof (ACPI_NAMESPACE_NODE)) + 1023) / 1024)); 504 505 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 506 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 507 AcpiGbl_RunningObjectCount, 508 (AcpiGbl_RunningObjectSize + 1023) / 1024)); 509 510 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 511 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 512 AcpiGbl_RunningAllocCount, 513 (AcpiGbl_RunningAllocSize + 1023) / 1024)); 514 515 return_VOID; 516} 517 518 519/***************************************************************************** 520 * 521 * FUNCTION: AcpiCmDumpCurrentAllocations 522 * 523 * PARAMETERS: Component - Component(s) to dump info for. 524 * Module - Module to dump info for. NULL means all. 525 * 526 * RETURN: None 527 * 528 * DESCRIPTION: Print a list of all outstanding allocations. 529 * 530 ****************************************************************************/ 531 532void 533AcpiCmDumpCurrentAllocations ( 534 UINT32 Component, 535 NATIVE_CHAR *Module) 536{ 537 ALLOCATION_INFO *Element = AcpiGbl_HeadAllocPtr; 538 UINT32 i; 539 540 541 FUNCTION_TRACE ("CmDumpCurrentAllocations"); 542 543 544 if (Element == NULL) 545 { 546 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 547 ("No outstanding allocations.\n")); 548 return_VOID; 549 } 550 551 552 /* 553 * Walk the allocation list. 554 */ 555 556 AcpiCmAcquireMutex (ACPI_MTX_MEMORY); 557 558 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 559 ("Outstanding allocations:\n")); 560 561 for (i = 1; ; i++) /* Just a counter */ 562 { 563 if ((Element->Component & Component) && 564 ((Module == NULL) || (0 == STRCMP (Module, Element->Module)))) 565 { 566 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 567 ("%p Len %04lX %9.9s-%ld", 568 Element->Address, Element->Size, Element->Module, 569 Element->Line)); 570 571 /* Most of the elements will be internal objects. */ 572 573 switch (((ACPI_OPERAND_OBJECT *) 574 (Element->Address))->Common.DataType) 575 { 576 case ACPI_DESC_TYPE_INTERNAL: 577 DEBUG_PRINT_RAW (TRACE_ALLOCATIONS | TRACE_TABLES, 578 (" ObjType %s", 579 AcpiCmGetTypeName (((ACPI_OPERAND_OBJECT *)(Element->Address))->Common.Type))); 580 break; 581 582 case ACPI_DESC_TYPE_PARSER: 583 DEBUG_PRINT_RAW (TRACE_ALLOCATIONS | TRACE_TABLES, 584 (" ParseObj Opcode %04X", 585 ((ACPI_PARSE_OBJECT *)(Element->Address))->Opcode)); 586 break; 587 588 case ACPI_DESC_TYPE_NAMED: 589 DEBUG_PRINT_RAW (TRACE_ALLOCATIONS | TRACE_TABLES, 590 (" Node %4.4s", 591 &((ACPI_NAMESPACE_NODE *)(Element->Address))->Name)); 592 break; 593 594 case ACPI_DESC_TYPE_STATE: 595 DEBUG_PRINT_RAW (TRACE_ALLOCATIONS | TRACE_TABLES, 596 (" StateObj")); 597 break; 598 } 599 600 DEBUG_PRINT_RAW (TRACE_ALLOCATIONS | TRACE_TABLES, ("\n")); 601 } 602 603 if (Element->Next == NULL) 604 { 605 break; 606 } 607 608 Element = Element->Next; 609 } 610 611 AcpiCmReleaseMutex (ACPI_MTX_MEMORY); 612 613 DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 614 ("Total number of unfreed allocations = %d\n", i)); 615 616 return_VOID; 617} 618 619#endif /* Debug routines for memory leak detection */ 620 621 622/***************************************************************************** 623 * 624 * FUNCTION: _CmAllocate 625 * 626 * PARAMETERS: Size - Size of the allocation 627 * Component - Component type of caller 628 * Module - Source file name of caller 629 * Line - Line number of caller 630 * 631 * RETURN: Address of the allocated memory on success, NULL on failure. 632 * 633 * DESCRIPTION: The subsystem's equivalent of malloc. 634 * 635 ****************************************************************************/ 636 637void * 638_CmAllocate ( 639 UINT32 Size, 640 UINT32 Component, 641 NATIVE_CHAR *Module, 642 UINT32 Line) 643{ 644 void *Address = NULL; 645 DEBUG_EXEC (\ 646 ACPI_STATUS Status) 647 648 649 FUNCTION_TRACE_U32 ("_CmAllocate", Size); 650 651 652 /* Check for an inadvertent size of zero bytes */ 653 654 if (!Size) 655 { 656 _REPORT_ERROR (Module, Line, Component, 657 ("CmAllocate: Attempt to allocate zero bytes\n")); 658 Size = 1; 659 } 660 661 Address = AcpiOsAllocate (Size); 662 if (!Address) 663 { 664 /* Report allocation error */ 665 666 _REPORT_ERROR (Module, Line, Component, 667 ("CmAllocate: Could not allocate size 0x%x\n", Size)); 668 669 return_VALUE (NULL); 670 } 671 672#ifdef ACPI_DEBUG 673 Status = AcpiCmAddElementToAllocList (Address, Size, MEM_MALLOC, Component, 674 Module, Line); 675 if (ACPI_FAILURE (Status)) 676 { 677 AcpiOsFree (Address); 678 return_PTR (NULL); 679 } 680 681 DEBUG_PRINT (TRACE_ALLOCATIONS, 682 ("CmAllocate: %p Size 0x%x\n", Address, Size)); 683#endif 684 685 return_PTR (Address); 686} 687 688 689/***************************************************************************** 690 * 691 * FUNCTION: _CmCallocate 692 * 693 * PARAMETERS: Size - Size of the allocation 694 * Component - Component type of caller 695 * Module - Source file name of caller 696 * Line - Line number of caller 697 * 698 * RETURN: Address of the allocated memory on success, NULL on failure. 699 * 700 * DESCRIPTION: Subsystem equivalent of calloc. 701 * 702 ****************************************************************************/ 703 704void * 705_CmCallocate ( 706 UINT32 Size, 707 UINT32 Component, 708 NATIVE_CHAR *Module, 709 UINT32 Line) 710{ 711 void *Address = NULL; 712 DEBUG_EXEC (\ 713 ACPI_STATUS Status) 714 715 716 FUNCTION_TRACE_U32 ("_CmCallocate", Size); 717 718 719 /* Check for an inadvertent size of zero bytes */ 720 721 if (!Size) 722 { 723 _REPORT_ERROR (Module, Line, Component, 724 ("CmCallocate: Attempt to allocate zero bytes\n")); 725 return_VALUE (NULL); 726 } 727 728 729 Address = AcpiOsCallocate (Size); 730 731 if (!Address) 732 { 733 /* Report allocation error */ 734 735 _REPORT_ERROR (Module, Line, Component, 736 ("CmCallocate: Could not allocate size 0x%x\n", Size)); 737 return_VALUE (NULL); 738 } 739 740#ifdef ACPI_DEBUG 741 Status = AcpiCmAddElementToAllocList (Address, Size, MEM_CALLOC, Component, 742 Module, Line); 743 if (ACPI_FAILURE (Status)) 744 { 745 AcpiOsFree (Address); 746 return_PTR (NULL); 747 } 748#endif 749 750 DEBUG_PRINT (TRACE_ALLOCATIONS, 751 ("CmCallocate: %p Size 0x%x\n", Address, Size)); 752 753 return_PTR (Address); 754} 755 756 757/***************************************************************************** 758 * 759 * FUNCTION: _CmFree 760 * 761 * PARAMETERS: Address - Address of the memory to deallocate 762 * Component - Component type of caller 763 * Module - Source file name of caller 764 * Line - Line number of caller 765 * 766 * RETURN: None 767 * 768 * DESCRIPTION: Frees the memory at Address 769 * 770 ****************************************************************************/ 771 772void 773_CmFree ( 774 void *Address, 775 UINT32 Component, 776 NATIVE_CHAR *Module, 777 UINT32 Line) 778{ 779 FUNCTION_TRACE_PTR ("_CmFree", Address); 780 781 782 if (NULL == Address) 783 { 784 _REPORT_ERROR (Module, Line, Component, 785 ("_CmFree: Trying to delete a NULL address\n")); 786 787 return_VOID; 788 } 789 790#ifdef ACPI_DEBUG 791 AcpiCmDeleteElementFromAllocList (Address, Component, Module, Line); 792#endif 793 794 AcpiOsFree (Address); 795 796 DEBUG_PRINT (TRACE_ALLOCATIONS, ("CmFree: %p freed\n", Address)); 797 798 return_VOID; 799} 800 801 802