📄 cmobject.c
字号:
/****************************************************************************** * * Module Name: cmobject - ACPI object create/delete/size/cache routines * $Revision: 34 $ * *****************************************************************************//* * Copyright (C) 2000 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"#include "acinterp.h"#include "acnamesp.h"#include "actables.h"#include "amlcode.h"#define _COMPONENT MISCELLANEOUS 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 * *****************************************************************************/u8acpi_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 * ****************************************************************************/voidacpi_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. * ******************************************************************************/voidacpi_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--; } return;}/***************************************************************************** * * FUNCTION: Acpi_cm_init_static_object * * PARAMETERS: Obj_desc - Pointer to a "static" object - on stack * or in the data segment. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -