1*a159c266SJung-uk Kim /****************************************************************************** 2*a159c266SJung-uk Kim * 3*a159c266SJung-uk Kim * Module Name: utcache - local cache allocation routines 4*a159c266SJung-uk Kim * 5*a159c266SJung-uk Kim *****************************************************************************/ 6*a159c266SJung-uk Kim 7*a159c266SJung-uk Kim /* 8*a159c266SJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9*a159c266SJung-uk Kim * All rights reserved. 10*a159c266SJung-uk Kim * 11*a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 13*a159c266SJung-uk Kim * are met: 14*a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*a159c266SJung-uk Kim * without modification. 17*a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*a159c266SJung-uk Kim * binary redistribution. 22*a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*a159c266SJung-uk Kim * from this software without specific prior written permission. 25*a159c266SJung-uk Kim * 26*a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*a159c266SJung-uk Kim * Software Foundation. 29*a159c266SJung-uk Kim * 30*a159c266SJung-uk Kim * NO WARRANTY 31*a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*a159c266SJung-uk Kim */ 43*a159c266SJung-uk Kim 44*a159c266SJung-uk Kim #define __UTCACHE_C__ 45*a159c266SJung-uk Kim 46*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 48*a159c266SJung-uk Kim 49*a159c266SJung-uk Kim #define _COMPONENT ACPI_UTILITIES 50*a159c266SJung-uk Kim ACPI_MODULE_NAME ("utcache") 51*a159c266SJung-uk Kim 52*a159c266SJung-uk Kim 53*a159c266SJung-uk Kim #ifdef ACPI_USE_LOCAL_CACHE 54*a159c266SJung-uk Kim /******************************************************************************* 55*a159c266SJung-uk Kim * 56*a159c266SJung-uk Kim * FUNCTION: AcpiOsCreateCache 57*a159c266SJung-uk Kim * 58*a159c266SJung-uk Kim * PARAMETERS: CacheName - Ascii name for the cache 59*a159c266SJung-uk Kim * ObjectSize - Size of each cached object 60*a159c266SJung-uk Kim * MaxDepth - Maximum depth of the cache (in objects) 61*a159c266SJung-uk Kim * ReturnCache - Where the new cache object is returned 62*a159c266SJung-uk Kim * 63*a159c266SJung-uk Kim * RETURN: Status 64*a159c266SJung-uk Kim * 65*a159c266SJung-uk Kim * DESCRIPTION: Create a cache object 66*a159c266SJung-uk Kim * 67*a159c266SJung-uk Kim ******************************************************************************/ 68*a159c266SJung-uk Kim 69*a159c266SJung-uk Kim ACPI_STATUS 70*a159c266SJung-uk Kim AcpiOsCreateCache ( 71*a159c266SJung-uk Kim char *CacheName, 72*a159c266SJung-uk Kim UINT16 ObjectSize, 73*a159c266SJung-uk Kim UINT16 MaxDepth, 74*a159c266SJung-uk Kim ACPI_MEMORY_LIST **ReturnCache) 75*a159c266SJung-uk Kim { 76*a159c266SJung-uk Kim ACPI_MEMORY_LIST *Cache; 77*a159c266SJung-uk Kim 78*a159c266SJung-uk Kim 79*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 80*a159c266SJung-uk Kim 81*a159c266SJung-uk Kim 82*a159c266SJung-uk Kim if (!CacheName || !ReturnCache || (ObjectSize < 16)) 83*a159c266SJung-uk Kim { 84*a159c266SJung-uk Kim return (AE_BAD_PARAMETER); 85*a159c266SJung-uk Kim } 86*a159c266SJung-uk Kim 87*a159c266SJung-uk Kim /* Create the cache object */ 88*a159c266SJung-uk Kim 89*a159c266SJung-uk Kim Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST)); 90*a159c266SJung-uk Kim if (!Cache) 91*a159c266SJung-uk Kim { 92*a159c266SJung-uk Kim return (AE_NO_MEMORY); 93*a159c266SJung-uk Kim } 94*a159c266SJung-uk Kim 95*a159c266SJung-uk Kim /* Populate the cache object and return it */ 96*a159c266SJung-uk Kim 97*a159c266SJung-uk Kim ACPI_MEMSET (Cache, 0, sizeof (ACPI_MEMORY_LIST)); 98*a159c266SJung-uk Kim Cache->LinkOffset = 8; 99*a159c266SJung-uk Kim Cache->ListName = CacheName; 100*a159c266SJung-uk Kim Cache->ObjectSize = ObjectSize; 101*a159c266SJung-uk Kim Cache->MaxDepth = MaxDepth; 102*a159c266SJung-uk Kim 103*a159c266SJung-uk Kim *ReturnCache = Cache; 104*a159c266SJung-uk Kim return (AE_OK); 105*a159c266SJung-uk Kim } 106*a159c266SJung-uk Kim 107*a159c266SJung-uk Kim 108*a159c266SJung-uk Kim /******************************************************************************* 109*a159c266SJung-uk Kim * 110*a159c266SJung-uk Kim * FUNCTION: AcpiOsPurgeCache 111*a159c266SJung-uk Kim * 112*a159c266SJung-uk Kim * PARAMETERS: Cache - Handle to cache object 113*a159c266SJung-uk Kim * 114*a159c266SJung-uk Kim * RETURN: Status 115*a159c266SJung-uk Kim * 116*a159c266SJung-uk Kim * DESCRIPTION: Free all objects within the requested cache. 117*a159c266SJung-uk Kim * 118*a159c266SJung-uk Kim ******************************************************************************/ 119*a159c266SJung-uk Kim 120*a159c266SJung-uk Kim ACPI_STATUS 121*a159c266SJung-uk Kim AcpiOsPurgeCache ( 122*a159c266SJung-uk Kim ACPI_MEMORY_LIST *Cache) 123*a159c266SJung-uk Kim { 124*a159c266SJung-uk Kim char *Next; 125*a159c266SJung-uk Kim ACPI_STATUS Status; 126*a159c266SJung-uk Kim 127*a159c266SJung-uk Kim 128*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 129*a159c266SJung-uk Kim 130*a159c266SJung-uk Kim 131*a159c266SJung-uk Kim if (!Cache) 132*a159c266SJung-uk Kim { 133*a159c266SJung-uk Kim return (AE_BAD_PARAMETER); 134*a159c266SJung-uk Kim } 135*a159c266SJung-uk Kim 136*a159c266SJung-uk Kim Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 137*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 138*a159c266SJung-uk Kim { 139*a159c266SJung-uk Kim return (Status); 140*a159c266SJung-uk Kim } 141*a159c266SJung-uk Kim 142*a159c266SJung-uk Kim /* Walk the list of objects in this cache */ 143*a159c266SJung-uk Kim 144*a159c266SJung-uk Kim while (Cache->ListHead) 145*a159c266SJung-uk Kim { 146*a159c266SJung-uk Kim /* Delete and unlink one cached state object */ 147*a159c266SJung-uk Kim 148*a159c266SJung-uk Kim Next = *(ACPI_CAST_INDIRECT_PTR (char, 149*a159c266SJung-uk Kim &(((char *) Cache->ListHead)[Cache->LinkOffset]))); 150*a159c266SJung-uk Kim ACPI_FREE (Cache->ListHead); 151*a159c266SJung-uk Kim 152*a159c266SJung-uk Kim Cache->ListHead = Next; 153*a159c266SJung-uk Kim Cache->CurrentDepth--; 154*a159c266SJung-uk Kim } 155*a159c266SJung-uk Kim 156*a159c266SJung-uk Kim (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 157*a159c266SJung-uk Kim return (AE_OK); 158*a159c266SJung-uk Kim } 159*a159c266SJung-uk Kim 160*a159c266SJung-uk Kim 161*a159c266SJung-uk Kim /******************************************************************************* 162*a159c266SJung-uk Kim * 163*a159c266SJung-uk Kim * FUNCTION: AcpiOsDeleteCache 164*a159c266SJung-uk Kim * 165*a159c266SJung-uk Kim * PARAMETERS: Cache - Handle to cache object 166*a159c266SJung-uk Kim * 167*a159c266SJung-uk Kim * RETURN: Status 168*a159c266SJung-uk Kim * 169*a159c266SJung-uk Kim * DESCRIPTION: Free all objects within the requested cache and delete the 170*a159c266SJung-uk Kim * cache object. 171*a159c266SJung-uk Kim * 172*a159c266SJung-uk Kim ******************************************************************************/ 173*a159c266SJung-uk Kim 174*a159c266SJung-uk Kim ACPI_STATUS 175*a159c266SJung-uk Kim AcpiOsDeleteCache ( 176*a159c266SJung-uk Kim ACPI_MEMORY_LIST *Cache) 177*a159c266SJung-uk Kim { 178*a159c266SJung-uk Kim ACPI_STATUS Status; 179*a159c266SJung-uk Kim 180*a159c266SJung-uk Kim 181*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 182*a159c266SJung-uk Kim 183*a159c266SJung-uk Kim 184*a159c266SJung-uk Kim /* Purge all objects in the cache */ 185*a159c266SJung-uk Kim 186*a159c266SJung-uk Kim Status = AcpiOsPurgeCache (Cache); 187*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 188*a159c266SJung-uk Kim { 189*a159c266SJung-uk Kim return (Status); 190*a159c266SJung-uk Kim } 191*a159c266SJung-uk Kim 192*a159c266SJung-uk Kim /* Now we can delete the cache object */ 193*a159c266SJung-uk Kim 194*a159c266SJung-uk Kim AcpiOsFree (Cache); 195*a159c266SJung-uk Kim return (AE_OK); 196*a159c266SJung-uk Kim } 197*a159c266SJung-uk Kim 198*a159c266SJung-uk Kim 199*a159c266SJung-uk Kim /******************************************************************************* 200*a159c266SJung-uk Kim * 201*a159c266SJung-uk Kim * FUNCTION: AcpiOsReleaseObject 202*a159c266SJung-uk Kim * 203*a159c266SJung-uk Kim * PARAMETERS: Cache - Handle to cache object 204*a159c266SJung-uk Kim * Object - The object to be released 205*a159c266SJung-uk Kim * 206*a159c266SJung-uk Kim * RETURN: None 207*a159c266SJung-uk Kim * 208*a159c266SJung-uk Kim * DESCRIPTION: Release an object to the specified cache. If cache is full, 209*a159c266SJung-uk Kim * the object is deleted. 210*a159c266SJung-uk Kim * 211*a159c266SJung-uk Kim ******************************************************************************/ 212*a159c266SJung-uk Kim 213*a159c266SJung-uk Kim ACPI_STATUS 214*a159c266SJung-uk Kim AcpiOsReleaseObject ( 215*a159c266SJung-uk Kim ACPI_MEMORY_LIST *Cache, 216*a159c266SJung-uk Kim void *Object) 217*a159c266SJung-uk Kim { 218*a159c266SJung-uk Kim ACPI_STATUS Status; 219*a159c266SJung-uk Kim 220*a159c266SJung-uk Kim 221*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 222*a159c266SJung-uk Kim 223*a159c266SJung-uk Kim 224*a159c266SJung-uk Kim if (!Cache || !Object) 225*a159c266SJung-uk Kim { 226*a159c266SJung-uk Kim return (AE_BAD_PARAMETER); 227*a159c266SJung-uk Kim } 228*a159c266SJung-uk Kim 229*a159c266SJung-uk Kim /* If cache is full, just free this object */ 230*a159c266SJung-uk Kim 231*a159c266SJung-uk Kim if (Cache->CurrentDepth >= Cache->MaxDepth) 232*a159c266SJung-uk Kim { 233*a159c266SJung-uk Kim ACPI_FREE (Object); 234*a159c266SJung-uk Kim ACPI_MEM_TRACKING (Cache->TotalFreed++); 235*a159c266SJung-uk Kim } 236*a159c266SJung-uk Kim 237*a159c266SJung-uk Kim /* Otherwise put this object back into the cache */ 238*a159c266SJung-uk Kim 239*a159c266SJung-uk Kim else 240*a159c266SJung-uk Kim { 241*a159c266SJung-uk Kim Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 242*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 243*a159c266SJung-uk Kim { 244*a159c266SJung-uk Kim return (Status); 245*a159c266SJung-uk Kim } 246*a159c266SJung-uk Kim 247*a159c266SJung-uk Kim /* Mark the object as cached */ 248*a159c266SJung-uk Kim 249*a159c266SJung-uk Kim ACPI_MEMSET (Object, 0xCA, Cache->ObjectSize); 250*a159c266SJung-uk Kim ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_CACHED); 251*a159c266SJung-uk Kim 252*a159c266SJung-uk Kim /* Put the object at the head of the cache list */ 253*a159c266SJung-uk Kim 254*a159c266SJung-uk Kim * (ACPI_CAST_INDIRECT_PTR (char, 255*a159c266SJung-uk Kim &(((char *) Object)[Cache->LinkOffset]))) = Cache->ListHead; 256*a159c266SJung-uk Kim Cache->ListHead = Object; 257*a159c266SJung-uk Kim Cache->CurrentDepth++; 258*a159c266SJung-uk Kim 259*a159c266SJung-uk Kim (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 260*a159c266SJung-uk Kim } 261*a159c266SJung-uk Kim 262*a159c266SJung-uk Kim return (AE_OK); 263*a159c266SJung-uk Kim } 264*a159c266SJung-uk Kim 265*a159c266SJung-uk Kim 266*a159c266SJung-uk Kim /******************************************************************************* 267*a159c266SJung-uk Kim * 268*a159c266SJung-uk Kim * FUNCTION: AcpiOsAcquireObject 269*a159c266SJung-uk Kim * 270*a159c266SJung-uk Kim * PARAMETERS: Cache - Handle to cache object 271*a159c266SJung-uk Kim * 272*a159c266SJung-uk Kim * RETURN: the acquired object. NULL on error 273*a159c266SJung-uk Kim * 274*a159c266SJung-uk Kim * DESCRIPTION: Get an object from the specified cache. If cache is empty, 275*a159c266SJung-uk Kim * the object is allocated. 276*a159c266SJung-uk Kim * 277*a159c266SJung-uk Kim ******************************************************************************/ 278*a159c266SJung-uk Kim 279*a159c266SJung-uk Kim void * 280*a159c266SJung-uk Kim AcpiOsAcquireObject ( 281*a159c266SJung-uk Kim ACPI_MEMORY_LIST *Cache) 282*a159c266SJung-uk Kim { 283*a159c266SJung-uk Kim ACPI_STATUS Status; 284*a159c266SJung-uk Kim void *Object; 285*a159c266SJung-uk Kim 286*a159c266SJung-uk Kim 287*a159c266SJung-uk Kim ACPI_FUNCTION_NAME (OsAcquireObject); 288*a159c266SJung-uk Kim 289*a159c266SJung-uk Kim 290*a159c266SJung-uk Kim if (!Cache) 291*a159c266SJung-uk Kim { 292*a159c266SJung-uk Kim return (NULL); 293*a159c266SJung-uk Kim } 294*a159c266SJung-uk Kim 295*a159c266SJung-uk Kim Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 296*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 297*a159c266SJung-uk Kim { 298*a159c266SJung-uk Kim return (NULL); 299*a159c266SJung-uk Kim } 300*a159c266SJung-uk Kim 301*a159c266SJung-uk Kim ACPI_MEM_TRACKING (Cache->Requests++); 302*a159c266SJung-uk Kim 303*a159c266SJung-uk Kim /* Check the cache first */ 304*a159c266SJung-uk Kim 305*a159c266SJung-uk Kim if (Cache->ListHead) 306*a159c266SJung-uk Kim { 307*a159c266SJung-uk Kim /* There is an object available, use it */ 308*a159c266SJung-uk Kim 309*a159c266SJung-uk Kim Object = Cache->ListHead; 310*a159c266SJung-uk Kim Cache->ListHead = *(ACPI_CAST_INDIRECT_PTR (char, 311*a159c266SJung-uk Kim &(((char *) Object)[Cache->LinkOffset]))); 312*a159c266SJung-uk Kim 313*a159c266SJung-uk Kim Cache->CurrentDepth--; 314*a159c266SJung-uk Kim 315*a159c266SJung-uk Kim ACPI_MEM_TRACKING (Cache->Hits++); 316*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 317*a159c266SJung-uk Kim "Object %p from %s cache\n", Object, Cache->ListName)); 318*a159c266SJung-uk Kim 319*a159c266SJung-uk Kim Status = AcpiUtReleaseMutex (ACPI_MTX_CACHES); 320*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 321*a159c266SJung-uk Kim { 322*a159c266SJung-uk Kim return (NULL); 323*a159c266SJung-uk Kim } 324*a159c266SJung-uk Kim 325*a159c266SJung-uk Kim /* Clear (zero) the previously used Object */ 326*a159c266SJung-uk Kim 327*a159c266SJung-uk Kim ACPI_MEMSET (Object, 0, Cache->ObjectSize); 328*a159c266SJung-uk Kim } 329*a159c266SJung-uk Kim else 330*a159c266SJung-uk Kim { 331*a159c266SJung-uk Kim /* The cache is empty, create a new object */ 332*a159c266SJung-uk Kim 333*a159c266SJung-uk Kim ACPI_MEM_TRACKING (Cache->TotalAllocated++); 334*a159c266SJung-uk Kim 335*a159c266SJung-uk Kim #ifdef ACPI_DBG_TRACK_ALLOCATIONS 336*a159c266SJung-uk Kim if ((Cache->TotalAllocated - Cache->TotalFreed) > Cache->MaxOccupied) 337*a159c266SJung-uk Kim { 338*a159c266SJung-uk Kim Cache->MaxOccupied = Cache->TotalAllocated - Cache->TotalFreed; 339*a159c266SJung-uk Kim } 340*a159c266SJung-uk Kim #endif 341*a159c266SJung-uk Kim 342*a159c266SJung-uk Kim /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ 343*a159c266SJung-uk Kim 344*a159c266SJung-uk Kim Status = AcpiUtReleaseMutex (ACPI_MTX_CACHES); 345*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 346*a159c266SJung-uk Kim { 347*a159c266SJung-uk Kim return (NULL); 348*a159c266SJung-uk Kim } 349*a159c266SJung-uk Kim 350*a159c266SJung-uk Kim Object = ACPI_ALLOCATE_ZEROED (Cache->ObjectSize); 351*a159c266SJung-uk Kim if (!Object) 352*a159c266SJung-uk Kim { 353*a159c266SJung-uk Kim return (NULL); 354*a159c266SJung-uk Kim } 355*a159c266SJung-uk Kim } 356*a159c266SJung-uk Kim 357*a159c266SJung-uk Kim return (Object); 358*a159c266SJung-uk Kim } 359*a159c266SJung-uk Kim #endif /* ACPI_USE_LOCAL_CACHE */ 360*a159c266SJung-uk Kim 361*a159c266SJung-uk Kim 362