📄 cmobject.c
字号:
/******************************************************************************
*
* Module Name: cmobject - ACPI object create/delete/size/cache routines
* $Revision: 1.1 $
*
*****************************************************************************/
/*
* Copyright (C) 2000, 2001 R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <acpi.h>
#define _COMPONENT ACPI_UTILITIES
MODULE_NAME ("cmobject")
/*******************************************************************************
*
* FUNCTION: _Cm_create_internal_object
*
* PARAMETERS: Address - Address of the memory to deallocate
* Component - Component type of caller
* Module - Source file name of caller
* Line - Line number of caller
* Type - ACPI Type of the new object
*
* RETURN: Object - The new object. Null on failure
*
* DESCRIPTION: Create and initialize a new internal object.
*
* NOTE: We always allocate the worst-case object descriptor because
* these objects are cached, and we want them to be
* one-size-satisifies-any-request. This in itself may not be
* the most memory efficient, but the efficiency of the object
* cache should more than make up for this!
*
******************************************************************************/
ACPI_OPERAND_OBJECT *
_cm_create_internal_object (
NATIVE_CHAR *module_name,
u32 line_number,
u32 component_id,
OBJECT_TYPE_INTERNAL type)
{
ACPI_OPERAND_OBJECT *object;
/* Allocate the raw object descriptor */
object = _cm_allocate_object_desc (module_name, line_number, component_id);
if (!object) {
/* Allocation failure */
return (NULL);
}
/* Save the object type in the object descriptor */
object->common.type = type;
/* Init the reference count */
object->common.reference_count = 1;
/* Any per-type initialization should go here */
return (object);
}
/*******************************************************************************
*
* FUNCTION: Acpi_cm_valid_internal_object
*
* PARAMETERS: Operand - Object to be validated
*
* RETURN: Validate a pointer to be an ACPI_OPERAND_OBJECT
*
******************************************************************************/
u8
acpi_cm_valid_internal_object (
void *object)
{
/* Check for a null pointer */
if (!object) {
return (FALSE);
}
/* Check for a pointer within one of the ACPI tables */
if (acpi_tb_system_table_pointer (object)) {
return (FALSE);
}
/* Check the descriptor type field */
if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) {
/* Not an ACPI internal object, do some further checking */
return (FALSE);
}
/* The object appears to be a valid ACPI_OPERAND_OBJECT */
return (TRUE);
}
/*******************************************************************************
*
* FUNCTION: _Cm_allocate_object_desc
*
* PARAMETERS: Module_name - Caller's module name (for error output)
* Line_number - Caller's line number (for error output)
* Component_id - Caller's component ID (for error output)
* Message - Error message to use on failure
*
* RETURN: Pointer to newly allocated object descriptor. Null on error
*
* DESCRIPTION: Allocate a new object descriptor. Gracefully handle
* error conditions.
*
******************************************************************************/
void *
_cm_allocate_object_desc (
NATIVE_CHAR *module_name,
u32 line_number,
u32 component_id)
{
ACPI_OPERAND_OBJECT *object;
acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
acpi_gbl_object_cache_requests++;
/* Check the cache first */
if (acpi_gbl_object_cache) {
/* There is an object available, use it */
object = acpi_gbl_object_cache;
acpi_gbl_object_cache = object->cache.next;
object->cache.next = NULL;
acpi_gbl_object_cache_hits++;
acpi_gbl_object_cache_depth--;
acpi_cm_release_mutex (ACPI_MTX_CACHES);
}
else {
/* The cache is empty, create a new object */
acpi_cm_release_mutex (ACPI_MTX_CACHES);
/* Attempt to allocate new descriptor */
object = _cm_callocate (sizeof (ACPI_OPERAND_OBJECT), component_id,
module_name, line_number);
if (!object) {
/* Allocation failed */
_REPORT_ERROR (module_name, line_number, component_id,
("Could not allocate an object descriptor\n"));
return (NULL);
}
/* Memory allocation metrics - compiled out in non debug mode. */
INCREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
}
/* Mark the descriptor type */
object->common.data_type = ACPI_DESC_TYPE_INTERNAL;
return (object);
}
/*******************************************************************************
*
* FUNCTION: Acpi_cm_delete_object_desc
*
* PARAMETERS: Object - Acpi internal object to be deleted
*
* RETURN: None.
*
* DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
*
******************************************************************************/
void
acpi_cm_delete_object_desc (
ACPI_OPERAND_OBJECT *object)
{
/* Make sure that the object isn't already in the cache */
if (object->common.data_type == (ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT)) {
return;
}
/* Object must be an ACPI_OPERAND_OBJECT */
if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
return;
}
/* If cache is full, just free this object */
if (acpi_gbl_object_cache_depth >= MAX_OBJECT_CACHE_DEPTH) {
/*
* Memory allocation metrics. Call the macro here since we only
* care about dynamically allocated objects.
*/
DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
acpi_cm_free (object);
return;
}
acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
/* Clear the entire object. This is important! */
MEMSET (object, 0, sizeof (ACPI_OPERAND_OBJECT));
object->common.data_type = ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT;
/* Put the object at the head of the global cache list */
object->cache.next = acpi_gbl_object_cache;
acpi_gbl_object_cache = object;
acpi_gbl_object_cache_depth++;
acpi_cm_release_mutex (ACPI_MTX_CACHES);
return;
}
/*******************************************************************************
*
* FUNCTION: Acpi_cm_delete_object_cache
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Purge the global state object cache. Used during subsystem
* termination.
*
******************************************************************************/
void
acpi_cm_delete_object_cache (
void)
{
ACPI_OPERAND_OBJECT *next;
/* Traverse the global cache list */
while (acpi_gbl_object_cache) {
/* Delete one cached state object */
next = acpi_gbl_object_cache->cache.next;
acpi_gbl_object_cache->cache.next = NULL;
/*
* Memory allocation metrics. Call the macro here since we only
* care about dynamically allocated objects.
*/
DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
acpi_cm_free (acpi_gbl_object_cache);
acpi_gbl_object_cache = next;
acpi_gbl_object_cache_depth--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -