2018-03-15 02:13:07 +03:00
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2012-10-31 06:25:05 +04:00
/******************************************************************************
*
* Module Name : utcache - local cache allocation routines
*
2022-04-11 21:54:22 +03:00
* Copyright ( C ) 2000 - 2022 , Intel Corp .
2012-10-31 06:25:05 +04:00
*
2018-03-15 02:13:07 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-10-31 06:25:05 +04:00
# include <acpi/acpi.h>
# include "accommon.h"
# define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ( " utcache " )
# ifdef ACPI_USE_LOCAL_CACHE
/*******************************************************************************
*
* FUNCTION : acpi_os_create_cache
*
* PARAMETERS : cache_name - Ascii name for the cache
* object_size - Size of each cached object
* max_depth - Maximum depth of the cache ( in objects )
* return_cache - Where the new cache object is returned
*
* RETURN : Status
*
* DESCRIPTION : Create a cache object
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
acpi_status
acpi_os_create_cache ( char * cache_name ,
u16 object_size ,
2013-10-29 05:30:22 +04:00
u16 max_depth , struct acpi_memory_list * * return_cache )
2012-10-31 06:25:05 +04:00
{
struct acpi_memory_list * cache ;
ACPI_FUNCTION_ENTRY ( ) ;
2017-04-26 11:19:10 +03:00
if ( ! cache_name | | ! return_cache | | ! object_size ) {
2012-10-31 06:25:05 +04:00
return ( AE_BAD_PARAMETER ) ;
}
/* Create the cache object */
cache = acpi_os_allocate ( sizeof ( struct acpi_memory_list ) ) ;
if ( ! cache ) {
return ( AE_NO_MEMORY ) ;
}
/* Populate the cache object and return it */
2015-07-01 09:45:11 +03:00
memset ( cache , 0 , sizeof ( struct acpi_memory_list ) ) ;
2012-10-31 06:25:05 +04:00
cache - > list_name = cache_name ;
cache - > object_size = object_size ;
cache - > max_depth = max_depth ;
* return_cache = cache ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_os_purge_cache
*
* PARAMETERS : cache - Handle to cache object
*
* RETURN : Status
*
* DESCRIPTION : Free all objects within the requested cache .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-05-05 07:57:53 +03:00
acpi_status acpi_os_purge_cache ( struct acpi_memory_list * cache )
2012-10-31 06:25:05 +04:00
{
2013-03-08 13:21:02 +04:00
void * next ;
2012-10-31 06:25:05 +04:00
acpi_status status ;
ACPI_FUNCTION_ENTRY ( ) ;
if ( ! cache ) {
return ( AE_BAD_PARAMETER ) ;
}
status = acpi_ut_acquire_mutex ( ACPI_MTX_CACHES ) ;
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
/* Walk the list of objects in this cache */
while ( cache - > list_head ) {
/* Delete and unlink one cached state object */
2013-03-08 13:21:54 +04:00
next = ACPI_GET_DESCRIPTOR_PTR ( cache - > list_head ) ;
2012-10-31 06:25:05 +04:00
ACPI_FREE ( cache - > list_head ) ;
cache - > list_head = next ;
cache - > current_depth - - ;
}
( void ) acpi_ut_release_mutex ( ACPI_MTX_CACHES ) ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_os_delete_cache
*
* PARAMETERS : cache - Handle to cache object
*
* RETURN : Status
*
* DESCRIPTION : Free all objects within the requested cache and delete the
* cache object .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-05-05 07:57:53 +03:00
acpi_status acpi_os_delete_cache ( struct acpi_memory_list * cache )
2012-10-31 06:25:05 +04:00
{
acpi_status status ;
ACPI_FUNCTION_ENTRY ( ) ;
/* Purge all objects in the cache */
status = acpi_os_purge_cache ( cache ) ;
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
/* Now we can delete the cache object */
acpi_os_free ( cache ) ;
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_os_release_object
*
* PARAMETERS : cache - Handle to cache object
* object - The object to be released
*
* RETURN : None
*
2012-10-31 06:26:55 +04:00
* DESCRIPTION : Release an object to the specified cache . If cache is full ,
2012-10-31 06:25:05 +04:00
* the object is deleted .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-05-05 07:57:53 +03:00
acpi_status acpi_os_release_object ( struct acpi_memory_list * cache , void * object )
2012-10-31 06:25:05 +04:00
{
acpi_status status ;
ACPI_FUNCTION_ENTRY ( ) ;
if ( ! cache | | ! object ) {
return ( AE_BAD_PARAMETER ) ;
}
/* If cache is full, just free this object */
if ( cache - > current_depth > = cache - > max_depth ) {
ACPI_FREE ( object ) ;
ACPI_MEM_TRACKING ( cache - > total_freed + + ) ;
}
/* Otherwise put this object back into the cache */
else {
status = acpi_ut_acquire_mutex ( ACPI_MTX_CACHES ) ;
if ( ACPI_FAILURE ( status ) ) {
return ( status ) ;
}
/* Mark the object as cached */
2015-07-01 09:45:11 +03:00
memset ( object , 0xCA , cache - > object_size ) ;
2012-10-31 06:25:05 +04:00
ACPI_SET_DESCRIPTOR_TYPE ( object , ACPI_DESC_TYPE_CACHED ) ;
/* Put the object at the head of the cache list */
2013-03-08 13:21:54 +04:00
ACPI_SET_DESCRIPTOR_PTR ( object , cache - > list_head ) ;
2012-10-31 06:25:05 +04:00
cache - > list_head = object ;
cache - > current_depth + + ;
( void ) acpi_ut_release_mutex ( ACPI_MTX_CACHES ) ;
}
return ( AE_OK ) ;
}
/*******************************************************************************
*
* FUNCTION : acpi_os_acquire_object
*
* PARAMETERS : cache - Handle to cache object
*
2012-10-31 06:26:55 +04:00
* RETURN : the acquired object . NULL on error
2012-10-31 06:25:05 +04:00
*
2012-10-31 06:26:55 +04:00
* DESCRIPTION : Get an object from the specified cache . If cache is empty ,
2012-10-31 06:25:05 +04:00
* the object is allocated .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void * acpi_os_acquire_object ( struct acpi_memory_list * cache )
{
acpi_status status ;
void * object ;
2016-02-19 09:17:43 +03:00
ACPI_FUNCTION_TRACE ( os_acquire_object ) ;
2012-10-31 06:25:05 +04:00
if ( ! cache ) {
2014-01-08 09:43:12 +04:00
return_PTR ( NULL ) ;
2012-10-31 06:25:05 +04:00
}
status = acpi_ut_acquire_mutex ( ACPI_MTX_CACHES ) ;
if ( ACPI_FAILURE ( status ) ) {
2014-01-08 09:43:12 +04:00
return_PTR ( NULL ) ;
2012-10-31 06:25:05 +04:00
}
ACPI_MEM_TRACKING ( cache - > requests + + ) ;
/* Check the cache first */
if ( cache - > list_head ) {
/* There is an object available, use it */
object = cache - > list_head ;
2013-03-08 13:21:54 +04:00
cache - > list_head = ACPI_GET_DESCRIPTOR_PTR ( object ) ;
2012-10-31 06:25:05 +04:00
cache - > current_depth - - ;
ACPI_MEM_TRACKING ( cache - > hits + + ) ;
2018-02-16 00:09:28 +03:00
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_EXEC ,
" %s: Object %p from %s cache \n " ,
ACPI_GET_FUNCTION_NAME , object ,
cache - > list_name ) ) ;
2012-10-31 06:25:05 +04:00
status = acpi_ut_release_mutex ( ACPI_MTX_CACHES ) ;
if ( ACPI_FAILURE ( status ) ) {
2014-01-08 09:43:12 +04:00
return_PTR ( NULL ) ;
2012-10-31 06:25:05 +04:00
}
/* Clear (zero) the previously used Object */
2015-07-01 09:45:11 +03:00
memset ( object , 0 , cache - > object_size ) ;
2012-10-31 06:25:05 +04:00
} else {
/* The cache is empty, create a new object */
ACPI_MEM_TRACKING ( cache - > total_allocated + + ) ;
# ifdef ACPI_DBG_TRACK_ALLOCATIONS
if ( ( cache - > total_allocated - cache - > total_freed ) >
cache - > max_occupied ) {
cache - > max_occupied =
cache - > total_allocated - cache - > total_freed ;
}
# endif
/* Avoid deadlock with ACPI_ALLOCATE_ZEROED */
status = acpi_ut_release_mutex ( ACPI_MTX_CACHES ) ;
if ( ACPI_FAILURE ( status ) ) {
2014-01-08 09:43:12 +04:00
return_PTR ( NULL ) ;
2012-10-31 06:25:05 +04:00
}
object = ACPI_ALLOCATE_ZEROED ( cache - > object_size ) ;
if ( ! object ) {
2014-01-08 09:43:12 +04:00
return_PTR ( NULL ) ;
2012-10-31 06:25:05 +04:00
}
}
2014-01-08 09:43:12 +04:00
return_PTR ( object ) ;
2012-10-31 06:25:05 +04:00
}
# endif /* ACPI_USE_LOCAL_CACHE */