Home | History | Annotate | Line # | Download | only in utilities
utalloc.c revision 1.1.1.2
      1 /******************************************************************************
      2  *
      3  * Module Name: utalloc - local memory allocation routines
      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.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #define __UTALLOC_C__
     45 
     46 #include "acpi.h"
     47 #include "accommon.h"
     48 #include "acdebug.h"
     49 
     50 #define _COMPONENT          ACPI_UTILITIES
     51         ACPI_MODULE_NAME    ("utalloc")
     52 
     53 
     54 /*******************************************************************************
     55  *
     56  * FUNCTION:    AcpiUtCreateCaches
     57  *
     58  * PARAMETERS:  None
     59  *
     60  * RETURN:      Status
     61  *
     62  * DESCRIPTION: Create all local caches
     63  *
     64  ******************************************************************************/
     65 
     66 ACPI_STATUS
     67 AcpiUtCreateCaches (
     68     void)
     69 {
     70     ACPI_STATUS             Status;
     71 
     72 
     73     /* Object Caches, for frequently used objects */
     74 
     75     Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
     76                 ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache);
     77     if (ACPI_FAILURE (Status))
     78     {
     79         return (Status);
     80     }
     81 
     82     Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE),
     83                 ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache);
     84     if (ACPI_FAILURE (Status))
     85     {
     86         return (Status);
     87     }
     88 
     89     Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON),
     90                 ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache);
     91     if (ACPI_FAILURE (Status))
     92     {
     93         return (Status);
     94     }
     95 
     96     Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED),
     97                 ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache);
     98     if (ACPI_FAILURE (Status))
     99     {
    100         return (Status);
    101     }
    102 
    103     Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT),
    104                 ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache);
    105     if (ACPI_FAILURE (Status))
    106     {
    107         return (Status);
    108     }
    109 
    110 
    111 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    112 
    113     /* Memory allocation lists */
    114 
    115     Status = AcpiUtCreateList ("Acpi-Global", 0,
    116                 &AcpiGbl_GlobalList);
    117     if (ACPI_FAILURE (Status))
    118     {
    119         return (Status);
    120     }
    121 
    122     Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
    123                 &AcpiGbl_NsNodeList);
    124     if (ACPI_FAILURE (Status))
    125     {
    126         return (Status);
    127     }
    128 #endif
    129 
    130     return (AE_OK);
    131 }
    132 
    133 
    134 /*******************************************************************************
    135  *
    136  * FUNCTION:    AcpiUtDeleteCaches
    137  *
    138  * PARAMETERS:  None
    139  *
    140  * RETURN:      Status
    141  *
    142  * DESCRIPTION: Purge and delete all local caches
    143  *
    144  ******************************************************************************/
    145 
    146 ACPI_STATUS
    147 AcpiUtDeleteCaches (
    148     void)
    149 {
    150 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    151     char                    Buffer[7];
    152 
    153     if (AcpiGbl_DisplayFinalMemStats)
    154     {
    155         ACPI_STRCPY (Buffer, "MEMORY");
    156         (void) AcpiDbDisplayStatistics (Buffer);
    157     }
    158 #endif
    159 
    160     (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache);
    161     AcpiGbl_NamespaceCache = NULL;
    162 
    163     (void) AcpiOsDeleteCache (AcpiGbl_StateCache);
    164     AcpiGbl_StateCache = NULL;
    165 
    166     (void) AcpiOsDeleteCache (AcpiGbl_OperandCache);
    167     AcpiGbl_OperandCache = NULL;
    168 
    169     (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache);
    170     AcpiGbl_PsNodeCache = NULL;
    171 
    172     (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache);
    173     AcpiGbl_PsNodeExtCache = NULL;
    174 
    175 
    176 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    177 
    178     /* Debug only - display leftover memory allocation, if any */
    179 
    180     AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL);
    181 
    182     /* Free memory lists */
    183 
    184     AcpiOsFree (AcpiGbl_GlobalList);
    185     AcpiGbl_GlobalList = NULL;
    186 
    187     AcpiOsFree (AcpiGbl_NsNodeList);
    188     AcpiGbl_NsNodeList = NULL;
    189 #endif
    190 
    191     return (AE_OK);
    192 }
    193 
    194 
    195 /*******************************************************************************
    196  *
    197  * FUNCTION:    AcpiUtValidateBuffer
    198  *
    199  * PARAMETERS:  Buffer              - Buffer descriptor to be validated
    200  *
    201  * RETURN:      Status
    202  *
    203  * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER
    204  *
    205  ******************************************************************************/
    206 
    207 ACPI_STATUS
    208 AcpiUtValidateBuffer (
    209     ACPI_BUFFER             *Buffer)
    210 {
    211 
    212     /* Obviously, the structure pointer must be valid */
    213 
    214     if (!Buffer)
    215     {
    216         return (AE_BAD_PARAMETER);
    217     }
    218 
    219     /* Special semantics for the length */
    220 
    221     if ((Buffer->Length == ACPI_NO_BUFFER)              ||
    222         (Buffer->Length == ACPI_ALLOCATE_BUFFER)        ||
    223         (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER))
    224     {
    225         return (AE_OK);
    226     }
    227 
    228     /* Length is valid, the buffer pointer must be also */
    229 
    230     if (!Buffer->Pointer)
    231     {
    232         return (AE_BAD_PARAMETER);
    233     }
    234 
    235     return (AE_OK);
    236 }
    237 
    238 
    239 /*******************************************************************************
    240  *
    241  * FUNCTION:    AcpiUtInitializeBuffer
    242  *
    243  * PARAMETERS:  Buffer              - Buffer to be validated
    244  *              RequiredLength      - Length needed
    245  *
    246  * RETURN:      Status
    247  *
    248  * DESCRIPTION: Validate that the buffer is of the required length or
    249  *              allocate a new buffer. Returned buffer is always zeroed.
    250  *
    251  ******************************************************************************/
    252 
    253 ACPI_STATUS
    254 AcpiUtInitializeBuffer (
    255     ACPI_BUFFER             *Buffer,
    256     ACPI_SIZE               RequiredLength)
    257 {
    258     ACPI_SIZE               InputBufferLength;
    259 
    260 
    261     /* Parameter validation */
    262 
    263     if (!Buffer || !RequiredLength)
    264     {
    265         return (AE_BAD_PARAMETER);
    266     }
    267 
    268     /*
    269      * Buffer->Length is used as both an input and output parameter. Get the
    270      * input actual length and set the output required buffer length.
    271      */
    272     InputBufferLength = Buffer->Length;
    273     Buffer->Length = RequiredLength;
    274 
    275     /*
    276      * The input buffer length contains the actual buffer length, or the type
    277      * of buffer to be allocated by this routine.
    278      */
    279     switch (InputBufferLength)
    280     {
    281     case ACPI_NO_BUFFER:
    282 
    283         /* Return the exception (and the required buffer length) */
    284 
    285         return (AE_BUFFER_OVERFLOW);
    286 
    287     case ACPI_ALLOCATE_BUFFER:
    288 
    289         /* Allocate a new buffer */
    290 
    291         Buffer->Pointer = AcpiOsAllocate (RequiredLength);
    292         break;
    293 
    294     case ACPI_ALLOCATE_LOCAL_BUFFER:
    295 
    296         /* Allocate a new buffer with local interface to allow tracking */
    297 
    298         Buffer->Pointer = ACPI_ALLOCATE (RequiredLength);
    299         break;
    300 
    301     default:
    302 
    303         /* Existing buffer: Validate the size of the buffer */
    304 
    305         if (InputBufferLength < RequiredLength)
    306         {
    307             return (AE_BUFFER_OVERFLOW);
    308         }
    309         break;
    310     }
    311 
    312     /* Validate allocation from above or input buffer pointer */
    313 
    314     if (!Buffer->Pointer)
    315     {
    316         return (AE_NO_MEMORY);
    317     }
    318 
    319     /* Have a valid buffer, clear it */
    320 
    321     ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength);
    322     return (AE_OK);
    323 }
    324 
    325 
    326 /*******************************************************************************
    327  *
    328  * FUNCTION:    AcpiUtAllocate
    329  *
    330  * PARAMETERS:  Size                - Size of the allocation
    331  *              Component           - Component type of caller
    332  *              Module              - Source file name of caller
    333  *              Line                - Line number of caller
    334  *
    335  * RETURN:      Address of the allocated memory on success, NULL on failure.
    336  *
    337  * DESCRIPTION: Subsystem equivalent of malloc.
    338  *
    339  ******************************************************************************/
    340 
    341 void *
    342 AcpiUtAllocate (
    343     ACPI_SIZE               Size,
    344     UINT32                  Component,
    345     const char              *Module,
    346     UINT32                  Line)
    347 {
    348     void                    *Allocation;
    349 
    350 
    351     ACPI_FUNCTION_TRACE_U32 (UtAllocate, Size);
    352 
    353 
    354     /* Check for an inadvertent size of zero bytes */
    355 
    356     if (!Size)
    357     {
    358         ACPI_WARNING ((Module, Line,
    359             "Attempt to allocate zero bytes, allocating 1 byte"));
    360         Size = 1;
    361     }
    362 
    363     Allocation = AcpiOsAllocate (Size);
    364     if (!Allocation)
    365     {
    366         /* Report allocation error */
    367 
    368         ACPI_WARNING ((Module, Line,
    369             "Could not allocate size %u", (UINT32) Size));
    370 
    371         return_PTR (NULL);
    372     }
    373 
    374     return_PTR (Allocation);
    375 }
    376 
    377 
    378 /*******************************************************************************
    379  *
    380  * FUNCTION:    AcpiUtAllocateZeroed
    381  *
    382  * PARAMETERS:  Size                - Size of the allocation
    383  *              Component           - Component type of caller
    384  *              Module              - Source file name of caller
    385  *              Line                - Line number of caller
    386  *
    387  * RETURN:      Address of the allocated memory on success, NULL on failure.
    388  *
    389  * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
    390  *
    391  ******************************************************************************/
    392 
    393 void *
    394 AcpiUtAllocateZeroed (
    395     ACPI_SIZE               Size,
    396     UINT32                  Component,
    397     const char              *Module,
    398     UINT32                  Line)
    399 {
    400     void                    *Allocation;
    401 
    402 
    403     ACPI_FUNCTION_ENTRY ();
    404 
    405 
    406     Allocation = AcpiUtAllocate (Size, Component, Module, Line);
    407     if (Allocation)
    408     {
    409         /* Clear the memory block */
    410 
    411         ACPI_MEMSET (Allocation, 0, Size);
    412     }
    413 
    414     return (Allocation);
    415 }
    416 
    417