utalloc.c revision 83174
1155131Srwatson/****************************************************************************** 2189279Srwatson * 3157137Srwatson * Module Name: utalloc - local cache and memory allocation routines 4155131Srwatson * $Revision: 100 $ 5185573Srwatson * 6173146Srwatson *****************************************************************************/ 7173146Srwatson 8173146Srwatson/****************************************************************************** 9173146Srwatson * 10173146Srwatson * 1. Copyright Notice 11186647Srwatson * 12186647Srwatson * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 13186647Srwatson * All rights reserved. 14186647Srwatson * 15186647Srwatson * 2. License 16186647Srwatson * 17186647Srwatson * 2.1. This is your license from Intel Corp. under its intellectual property 18186647Srwatson * rights. You may have additional license terms from the party that provided 19186647Srwatson * you this software, covering your right to use that party's intellectual 20186647Srwatson * property rights. 21186647Srwatson * 22186647Srwatson * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23186647Srwatson * copy of the source code appearing in this file ("Covered Code") an 24186647Srwatson * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25155131Srwatson * base code distributed originally by Intel ("Original Intel Code") to copy, 26155131Srwatson * make derivatives, distribute, use and display any portion of the Covered 27155131Srwatson * Code in any form, with the right to sublicense such rights; and 28155131Srwatson * 29155131Srwatson * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30155131Srwatson * license (with the right to sublicense), under only those claims of Intel 31155131Srwatson * patents that are infringed by the Original Intel Code, to make, use, sell, 32155131Srwatson * offer to sell, and import the Covered Code and derivative works thereof 33155131Srwatson * solely to the minimum extent necessary to exercise the above copyright 34155131Srwatson * license, and in no event shall the patent license extend to any additions 35155131Srwatson * to or modifications of the Original Intel Code. No other license or right 36155131Srwatson * is granted directly or by implication, estoppel or otherwise; 37155131Srwatson * 38155131Srwatson * The above copyright and patent license is granted only if the following 39155131Srwatson * conditions are met: 40155131Srwatson * 41155131Srwatson * 3. Conditions 42155131Srwatson * 43155131Srwatson * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44155131Srwatson * Redistribution of source code of any substantial portion of the Covered 45155131Srwatson * Code or modification with rights to further distribute source must include 46155131Srwatson * the above Copyright Notice, the above License, this list of Conditions, 47155131Srwatson * and the following Disclaimer and Export Compliance provision. In addition, 48155131Srwatson * Licensee must cause all Covered Code to which Licensee contributes to 49155131Srwatson * contain a file documenting the changes Licensee made to create that Covered 50155131Srwatson * Code and the date of any change. Licensee must include in that file the 51155131Srwatson * documentation of any changes made by any predecessor Licensee. Licensee 52155131Srwatson * must include a prominent statement that the modification is derived, 53155131Srwatson * directly or indirectly, from Original Intel Code. 54155131Srwatson * 55155131Srwatson * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56155131Srwatson * Redistribution of source code of any substantial portion of the Covered 57155131Srwatson * Code or modification without rights to further distribute source must 58155131Srwatson * include the following Disclaimer and Export Compliance provision in the 59155131Srwatson * documentation and/or other materials provided with distribution. In 60155131Srwatson * addition, Licensee may not authorize further sublicense of source of any 61155131Srwatson * portion of the Covered Code, and must include terms to the effect that the 62155131Srwatson * license from Licensee to its licensee is limited to the intellectual 63155131Srwatson * property embodied in the software Licensee provides to its licensee, and 64155131Srwatson * not to intellectual property embodied in modifications its licensee may 65155131Srwatson * make. 66155131Srwatson * 67155131Srwatson * 3.3. Redistribution of Executable. Redistribution in executable form of any 68155131Srwatson * substantial portion of the Covered Code or modification must reproduce the 69155131Srwatson * above Copyright Notice, and the following Disclaimer and Export Compliance 70155131Srwatson * provision in the documentation and/or other materials provided with the 71155131Srwatson * distribution. 72155131Srwatson * 73155131Srwatson * 3.4. Intel retains all right, title, and interest in and to the Original 74155131Srwatson * Intel Code. 75155131Srwatson * 76155131Srwatson * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77155131Srwatson * Intel shall be used in advertising or otherwise to promote the sale, use or 78155131Srwatson * other dealings in products derived from or relating to the Covered Code 79155131Srwatson * without prior written authorization from Intel. 80155131Srwatson * 81155131Srwatson * 4. Disclaimer and Export Compliance 82155131Srwatson * 83155131Srwatson * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84155131Srwatson * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85155131Srwatson * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86155131Srwatson * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87155131Srwatson * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89155131Srwatson * PARTICULAR PURPOSE. 90155131Srwatson * 91155131Srwatson * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92155131Srwatson * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93155131Srwatson * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94155131Srwatson * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95155131Srwatson * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96155131Srwatson * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97155131Srwatson * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98155131Srwatson * LIMITED REMEDY. 99155131Srwatson * 100155131Srwatson * 4.3. Licensee shall not export, either directly or indirectly, any of this 101155131Srwatson * software or system incorporating such software without first obtaining any 102155131Srwatson * required license or other approval from the U. S. Department of Commerce or 103155131Srwatson * any other agency or department of the United States Government. In the 104155131Srwatson * event Licensee exports any such software from the United States or 105155131Srwatson * re-exports any such software from a foreign destination, Licensee shall 106155131Srwatson * ensure that the distribution and export/re-export of the software is in 107155131Srwatson * compliance with all laws, regulations, orders, or other restrictions of the 108155131Srwatson * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109155131Srwatson * any of its subsidiaries will export/re-export any technical data, process, 110155131Srwatson * software, or service, directly or indirectly, to any country for which the 111155131Srwatson * United States government or any agency thereof requires an export license, 112155131Srwatson * other governmental approval, or letter of assurance, without first obtaining 113155131Srwatson * such license, approval or letter. 114155131Srwatson * 115155131Srwatson *****************************************************************************/ 116155131Srwatson 117155131Srwatson#define __UTALLOC_C__ 118155131Srwatson 119155131Srwatson#include "acpi.h" 120155131Srwatson#include "acparser.h" 121155131Srwatson#include "acinterp.h" 122155131Srwatson#include "acnamesp.h" 123155131Srwatson#include "acglobal.h" 124155131Srwatson 125155131Srwatson#define _COMPONENT ACPI_UTILITIES 126155131Srwatson MODULE_NAME ("utalloc") 127155131Srwatson 128155131Srwatson 129155131Srwatson/****************************************************************************** 130155131Srwatson * 131155131Srwatson * FUNCTION: AcpiUtReleaseToCache 132155131Srwatson * 133155131Srwatson * PARAMETERS: ListId - Memory list/cache ID 134155131Srwatson * Object - The object to be released 135155131Srwatson * 136155131Srwatson * RETURN: None 137155131Srwatson * 138155131Srwatson * DESCRIPTION: Release an object to the specified cache. If cache is full, 139155131Srwatson * the object is deleted. 140155131Srwatson * 141162506Srwatson ******************************************************************************/ 142162506Srwatson 143155131Srwatsonvoid 144155131SrwatsonAcpiUtReleaseToCache ( 145155131Srwatson UINT32 ListId, 146155131Srwatson void *Object) 147155131Srwatson{ 148155131Srwatson ACPI_MEMORY_LIST *CacheInfo; 149155131Srwatson 150155131Srwatson 151155131Srwatson FUNCTION_ENTRY (); 152155131Srwatson 153155131Srwatson 154155131Srwatson /* If walk cache is full, just free this wallkstate object */ 155155131Srwatson 156155131Srwatson CacheInfo = &AcpiGbl_MemoryLists[ListId]; 157155131Srwatson if (CacheInfo->CacheDepth >= CacheInfo->MaxCacheDepth) 158155131Srwatson { 159155131Srwatson ACPI_MEM_FREE (Object); 160155131Srwatson ACPI_MEM_TRACKING (CacheInfo->TotalFreed++); 161155131Srwatson } 162155131Srwatson 163155131Srwatson /* Otherwise put this object back into the cache */ 164171540Srwatson 165171540Srwatson else 166155131Srwatson { 167155131Srwatson AcpiUtAcquireMutex (ACPI_MTX_CACHES); 168171540Srwatson 169171540Srwatson /* Mark the object as cached */ 170171540Srwatson 171155131Srwatson MEMSET (Object, 0xCA, CacheInfo->ObjectSize); 172155131Srwatson 173155131Srwatson /* Put the object at the head of the cache list */ 174155131Srwatson 175155131Srwatson * (char **) (((char *) Object) + CacheInfo->LinkOffset) = CacheInfo->ListHead; 176155131Srwatson CacheInfo->ListHead = Object; 177155131Srwatson CacheInfo->CacheDepth++; 178155131Srwatson 179155131Srwatson AcpiUtReleaseMutex (ACPI_MTX_CACHES); 180155131Srwatson } 181155131Srwatson} 182155131Srwatson 183155131Srwatson 184155131Srwatson/****************************************************************************** 185155131Srwatson * 186155131Srwatson * FUNCTION: AcpiUtAcquireFromCache 187155131Srwatson * 188155131Srwatson * PARAMETERS: ListId - Memory list ID 189155131Srwatson * 190155131Srwatson * RETURN: A requested object. NULL if the object could not be 191155131Srwatson * allocated. 192155131Srwatson * 193155131Srwatson * DESCRIPTION: Get an object from the specified cache. If cache is empty, 194171540Srwatson * the object is allocated. 195155131Srwatson * 196155131Srwatson ******************************************************************************/ 197155131Srwatson 198155131Srwatsonvoid * 199171540SrwatsonAcpiUtAcquireFromCache ( 200155131Srwatson UINT32 ListId) 201155131Srwatson{ 202155131Srwatson ACPI_MEMORY_LIST *CacheInfo; 203186647Srwatson void *Object; 204155131Srwatson 205155131Srwatson 206155131Srwatson PROC_NAME ("UtAcquireFromCache"); 207171540Srwatson 208155131Srwatson 209155131Srwatson CacheInfo = &AcpiGbl_MemoryLists[ListId]; 210155131Srwatson AcpiUtAcquireMutex (ACPI_MTX_CACHES); 211155131Srwatson ACPI_MEM_TRACKING (CacheInfo->CacheRequests++); 212155131Srwatson 213155131Srwatson /* Check the cache first */ 214155131Srwatson 215155131Srwatson if (CacheInfo->ListHead) 216155131Srwatson { 217155131Srwatson /* There is an object available, use it */ 218155131Srwatson 219155131Srwatson Object = CacheInfo->ListHead; 220155131Srwatson CacheInfo->ListHead = * (char **) (((char *) Object) + CacheInfo->LinkOffset); 221155131Srwatson 222155131Srwatson ACPI_MEM_TRACKING (CacheInfo->CacheHits++); 223155131Srwatson CacheInfo->CacheDepth--; 224155131Srwatson 225155131Srwatson#ifdef ACPI_DBG_TRACK_ALLOCATIONS 226155131Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n", 227155131Srwatson Object, AcpiGbl_MemoryLists[ListId].ListName)); 228155131Srwatson#endif 229155131Srwatson 230155131Srwatson AcpiUtReleaseMutex (ACPI_MTX_CACHES); 231171540Srwatson 232155131Srwatson /* Clear (zero) the previously used Object */ 233155131Srwatson 234155131Srwatson MEMSET (Object, 0, CacheInfo->ObjectSize); 235155131Srwatson } 236155131Srwatson 237155131Srwatson else 238155131Srwatson { 239155131Srwatson /* The cache is empty, create a new object */ 240155131Srwatson 241155131Srwatson /* Avoid deadlock with ACPI_MEM_CALLOCATE */ 242155131Srwatson 243155131Srwatson AcpiUtReleaseMutex (ACPI_MTX_CACHES); 244155131Srwatson 245155131Srwatson Object = ACPI_MEM_CALLOCATE (CacheInfo->ObjectSize); 246155131Srwatson ACPI_MEM_TRACKING (CacheInfo->TotalAllocated++); 247155131Srwatson } 248155131Srwatson 249155131Srwatson return (Object); 250155131Srwatson} 251155131Srwatson 252155131Srwatson 253155131Srwatson/****************************************************************************** 254155131Srwatson * 255155131Srwatson * FUNCTION: AcpiUtDeleteGenericCache 256155131Srwatson * 257155131Srwatson * PARAMETERS: ListId - Memory list ID 258155131Srwatson * 259155131Srwatson * RETURN: None 260171540Srwatson * 261155131Srwatson * DESCRIPTION: Free all objects within the requested cache. 262155131Srwatson * 263171540Srwatson ******************************************************************************/ 264171540Srwatson 265171540Srwatsonvoid 266171540SrwatsonAcpiUtDeleteGenericCache ( 267171540Srwatson UINT32 ListId) 268171540Srwatson{ 269171540Srwatson ACPI_MEMORY_LIST *CacheInfo; 270171540Srwatson char *Next; 271171540Srwatson 272171540Srwatson 273171540Srwatson FUNCTION_ENTRY (); 274171540Srwatson 275171540Srwatson 276171540Srwatson CacheInfo = &AcpiGbl_MemoryLists[ListId]; 277171540Srwatson while (CacheInfo->ListHead) 278171540Srwatson { 279171540Srwatson /* Delete one cached state object */ 280171540Srwatson 281171540Srwatson Next = * (char **) (((char *) CacheInfo->ListHead) + CacheInfo->LinkOffset); 282171540Srwatson ACPI_MEM_FREE (CacheInfo->ListHead); 283171540Srwatson 284171540Srwatson CacheInfo->ListHead = Next; 285171540Srwatson CacheInfo->CacheDepth--; 286171540Srwatson } 287171540Srwatson} 288171540Srwatson 289171540Srwatson 290171540Srwatson#ifdef ACPI_DBG_TRACK_ALLOCATIONS 291171540Srwatson 292171540Srwatson 293171540Srwatson/* 294171540Srwatson * These procedures are used for tracking memory leaks in the subsystem, and 295185573Srwatson * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. 296161633Srwatson * 297185573Srwatson * Each memory allocation is tracked via a doubly linked list. Each 298185573Srwatson * element contains the caller's component, module name, function name, and 299161633Srwatson * line number. AcpiUtAllocate and AcpiUtCallocate call 300161633Srwatson * AcpiUtAddElementToAllocList to add an element to the list; deletion 301161633Srwatson * occurs in the body of AcpiUtFree. 302161633Srwatson */ 303161633Srwatson 304161633Srwatson 305161633Srwatson/******************************************************************************* 306161633Srwatson * 307155131Srwatson * FUNCTION: AcpiUtSearchAllocList 308161633Srwatson * 309161633Srwatson * PARAMETERS: Address - Address of allocated memory 310161633Srwatson * 311155131Srwatson * RETURN: A list element if found; NULL otherwise. 312155131Srwatson * 313155131Srwatson * DESCRIPTION: Searches for an element in the global allocation tracking list. 314161633Srwatson * 315161633Srwatson ******************************************************************************/ 316155131Srwatson 317161633SrwatsonACPI_DEBUG_MEM_BLOCK * 318161633SrwatsonAcpiUtSearchAllocList ( 319161633Srwatson UINT32 ListId, 320155131Srwatson void *Address) 321155131Srwatson{ 322155131Srwatson ACPI_DEBUG_MEM_BLOCK *Element; 323161633Srwatson 324161633Srwatson 325161633Srwatson FUNCTION_ENTRY (); 326161633Srwatson 327162506Srwatson 328155131Srwatson if (ListId > ACPI_MEM_LIST_MAX) 329155131Srwatson { 330161633Srwatson return (NULL); 331161633Srwatson } 332161633Srwatson 333161633Srwatson Element = AcpiGbl_MemoryLists[ListId].ListHead; 334161633Srwatson 335161633Srwatson /* Search for the address. */ 336161633Srwatson 337161633Srwatson while (Element) 338161633Srwatson { 339161633Srwatson if (Element == Address) 340161633Srwatson { 341161633Srwatson return (Element); 342161633Srwatson } 343161633Srwatson 344161633Srwatson Element = Element->Next; 345161633Srwatson } 346161633Srwatson 347161633Srwatson return (NULL); 348161633Srwatson} 349161633Srwatson 350161633Srwatson 351161633Srwatson/******************************************************************************* 352161633Srwatson * 353161633Srwatson * FUNCTION: AcpiUtAddElementToAllocList 354171540Srwatson * 355161633Srwatson * PARAMETERS: Address - Address of allocated memory 356161633Srwatson * Size - Size of the allocation 357161633Srwatson * AllocType - MEM_MALLOC or MEM_CALLOC 358161633Srwatson * Component - Component type of caller 359161633Srwatson * Module - Source file name of caller 360161633Srwatson * Line - Line number of caller 361161633Srwatson * 362161633Srwatson * RETURN: None. 363161633Srwatson * 364161633Srwatson * DESCRIPTION: Inserts an element into the global allocation tracking list. 365161633Srwatson * 366161633Srwatson ******************************************************************************/ 367161633Srwatson 368161633SrwatsonACPI_STATUS 369161633SrwatsonAcpiUtAddElementToAllocList ( 370161633Srwatson UINT32 ListId, 371171540Srwatson ACPI_DEBUG_MEM_BLOCK *Address, 372161633Srwatson UINT32 Size, 373161633Srwatson UINT8 AllocType, 374161633Srwatson UINT32 Component, 375161633Srwatson NATIVE_CHAR *Module, 376161633Srwatson UINT32 Line) 377161633Srwatson{ 378161633Srwatson ACPI_MEMORY_LIST *MemList; 379161633Srwatson ACPI_DEBUG_MEM_BLOCK *Element; 380161633Srwatson ACPI_STATUS Status = AE_OK; 381171540Srwatson 382161633Srwatson 383162506Srwatson FUNCTION_TRACE_PTR ("UtAddElementToAllocList", Address); 384162506Srwatson 385161633Srwatson 386161633Srwatson if (ListId > ACPI_MEM_LIST_MAX) 387161633Srwatson { 388161633Srwatson return_ACPI_STATUS (AE_BAD_PARAMETER); 389161633Srwatson } 390161633Srwatson 391161633Srwatson MemList = &AcpiGbl_MemoryLists[ListId]; 392161633Srwatson AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 393161633Srwatson 394161633Srwatson /* 395161633Srwatson * Search list for this address to make sure it is not already on the list. 396161633Srwatson * This will catch several kinds of problems. 397161633Srwatson */ 398161633Srwatson 399161633Srwatson Element = AcpiUtSearchAllocList (ListId, Address); 400161633Srwatson if (Element) 401161633Srwatson { 402161633Srwatson REPORT_ERROR (("UtAddElementToAllocList: Address already present in list! (%p)\n", 403161633Srwatson Address)); 404161633Srwatson 405161633Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", Element, Address)); 406161633Srwatson 407161633Srwatson goto UnlockAndExit; 408171540Srwatson } 409161633Srwatson 410161633Srwatson /* Fill in the instance data. */ 411161633Srwatson 412161633Srwatson Address->Size = Size; 413161633Srwatson Address->AllocType = AllocType; 414171540Srwatson Address->Component = Component; 415161633Srwatson Address->Line = Line; 416161633Srwatson 417161633Srwatson STRNCPY (Address->Module, Module, MAX_MODULE_NAME); 418161633Srwatson 419161633Srwatson /* Insert at list head */ 420161633Srwatson 421161633Srwatson if (MemList->ListHead) 422161633Srwatson { 423161633Srwatson ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Address; 424161633Srwatson } 425161633Srwatson 426161633Srwatson Address->Next = MemList->ListHead; 427161633Srwatson Address->Previous = NULL; 428161633Srwatson 429161633Srwatson MemList->ListHead = Address; 430161633Srwatson 431161633Srwatson 432161633SrwatsonUnlockAndExit: 433161633Srwatson AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 434161633Srwatson return_ACPI_STATUS (Status); 435161633Srwatson} 436161633Srwatson 437161633Srwatson 438161633Srwatson/******************************************************************************* 439161633Srwatson * 440161633Srwatson * FUNCTION: AcpiUtDeleteElementFromAllocList 441161633Srwatson * 442161633Srwatson * PARAMETERS: Address - Address of allocated memory 443161633Srwatson * Component - Component type of caller 444161633Srwatson * Module - Source file name of caller 445161633Srwatson * Line - Line number of caller 446161633Srwatson * 447161633Srwatson * RETURN: 448161633Srwatson * 449161633Srwatson * DESCRIPTION: Deletes an element from the global allocation tracking list. 450161633Srwatson * 451161633Srwatson ******************************************************************************/ 452161633Srwatson 453161633SrwatsonACPI_STATUS 454161633SrwatsonAcpiUtDeleteElementFromAllocList ( 455161633Srwatson UINT32 ListId, 456161633Srwatson ACPI_DEBUG_MEM_BLOCK *Address, 457161633Srwatson UINT32 Component, 458161633Srwatson NATIVE_CHAR *Module, 459161633Srwatson UINT32 Line) 460161633Srwatson{ 461161633Srwatson ACPI_MEMORY_LIST *MemList; 462161633Srwatson 463173146Srwatson 464161633Srwatson FUNCTION_TRACE ("UtDeleteElementFromAllocList"); 465161633Srwatson 466161633Srwatson 467161633Srwatson if (ListId > ACPI_MEM_LIST_MAX) 468161633Srwatson { 469161633Srwatson return_ACPI_STATUS (AE_BAD_PARAMETER); 470161633Srwatson } 471161633Srwatson 472161633Srwatson MemList = &AcpiGbl_MemoryLists[ListId]; 473161633Srwatson if (NULL == MemList->ListHead) 474161633Srwatson { 475161633Srwatson /* No allocations! */ 476161633Srwatson 477162506Srwatson _REPORT_ERROR (Module, Line, Component, 478162506Srwatson ("UtDeleteElementFromAllocList: Empty allocation list, nothing to free!\n")); 479162506Srwatson 480162626Srwatson return_ACPI_STATUS (AE_OK); 481162626Srwatson } 482162626Srwatson 483162626Srwatson 484168780Srwatson AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 485168780Srwatson 486168780Srwatson /* Unlink */ 487168780Srwatson 488168780Srwatson if (Address->Previous) 489168780Srwatson { 490168780Srwatson (Address->Previous)->Next = Address->Next; 491168780Srwatson } 492168780Srwatson else 493168780Srwatson { 494189279Srwatson MemList->ListHead = Address->Next; 495168780Srwatson } 496168780Srwatson 497168780Srwatson if (Address->Next) 498168780Srwatson { 499168780Srwatson (Address->Next)->Previous = Address->Previous; 500168780Srwatson } 501168780Srwatson 502168780Srwatson 503168780Srwatson /* Mark the segment as deleted */ 504168780Srwatson 505168780Srwatson MEMSET (&Address->UserSpace, 0xEA, Address->Size); 506171540Srwatson 507171540Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size %X\n", Address->Size)); 508171540Srwatson 509171540Srwatson AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 510171540Srwatson return_ACPI_STATUS (AE_OK); 511171540Srwatson} 512171540Srwatson 513171540Srwatson 514171540Srwatson/******************************************************************************* 515171540Srwatson * 516185573Srwatson * FUNCTION: AcpiUtDumpAllocationInfo 517185573Srwatson * 518185573Srwatson * PARAMETERS: 519185573Srwatson * 520185573Srwatson * RETURN: None 521185573Srwatson * 522185573Srwatson * DESCRIPTION: Print some info about the outstanding allocations. 523185573Srwatson * 524185573Srwatson ******************************************************************************/ 525185573Srwatson 526185573Srwatsonvoid 527185573SrwatsonAcpiUtDumpAllocationInfo ( 528185573Srwatson void) 529185573Srwatson{ 530185573Srwatson/* 531185573Srwatson ACPI_MEMORY_LIST *MemList; 532185573Srwatson*/ 533185573Srwatson 534185573Srwatson FUNCTION_TRACE ("UtDumpAllocationInfo"); 535185573Srwatson 536185573Srwatson/* 537185573Srwatson ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 538185573Srwatson ("%30s: %4d (%3d Kb)\n", "Current allocations", 539185573Srwatson MemList->CurrentCount, 540185573Srwatson ROUND_UP_TO_1K (MemList->CurrentSize))); 541185573Srwatson 542185573Srwatson ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 543185573Srwatson ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 544185573Srwatson MemList->MaxConcurrentCount, 545185573Srwatson ROUND_UP_TO_1K (MemList->MaxConcurrentSize))); 546185573Srwatson 547185573Srwatson 548185573Srwatson ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 549185573Srwatson ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 550185573Srwatson RunningObjectCount, 551185573Srwatson ROUND_UP_TO_1K (RunningObjectSize))); 552185573Srwatson 553186647Srwatson ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 554186647Srwatson ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 555189279Srwatson RunningAllocCount, 556189279Srwatson ROUND_UP_TO_1K (RunningAllocSize))); 557161633Srwatson 558186647Srwatson 559161633Srwatson ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 560186647Srwatson ("%30s: %4d (%3d Kb)\n", "Current Nodes", 561186647Srwatson AcpiGbl_CurrentNodeCount, 562186647Srwatson ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize))); 563186647Srwatson 564186647Srwatson ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 565186647Srwatson ("%30s: %4d (%3d Kb)\n", "Max Nodes", 566186647Srwatson AcpiGbl_MaxConcurrentNodeCount, 567186647Srwatson ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount * sizeof (ACPI_NAMESPACE_NODE))))); 568155131Srwatson*/ 569155131Srwatson return_VOID; 570186647Srwatson} 571186647Srwatson 572186647Srwatson 573186647Srwatson/******************************************************************************* 574186647Srwatson * 575155131Srwatson * FUNCTION: AcpiUtDumpCurrentAllocations 576155131Srwatson * 577186647Srwatson * PARAMETERS: Component - Component(s) to dump info for. 578186647Srwatson * Module - Module to dump info for. NULL means all. 579186647Srwatson * 580186647Srwatson * RETURN: None 581186647Srwatson * 582186647Srwatson * DESCRIPTION: Print a list of all outstanding allocations. 583186647Srwatson * 584155131Srwatson ******************************************************************************/ 585186647Srwatson 586186647Srwatsonvoid 587186647SrwatsonAcpiUtDumpCurrentAllocations ( 588186647Srwatson UINT32 Component, 589186647Srwatson NATIVE_CHAR *Module) 590186647Srwatson{ 591186647Srwatson ACPI_DEBUG_MEM_BLOCK *Element; 592186647Srwatson UINT32 i; 593186647Srwatson 594186647Srwatson 595186647Srwatson FUNCTION_TRACE ("UtDumpCurrentAllocations"); 596186647Srwatson 597186647Srwatson 598186647Srwatson Element = AcpiGbl_MemoryLists[0].ListHead; 599186647Srwatson if (Element == NULL) 600155131Srwatson { 601155131Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 602155131Srwatson "No outstanding allocations.\n")); 603155131Srwatson return_VOID; 604186647Srwatson } 605186647Srwatson 606186647Srwatson 607186647Srwatson /* 608186647Srwatson * Walk the allocation list. 609186647Srwatson */ 610186647Srwatson AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 611186647Srwatson 612186647Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 613186647Srwatson "Outstanding allocations:\n")); 614186647Srwatson 615186647Srwatson for (i = 1; ; i++) /* Just a counter */ 616186647Srwatson { 617186647Srwatson if ((Element->Component & Component) && 618186647Srwatson ((Module == NULL) || (0 == STRCMP (Module, Element->Module)))) 619186647Srwatson { 620186647Srwatson ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 621186647Srwatson "%p Len %04lX %9.9s-%ld", 622186647Srwatson &Element->UserSpace, Element->Size, Element->Module, 623186647Srwatson Element->Line)); 624186647Srwatson 625186647Srwatson /* Most of the elements will be internal objects. */ 626186647Srwatson 627186647Srwatson switch (((ACPI_OPERAND_OBJECT *) 628186647Srwatson (&Element->UserSpace))->Common.DataType) 629186647Srwatson { 630186647Srwatson case ACPI_DESC_TYPE_INTERNAL: 631186647Srwatson ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, 632186647Srwatson " ObjType %s", 633186647Srwatson AcpiUtGetTypeName (((ACPI_OPERAND_OBJECT *)(&Element->UserSpace))->Common.Type))); 634186647Srwatson break; 635186647Srwatson 636186647Srwatson case ACPI_DESC_TYPE_PARSER: 637155131Srwatson ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, 638186647Srwatson " ParseObj Opcode %04X", 639186647Srwatson ((ACPI_PARSE_OBJECT *)(&Element->UserSpace))->Opcode)); 640186647Srwatson break; 641186647Srwatson 642186647Srwatson case ACPI_DESC_TYPE_NAMED: 643186647Srwatson ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, 644186647Srwatson " Node %4.4s", 645186647Srwatson &((ACPI_NAMESPACE_NODE *)(&Element->UserSpace))->Name)); 646186647Srwatson break; 647186647Srwatson 648186647Srwatson case ACPI_DESC_TYPE_STATE: 649186647Srwatson ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, 650186647Srwatson " StateObj")); 651186647Srwatson break; 652186647Srwatson } 653186647Srwatson 654186647Srwatson ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, "\n")); 655186647Srwatson } 656186647Srwatson 657186647Srwatson if (Element->Next == NULL) 658186647Srwatson { 659 break; 660 } 661 662 Element = Element->Next; 663 } 664 665 AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 666 667 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 668 "Total number of unfreed allocations = %d(%X)\n", i,i)); 669 670 671 return_VOID; 672 673} 674 675 676/******************************************************************************* 677 * 678 * FUNCTION: AcpiUtAllocate 679 * 680 * PARAMETERS: Size - Size of the allocation 681 * Component - Component type of caller 682 * Module - Source file name of caller 683 * Line - Line number of caller 684 * 685 * RETURN: Address of the allocated memory on success, NULL on failure. 686 * 687 * DESCRIPTION: The subsystem's equivalent of malloc. 688 * 689 ******************************************************************************/ 690 691void * 692AcpiUtAllocate ( 693 UINT32 Size, 694 UINT32 Component, 695 NATIVE_CHAR *Module, 696 UINT32 Line) 697{ 698 ACPI_DEBUG_MEM_BLOCK *Address; 699 ACPI_STATUS Status; 700 701 702 FUNCTION_TRACE_U32 ("UtAllocate", Size); 703 704 705 /* Check for an inadvertent size of zero bytes */ 706 707 if (!Size) 708 { 709 _REPORT_ERROR (Module, Line, Component, 710 ("UtAllocate: Attempt to allocate zero bytes\n")); 711 Size = 1; 712 } 713 714 Address = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_BLOCK)); 715 if (!Address) 716 { 717 /* Report allocation error */ 718 719 _REPORT_ERROR (Module, Line, Component, 720 ("UtAllocate: Could not allocate size %X\n", Size)); 721 722 return_PTR (NULL); 723 } 724 725 Status = AcpiUtAddElementToAllocList (ACPI_MEM_LIST_GLOBAL, Address, Size, 726 MEM_MALLOC, Component, Module, Line); 727 if (ACPI_FAILURE (Status)) 728 { 729 AcpiOsFree (Address); 730 return_PTR (NULL); 731 } 732 733 AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].TotalAllocated++; 734 AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].CurrentTotalSize += Size; 735 736 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", Address, Size)); 737 738 return_PTR ((void *) &Address->UserSpace); 739} 740 741 742/******************************************************************************* 743 * 744 * FUNCTION: AcpiUtCallocate 745 * 746 * PARAMETERS: Size - Size of the allocation 747 * Component - Component type of caller 748 * Module - Source file name of caller 749 * Line - Line number of caller 750 * 751 * RETURN: Address of the allocated memory on success, NULL on failure. 752 * 753 * DESCRIPTION: Subsystem equivalent of calloc. 754 * 755 ******************************************************************************/ 756 757void * 758AcpiUtCallocate ( 759 UINT32 Size, 760 UINT32 Component, 761 NATIVE_CHAR *Module, 762 UINT32 Line) 763{ 764 ACPI_DEBUG_MEM_BLOCK *Address; 765 ACPI_STATUS Status; 766 767 768 FUNCTION_TRACE_U32 ("UtCallocate", Size); 769 770 771 /* Check for an inadvertent size of zero bytes */ 772 773 if (!Size) 774 { 775 _REPORT_ERROR (Module, Line, Component, 776 ("UtCallocate: Attempt to allocate zero bytes\n")); 777 return_PTR (NULL); 778 } 779 780 781 Address = AcpiOsCallocate (Size + sizeof (ACPI_DEBUG_MEM_BLOCK)); 782 if (!Address) 783 { 784 /* Report allocation error */ 785 786 _REPORT_ERROR (Module, Line, Component, 787 ("UtCallocate: Could not allocate size %X\n", Size)); 788 return_PTR (NULL); 789 } 790 791 Status = AcpiUtAddElementToAllocList (ACPI_MEM_LIST_GLOBAL, Address, Size, 792 MEM_CALLOC, Component, Module, Line); 793 if (ACPI_FAILURE (Status)) 794 { 795 AcpiOsFree (Address); 796 return_PTR (NULL); 797 } 798 799 AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].TotalAllocated++; 800 AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].CurrentTotalSize += Size; 801 802 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", Address, Size)); 803 return_PTR ((void *) &Address->UserSpace); 804} 805 806 807/******************************************************************************* 808 * 809 * FUNCTION: AcpiUtFree 810 * 811 * PARAMETERS: Address - Address of the memory to deallocate 812 * Component - Component type of caller 813 * Module - Source file name of caller 814 * Line - Line number of caller 815 * 816 * RETURN: None 817 * 818 * DESCRIPTION: Frees the memory at Address 819 * 820 ******************************************************************************/ 821 822void 823AcpiUtFree ( 824 void *Address, 825 UINT32 Component, 826 NATIVE_CHAR *Module, 827 UINT32 Line) 828{ 829 ACPI_DEBUG_MEM_BLOCK *DebugBlock; 830 831 832 FUNCTION_TRACE_PTR ("UtFree", Address); 833 834 835 if (NULL == Address) 836 { 837 _REPORT_ERROR (Module, Line, Component, 838 ("AcpiUtFree: Trying to delete a NULL address\n")); 839 840 return_VOID; 841 } 842 843 DebugBlock = (ACPI_DEBUG_MEM_BLOCK *) 844 (((char *) Address) - sizeof (ACPI_DEBUG_MEM_HEADER)); 845 846 AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].TotalFreed++; 847 AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].CurrentTotalSize -= DebugBlock->Size; 848 849 AcpiUtDeleteElementFromAllocList (ACPI_MEM_LIST_GLOBAL, DebugBlock, 850 Component, Module, Line); 851 AcpiOsFree (DebugBlock); 852 853 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Address)); 854 855 return_VOID; 856} 857 858#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ 859 860