📄 utalloc.c
字号:
/****************************************************************************** * * Module Name: utalloc - local cache and memory allocation routines * $Revision: 106 $ * *****************************************************************************//* * 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"#include "acparser.h"#include "acinterp.h"#include "acnamesp.h"#include "acglobal.h"#define _COMPONENT ACPI_UTILITIES MODULE_NAME ("utalloc")/****************************************************************************** * * FUNCTION: Acpi_ut_release_to_cache * * PARAMETERS: List_id - Memory list/cache ID * Object - The object to be released * * RETURN: None * * DESCRIPTION: Release an object to the specified cache. If cache is full, * the object is deleted. * ******************************************************************************/voidacpi_ut_release_to_cache ( u32 list_id, void *object){ ACPI_MEMORY_LIST *cache_info; FUNCTION_ENTRY (); /* If walk cache is full, just free this wallkstate object */ cache_info = &acpi_gbl_memory_lists[list_id]; if (cache_info->cache_depth >= cache_info->max_cache_depth) { ACPI_MEM_FREE (object); ACPI_MEM_TRACKING (cache_info->total_freed++); } /* Otherwise put this object back into the cache */ else { acpi_ut_acquire_mutex (ACPI_MTX_CACHES); /* Mark the object as cached */ MEMSET (object, 0xCA, cache_info->object_size); ((acpi_operand_object *) object)->common.data_type = ACPI_CACHED_OBJECT; /* Put the object at the head of the cache list */ * (char **) (((char *) object) + cache_info->link_offset) = cache_info->list_head; cache_info->list_head = object; cache_info->cache_depth++; acpi_ut_release_mutex (ACPI_MTX_CACHES); }}/****************************************************************************** * * FUNCTION: Acpi_ut_acquire_from_cache * * PARAMETERS: List_id - Memory list ID * * RETURN: A requested object. NULL if the object could not be * allocated. * * DESCRIPTION: Get an object from the specified cache. If cache is empty, * the object is allocated. * ******************************************************************************/void *acpi_ut_acquire_from_cache ( u32 list_id){ ACPI_MEMORY_LIST *cache_info; void *object; PROC_NAME ("Ut_acquire_from_cache"); cache_info = &acpi_gbl_memory_lists[list_id]; acpi_ut_acquire_mutex (ACPI_MTX_CACHES); ACPI_MEM_TRACKING (cache_info->cache_requests++); /* Check the cache first */ if (cache_info->list_head) { /* There is an object available, use it */ object = cache_info->list_head; cache_info->list_head = * (char **) (((char *) object) + cache_info->link_offset); ACPI_MEM_TRACKING (cache_info->cache_hits++); cache_info->cache_depth--;#ifdef ACPI_DBG_TRACK_ALLOCATIONS ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n", object, acpi_gbl_memory_lists[list_id].list_name));#endif acpi_ut_release_mutex (ACPI_MTX_CACHES); /* Clear (zero) the previously used Object */ MEMSET (object, 0, cache_info->object_size); } else { /* The cache is empty, create a new object */ /* Avoid deadlock with ACPI_MEM_CALLOCATE */ acpi_ut_release_mutex (ACPI_MTX_CACHES); object = ACPI_MEM_CALLOCATE (cache_info->object_size); ACPI_MEM_TRACKING (cache_info->total_allocated++); } return (object);}/****************************************************************************** * * FUNCTION: Acpi_ut_delete_generic_cache * * PARAMETERS: List_id - Memory list ID * * RETURN: None * * DESCRIPTION: Free all objects within the requested cache. * ******************************************************************************/voidacpi_ut_delete_generic_cache ( u32 list_id){ ACPI_MEMORY_LIST *cache_info; char *next; FUNCTION_ENTRY (); cache_info = &acpi_gbl_memory_lists[list_id]; while (cache_info->list_head) { /* Delete one cached state object */ next = * (char **) (((char *) cache_info->list_head) + cache_info->link_offset); ACPI_MEM_FREE (cache_info->list_head); cache_info->list_head = next; cache_info->cache_depth--; }}#ifdef ACPI_DBG_TRACK_ALLOCATIONS/* * These procedures are used for tracking memory leaks in the subsystem, and * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. * * Each memory allocation is tracked via a doubly linked list. Each * element contains the caller's component, module name, function name, and * line number. Acpi_ut_allocate and Acpi_ut_callocate call * Acpi_ut_track_allocation to add an element to the list; deletion * occurs in the body of Acpi_ut_free. *//******************************************************************************* * * FUNCTION: Acpi_ut_find_allocation * * PARAMETERS: Address - Address of allocated memory * * RETURN: A list element if found; NULL otherwise. * * DESCRIPTION: Searches for an element in the global allocation tracking list. * ******************************************************************************/acpi_debug_mem_block *acpi_ut_find_allocation ( u32 list_id, void *address){ acpi_debug_mem_block *element; FUNCTION_ENTRY (); if (list_id > ACPI_MEM_LIST_MAX) { return (NULL); } element = acpi_gbl_memory_lists[list_id].list_head; /* Search for the address. */ while (element) { if (element == address) { return (element); } element = element->next; } return (NULL);}/******************************************************************************* * * FUNCTION: Acpi_ut_track_allocation * * PARAMETERS: Address - Address of allocated memory * Size - Size of the allocation * Alloc_type - MEM_MALLOC or MEM_CALLOC * Component - Component type of caller * Module - Source file name of caller * Line - Line number of caller * * RETURN: None. * * DESCRIPTION: Inserts an element into the global allocation tracking list. * ******************************************************************************/acpi_statusacpi_ut_track_allocation ( u32 list_id, acpi_debug_mem_block *address, u32 size, u8 alloc_type, u32 component, NATIVE_CHAR *module, u32 line){ ACPI_MEMORY_LIST *mem_list; acpi_debug_mem_block *element; acpi_status status = AE_OK; FUNCTION_TRACE_PTR ("Ut_track_allocation", address); if (list_id > ACPI_MEM_LIST_MAX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } mem_list = &acpi_gbl_memory_lists[list_id]; acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); /* * Search list for this address to make sure it is not already on the list. * This will catch several kinds of problems. */ element = acpi_ut_find_allocation (list_id, address); if (element) { REPORT_ERROR (("Ut_track_allocation: Address already present in list! (%p)\n", address)); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, address)); goto unlock_and_exit; } /* Fill in the instance data. */ address->size = size; address->alloc_type = alloc_type; address->component = component; address->line = line; STRNCPY (address->module, module, MAX_MODULE_NAME); /* Insert at list head */ if (mem_list->list_head) { ((acpi_debug_mem_block *)(mem_list->list_head))->previous = address; } address->next = mem_list->list_head; address->previous = NULL; mem_list->list_head = address;unlock_and_exit: acpi_ut_release_mutex (ACPI_MTX_MEMORY); return_ACPI_STATUS (status);}/******************************************************************************* * * FUNCTION: Acpi_ut_remove_allocation * * PARAMETERS: Address - Address of allocated memory * Component - Component type of caller * Module - Source file name of caller * Line - Line number of caller * * RETURN: * * DESCRIPTION: Deletes an element from the global allocation tracking list. * ******************************************************************************/acpi_statusacpi_ut_remove_allocation ( u32 list_id, acpi_debug_mem_block *address, u32 component, NATIVE_CHAR *module, u32 line){ ACPI_MEMORY_LIST *mem_list; FUNCTION_TRACE ("Ut_remove_allocation"); if (list_id > ACPI_MEM_LIST_MAX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } mem_list = &acpi_gbl_memory_lists[list_id]; if (NULL == mem_list->list_head) { /* No allocations! */ _REPORT_ERROR (module, line, component, ("Ut_remove_allocation: Empty allocation list, nothing to free!\n")); return_ACPI_STATUS (AE_OK); } acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); /* Unlink */ if (address->previous) { (address->previous)->next = address->next; } else { mem_list->list_head = address->next; } if (address->next) { (address->next)->previous = address->previous;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -