Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure
   1 /******************************************************************************
   2  *
   3  * Module Name: uttrack - Memory allocation tracking routines (debug only)
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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.


  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 /* Local prototypes */
  66 
  67 static ACPI_DEBUG_MEM_BLOCK *
  68 AcpiUtFindAllocation (
  69     void                    *Allocation);
  70 
  71 static ACPI_STATUS
  72 AcpiUtTrackAllocation (
  73     ACPI_DEBUG_MEM_BLOCK    *Address,
  74     ACPI_SIZE               Size,
  75     UINT8                   AllocType,
  76     UINT32                  Component,
  77     const char              *Module,
  78     UINT32                  Line);
  79 
  80 static ACPI_STATUS
  81 AcpiUtRemoveAllocation (
  82     ACPI_DEBUG_MEM_BLOCK    *Address,
  83     UINT32                  Component,
  84     const char              *Module,
  85     UINT32                  Line);
  86 
  87 
  88 /*******************************************************************************
  89  *


 133  *              Module              - Source file name of caller
 134  *              Line                - Line number of caller
 135  *
 136  * RETURN:      Address of the allocated memory on success, NULL on failure.
 137  *
 138  * DESCRIPTION: The subsystem's equivalent of malloc.
 139  *
 140  ******************************************************************************/
 141 
 142 void *
 143 AcpiUtAllocateAndTrack (
 144     ACPI_SIZE               Size,
 145     UINT32                  Component,
 146     const char              *Module,
 147     UINT32                  Line)
 148 {
 149     ACPI_DEBUG_MEM_BLOCK    *Allocation;
 150     ACPI_STATUS             Status;
 151 
 152 
 153     Allocation = AcpiUtAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER),
 154                     Component, Module, Line);








 155     if (!Allocation)
 156     {





 157         return (NULL);
 158     }
 159 
 160     Status = AcpiUtTrackAllocation (Allocation, Size,
 161                     ACPI_MEM_MALLOC, Component, Module, Line);
 162     if (ACPI_FAILURE (Status))
 163     {
 164         AcpiOsFree (Allocation);
 165         return (NULL);
 166     }
 167 
 168     AcpiGbl_GlobalList->TotalAllocated++;
 169     AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
 170     AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
 171     if (AcpiGbl_GlobalList->CurrentTotalSize > AcpiGbl_GlobalList->MaxOccupied)
 172     {
 173         AcpiGbl_GlobalList->MaxOccupied = AcpiGbl_GlobalList->CurrentTotalSize;
 174     }
 175 
 176     return ((void *) &Allocation->UserSpace);


 186  *              Module              - Source file name of caller
 187  *              Line                - Line number of caller
 188  *
 189  * RETURN:      Address of the allocated memory on success, NULL on failure.
 190  *
 191  * DESCRIPTION: Subsystem equivalent of calloc.
 192  *
 193  ******************************************************************************/
 194 
 195 void *
 196 AcpiUtAllocateZeroedAndTrack (
 197     ACPI_SIZE               Size,
 198     UINT32                  Component,
 199     const char              *Module,
 200     UINT32                  Line)
 201 {
 202     ACPI_DEBUG_MEM_BLOCK    *Allocation;
 203     ACPI_STATUS             Status;
 204 
 205 
 206     Allocation = AcpiUtAllocateZeroed (Size + sizeof (ACPI_DEBUG_MEM_HEADER),
 207                     Component, Module, Line);








 208     if (!Allocation)
 209     {
 210         /* Report allocation error */
 211 
 212         ACPI_ERROR ((Module, Line,
 213             "Could not allocate size %u", (UINT32) Size));
 214         return (NULL);
 215     }
 216 
 217     Status = AcpiUtTrackAllocation (Allocation, Size,
 218                 ACPI_MEM_CALLOC, Component, Module, Line);
 219     if (ACPI_FAILURE (Status))
 220     {
 221         AcpiOsFree (Allocation);
 222         return (NULL);
 223     }
 224 
 225     AcpiGbl_GlobalList->TotalAllocated++;
 226     AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
 227     AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;


 268         ACPI_ERROR ((Module, Line,
 269             "Attempt to delete a NULL address"));
 270 
 271         return_VOID;
 272     }
 273 
 274     DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK,
 275                     (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER)));
 276 
 277     AcpiGbl_GlobalList->TotalFreed++;
 278     AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size;
 279 
 280     Status = AcpiUtRemoveAllocation (DebugBlock,
 281                     Component, Module, Line);
 282     if (ACPI_FAILURE (Status))
 283     {
 284         ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory"));
 285     }
 286 
 287     AcpiOsFree (DebugBlock);
 288     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Allocation));

 289     return_VOID;
 290 }
 291 
 292 
 293 /*******************************************************************************
 294  *
 295  * FUNCTION:    AcpiUtFindAllocation
 296  *
 297  * PARAMETERS:  Allocation              - Address of allocated memory
 298  *
 299  * RETURN:      A list element if found; NULL otherwise.




 300  *
 301  * DESCRIPTION: Searches for an element in the global allocation tracking list.


 302  *









 303  ******************************************************************************/
 304 
 305 static ACPI_DEBUG_MEM_BLOCK *
 306 AcpiUtFindAllocation (
 307     void                    *Allocation)
 308 {
 309     ACPI_DEBUG_MEM_BLOCK    *Element;
 310 
 311 
 312     ACPI_FUNCTION_ENTRY ();
 313 
 314 
 315     Element = AcpiGbl_GlobalList->ListHead;




 316 
 317     /* Search for the address. */









 318 
 319     while (Element)
 320     {
 321         if (Element == Allocation)
 322         {
 323             return (Element);
 324         }
 325 
 326         Element = Element->Next;
 327     }
 328 
 329     return (NULL);





 330 }
 331 
 332 
 333 /*******************************************************************************
 334  *
 335  * FUNCTION:    AcpiUtTrackAllocation
 336  *
 337  * PARAMETERS:  Allocation          - Address of allocated memory
 338  *              Size                - Size of the allocation
 339  *              AllocType           - MEM_MALLOC or MEM_CALLOC
 340  *              Component           - Component type of caller
 341  *              Module              - Source file name of caller
 342  *              Line                - Line number of caller
 343  *
 344  * RETURN:      None.
 345  *
 346  * DESCRIPTION: Inserts an element into the global allocation tracking list.
 347  *
 348  ******************************************************************************/
 349 
 350 static ACPI_STATUS
 351 AcpiUtTrackAllocation (
 352     ACPI_DEBUG_MEM_BLOCK    *Allocation,
 353     ACPI_SIZE               Size,
 354     UINT8                   AllocType,
 355     UINT32                  Component,
 356     const char              *Module,
 357     UINT32                  Line)
 358 {
 359     ACPI_MEMORY_LIST        *MemList;
 360     ACPI_DEBUG_MEM_BLOCK    *Element;
 361     ACPI_STATUS             Status = AE_OK;
 362 
 363 
 364     ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation);
 365 
 366 
 367     if (AcpiGbl_DisableMemTracking)
 368     {
 369         return_ACPI_STATUS (AE_OK);
 370     }
 371 
 372     MemList = AcpiGbl_GlobalList;
 373     Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
 374     if (ACPI_FAILURE (Status))
 375     {
 376         return_ACPI_STATUS (Status);
 377     }
 378 
 379     /*
 380      * Search list for this address to make sure it is not already on the list.
 381      * This will catch several kinds of problems.
 382      */
 383     Element = AcpiUtFindAllocation (Allocation);
 384     if (Element)
 385     {
 386         ACPI_ERROR ((AE_INFO,
 387             "UtTrackAllocation: Allocation already present in list! (%p)",
 388             Allocation));
 389 
 390         ACPI_ERROR ((AE_INFO, "Element %p Address %p",
 391             Element, Allocation));
 392 
 393         goto UnlockAndExit;
 394     }
 395 
 396     /* Fill in the instance data. */
 397 
 398     Allocation->Size      = (UINT32) Size;
 399     Allocation->AllocType = AllocType;
 400     Allocation->Component = Component;
 401     Allocation->Line      = Line;
 402 
 403     ACPI_STRNCPY (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
 404     Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
 405 


 406     /* Insert at list head */
 407 
 408     if (MemList->ListHead)
 409     {
 410         ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Allocation;
 411     }
 412 
 413     Allocation->Next = MemList->ListHead;
 414     Allocation->Previous = NULL;
 415 
 416     MemList->ListHead = Allocation;




 417 


 418 









 419 UnlockAndExit:
 420     Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
 421     return_ACPI_STATUS (Status);
 422 }
 423 
 424 
 425 /*******************************************************************************
 426  *
 427  * FUNCTION:    AcpiUtRemoveAllocation
 428  *
 429  * PARAMETERS:  Allocation          - Address of allocated memory
 430  *              Component           - Component type of caller
 431  *              Module              - Source file name of caller
 432  *              Line                - Line number of caller
 433  *
 434  * RETURN:
 435  *
 436  * DESCRIPTION: Deletes an element from the global allocation tracking list.
 437  *
 438  ******************************************************************************/
 439 
 440 static ACPI_STATUS
 441 AcpiUtRemoveAllocation (
 442     ACPI_DEBUG_MEM_BLOCK    *Allocation,
 443     UINT32                  Component,
 444     const char              *Module,
 445     UINT32                  Line)
 446 {
 447     ACPI_MEMORY_LIST        *MemList;
 448     ACPI_STATUS             Status;
 449 
 450 
 451     ACPI_FUNCTION_TRACE (UtRemoveAllocation);
 452 
 453 
 454     if (AcpiGbl_DisableMemTracking)
 455     {
 456         return_ACPI_STATUS (AE_OK);
 457     }
 458 
 459     MemList = AcpiGbl_GlobalList;
 460     if (NULL == MemList->ListHead)
 461     {
 462         /* No allocations! */
 463 
 464         ACPI_ERROR ((Module, Line,
 465             "Empty allocation list, nothing to free!"));
 466 
 467         return_ACPI_STATUS (AE_OK);
 468     }
 469 
 470     Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
 471     if (ACPI_FAILURE (Status))
 472     {
 473         return_ACPI_STATUS (Status);
 474     }
 475 
 476     /* Unlink */
 477 
 478     if (Allocation->Previous)
 479     {
 480         (Allocation->Previous)->Next = Allocation->Next;
 481     }
 482     else
 483     {
 484         MemList->ListHead = Allocation->Next;
 485     }
 486 
 487     if (Allocation->Next)
 488     {
 489         (Allocation->Next)->Previous = Allocation->Previous;
 490     }
 491 



 492     /* Mark the segment as deleted */
 493 
 494     ACPI_MEMSET (&Allocation->UserSpace, 0xEA, Allocation->Size);
 495 
 496     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
 497         Allocation->Size));
 498 
 499     Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
 500     return_ACPI_STATUS (Status);
 501 }
 502 
 503 
 504 /*******************************************************************************
 505  *
 506  * FUNCTION:    AcpiUtDumpAllocationInfo
 507  *
 508  * PARAMETERS:
 509  *
 510  * RETURN:      None
 511  *
 512  * DESCRIPTION: Print some info about the outstanding allocations.
 513  *
 514  ******************************************************************************/
 515 
 516 void
 517 AcpiUtDumpAllocationInfo (
 518     void)
 519 {
 520 /*
 521     ACPI_MEMORY_LIST        *MemList;
 522 */
 523 
 524     ACPI_FUNCTION_TRACE (UtDumpAllocationInfo);
 525 
 526 /*
 527     ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 528                     ("%30s: %4d (%3d Kb)\n", "Current allocations",


 573  * DESCRIPTION: Print a list of all outstanding allocations.
 574  *
 575  ******************************************************************************/
 576 
 577 void
 578 AcpiUtDumpAllocations (
 579     UINT32                  Component,
 580     const char              *Module)
 581 {
 582     ACPI_DEBUG_MEM_BLOCK    *Element;
 583     ACPI_DESCRIPTOR         *Descriptor;
 584     UINT32                  NumOutstanding = 0;
 585     UINT8                   DescriptorType;
 586 
 587 
 588     ACPI_FUNCTION_TRACE (UtDumpAllocations);
 589 
 590 
 591     if (AcpiGbl_DisableMemTracking)
 592     {
 593         return;
 594     }
 595 
 596     /*
 597      * Walk the allocation list.
 598      */
 599     if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY)))
 600     {
 601         return;
 602     }
 603 
 604     Element = AcpiGbl_GlobalList->ListHead;
 605     while (Element)
 606     {
 607         if ((Element->Component & Component) &&
 608             ((Module == NULL) || (0 == ACPI_STRCMP (Module, Element->Module))))
 609         {
 610             Descriptor = ACPI_CAST_PTR (ACPI_DESCRIPTOR, &Element->UserSpace);
 611 
 612             if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR))
 613             {
 614                 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u "
 615                     "[Not a Descriptor - too small]\n",
 616                     Descriptor, Element->Size, Element->Module,
 617                     Element->Line);
 618             }
 619             else
 620             {
 621                 /* Ignore allocated objects that are in a cache */
 622 
 623                 if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != ACPI_DESC_TYPE_CACHED)
 624                 {
 625                     AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ",
 626                         Descriptor, Element->Size, Element->Module,
 627                         Element->Line, AcpiUtGetDescriptorName (Descriptor));
 628 
 629                     /* Validate the descriptor type using Type field and length */
 630 
 631                     DescriptorType = 0; /* Not a valid descriptor type */
 632 
 633                     switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
 634                     {
 635                     case ACPI_DESC_TYPE_OPERAND:
 636                         if (Element->Size == sizeof (ACPI_DESC_TYPE_OPERAND))

 637                         {
 638                             DescriptorType = ACPI_DESC_TYPE_OPERAND;
 639                         }
 640                         break;
 641 
 642                     case ACPI_DESC_TYPE_PARSER:
 643                         if (Element->Size == sizeof (ACPI_DESC_TYPE_PARSER))

 644                         {
 645                             DescriptorType = ACPI_DESC_TYPE_PARSER;
 646                         }
 647                         break;
 648 
 649                     case ACPI_DESC_TYPE_NAMED:
 650                         if (Element->Size == sizeof (ACPI_DESC_TYPE_NAMED))

 651                         {
 652                             DescriptorType = ACPI_DESC_TYPE_NAMED;
 653                         }
 654                         break;
 655 
 656                     default:

 657                         break;
 658                     }
 659 
 660                     /* Display additional info for the major descriptor types */
 661 
 662                     switch (DescriptorType)
 663                     {
 664                     case ACPI_DESC_TYPE_OPERAND:

 665                         AcpiOsPrintf ("%12.12s  RefCount 0x%04X\n",
 666                             AcpiUtGetTypeName (Descriptor->Object.Common.Type),
 667                             Descriptor->Object.Common.ReferenceCount);
 668                         break;
 669 
 670                     case ACPI_DESC_TYPE_PARSER:

 671                         AcpiOsPrintf ("AmlOpcode 0x%04hX\n",
 672                             Descriptor->Op.Asl.AmlOpcode);
 673                         break;
 674 
 675                     case ACPI_DESC_TYPE_NAMED:

 676                         AcpiOsPrintf ("%4.4s\n",
 677                             AcpiUtGetNodeName (&Descriptor->Node));
 678                         break;
 679 
 680                     default:

 681                         AcpiOsPrintf ( "\n");
 682                         break;
 683                     }
 684                 }
 685             }
 686 
 687             NumOutstanding++;
 688         }
 689 
 690         Element = Element->Next;
 691     }
 692 
 693     (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
 694 
 695     /* Print summary */
 696 
 697     if (!NumOutstanding)
 698     {
 699         ACPI_INFO ((AE_INFO, "No outstanding allocations"));
 700     }
 701     else
 702     {
 703         ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations",
 704             NumOutstanding, NumOutstanding));
 705     }
 706 
 707     return_VOID;
 708 }
 709 
 710 #endif  /* ACPI_DBG_TRACK_ALLOCATIONS */
 711 
   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.


  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  *


 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);


 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;


 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",


 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 */