1 /******************************************************************************
3 * Module Name: utalloc - local memory allocation routines
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2005, R. Byron Moore
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
45 #include <acpi/acpi.h>
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utalloc")
50 /* Local prototypes */
52 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
53 static struct acpi_debug_mem_block *
54 acpi_ut_find_allocation (
58 acpi_ut_track_allocation (
59 struct acpi_debug_mem_block *address,
67 acpi_ut_remove_allocation (
68 struct acpi_debug_mem_block *address,
72 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
74 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
79 acpi_handle *return_cache);
83 /*******************************************************************************
85 * FUNCTION: acpi_ut_create_caches
91 * DESCRIPTION: Create all local caches
93 ******************************************************************************/
96 acpi_ut_create_caches (
102 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
104 /* Memory allocation lists */
106 status = acpi_ut_create_list ("Acpi-Global", 0,
107 &acpi_gbl_global_list);
108 if (ACPI_FAILURE (status)) {
112 status = acpi_ut_create_list ("Acpi-Namespace", sizeof (struct acpi_namespace_node),
113 &acpi_gbl_ns_node_list);
114 if (ACPI_FAILURE (status)) {
119 /* Object Caches, for frequently used objects */
121 status = acpi_os_create_cache ("acpi_state", sizeof (union acpi_generic_state),
122 ACPI_MAX_STATE_CACHE_DEPTH, &acpi_gbl_state_cache);
123 if (ACPI_FAILURE (status)) {
127 status = acpi_os_create_cache ("acpi_parse", sizeof (struct acpi_parse_obj_common),
128 ACPI_MAX_PARSE_CACHE_DEPTH, &acpi_gbl_ps_node_cache);
129 if (ACPI_FAILURE (status)) {
133 status = acpi_os_create_cache ("acpi_parse_ext", sizeof (struct acpi_parse_obj_named),
134 ACPI_MAX_EXTPARSE_CACHE_DEPTH, &acpi_gbl_ps_node_ext_cache);
135 if (ACPI_FAILURE (status)) {
139 status = acpi_os_create_cache ("acpi_operand", sizeof (union acpi_operand_object),
140 ACPI_MAX_OBJECT_CACHE_DEPTH, &acpi_gbl_operand_cache);
141 if (ACPI_FAILURE (status)) {
149 /*******************************************************************************
151 * FUNCTION: acpi_ut_delete_caches
157 * DESCRIPTION: Purge and delete all local caches
159 ******************************************************************************/
162 acpi_ut_delete_caches (
166 (void) acpi_os_delete_cache (acpi_gbl_state_cache);
167 acpi_gbl_state_cache = NULL;
169 (void) acpi_os_delete_cache (acpi_gbl_operand_cache);
170 acpi_gbl_operand_cache = NULL;
172 (void) acpi_os_delete_cache (acpi_gbl_ps_node_cache);
173 acpi_gbl_ps_node_cache = NULL;
175 (void) acpi_os_delete_cache (acpi_gbl_ps_node_ext_cache);
176 acpi_gbl_ps_node_ext_cache = NULL;
181 /*******************************************************************************
183 * FUNCTION: acpi_ut_validate_buffer
185 * PARAMETERS: Buffer - Buffer descriptor to be validated
189 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
191 ******************************************************************************/
194 acpi_ut_validate_buffer (
195 struct acpi_buffer *buffer)
198 /* Obviously, the structure pointer must be valid */
201 return (AE_BAD_PARAMETER);
204 /* Special semantics for the length */
206 if ((buffer->length == ACPI_NO_BUFFER) ||
207 (buffer->length == ACPI_ALLOCATE_BUFFER) ||
208 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
212 /* Length is valid, the buffer pointer must be also */
214 if (!buffer->pointer) {
215 return (AE_BAD_PARAMETER);
222 /*******************************************************************************
224 * FUNCTION: acpi_ut_initialize_buffer
226 * PARAMETERS: Buffer - Buffer to be validated
227 * required_length - Length needed
231 * DESCRIPTION: Validate that the buffer is of the required length or
232 * allocate a new buffer. Returned buffer is always zeroed.
234 ******************************************************************************/
237 acpi_ut_initialize_buffer (
238 struct acpi_buffer *buffer,
239 acpi_size required_length)
241 acpi_status status = AE_OK;
244 switch (buffer->length) {
247 /* Set the exception and returned the required length */
249 status = AE_BUFFER_OVERFLOW;
253 case ACPI_ALLOCATE_BUFFER:
255 /* Allocate a new buffer */
257 buffer->pointer = acpi_os_allocate (required_length);
258 if (!buffer->pointer) {
259 return (AE_NO_MEMORY);
262 /* Clear the buffer */
264 ACPI_MEMSET (buffer->pointer, 0, required_length);
268 case ACPI_ALLOCATE_LOCAL_BUFFER:
270 /* Allocate a new buffer with local interface to allow tracking */
272 buffer->pointer = ACPI_MEM_CALLOCATE (required_length);
273 if (!buffer->pointer) {
274 return (AE_NO_MEMORY);
281 /* Existing buffer: Validate the size of the buffer */
283 if (buffer->length < required_length) {
284 status = AE_BUFFER_OVERFLOW;
288 /* Clear the buffer */
290 ACPI_MEMSET (buffer->pointer, 0, required_length);
294 buffer->length = required_length;
299 /*******************************************************************************
301 * FUNCTION: acpi_ut_allocate
303 * PARAMETERS: Size - Size of the allocation
304 * Component - Component type of caller
305 * Module - Source file name of caller
306 * Line - Line number of caller
308 * RETURN: Address of the allocated memory on success, NULL on failure.
310 * DESCRIPTION: The subsystem's equivalent of malloc.
312 ******************************************************************************/
324 ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
327 /* Check for an inadvertent size of zero bytes */
330 _ACPI_REPORT_ERROR (module, line, component,
331 ("ut_allocate: Attempt to allocate zero bytes\n"));
335 allocation = acpi_os_allocate (size);
337 /* Report allocation error */
339 _ACPI_REPORT_ERROR (module, line, component,
340 ("ut_allocate: Could not allocate size %X\n", (u32) size));
345 return_PTR (allocation);
349 /*******************************************************************************
351 * FUNCTION: acpi_ut_callocate
353 * PARAMETERS: Size - Size of the allocation
354 * Component - Component type of caller
355 * Module - Source file name of caller
356 * Line - Line number of caller
358 * RETURN: Address of the allocated memory on success, NULL on failure.
360 * DESCRIPTION: Subsystem equivalent of calloc.
362 ******************************************************************************/
374 ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
377 /* Check for an inadvertent size of zero bytes */
380 _ACPI_REPORT_ERROR (module, line, component,
381 ("ut_callocate: Attempt to allocate zero bytes\n"));
385 allocation = acpi_os_allocate (size);
387 /* Report allocation error */
389 _ACPI_REPORT_ERROR (module, line, component,
390 ("ut_callocate: Could not allocate size %X\n", (u32) size));
394 /* Clear the memory block */
396 ACPI_MEMSET (allocation, 0, size);
397 return_PTR (allocation);
401 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
403 * These procedures are used for tracking memory leaks in the subsystem, and
404 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
406 * Each memory allocation is tracked via a doubly linked list. Each
407 * element contains the caller's component, module name, function name, and
408 * line number. acpi_ut_allocate and acpi_ut_callocate call
409 * acpi_ut_track_allocation to add an element to the list; deletion
410 * occurs in the body of acpi_ut_free.
413 /*******************************************************************************
415 * FUNCTION: acpi_ut_create_list
417 * PARAMETERS: cache_name - Ascii name for the cache
418 * object_size - Size of each cached object
419 * return_cache - Where the new cache object is returned
423 * DESCRIPTION: Create a local memory list for tracking purposed
425 ******************************************************************************/
428 acpi_ut_create_list (
431 acpi_handle *return_cache)
433 struct acpi_memory_list *cache;
436 cache = acpi_os_allocate (sizeof (struct acpi_memory_list));
438 return (AE_NO_MEMORY);
441 ACPI_MEMSET (cache, 0, sizeof (struct acpi_memory_list));
443 cache->list_name = list_name;
444 cache->object_size = object_size;
446 *return_cache = cache;
451 /*******************************************************************************
453 * FUNCTION: acpi_ut_allocate_and_track
455 * PARAMETERS: Size - Size of the allocation
456 * Component - Component type of caller
457 * Module - Source file name of caller
458 * Line - Line number of caller
460 * RETURN: Address of the allocated memory on success, NULL on failure.
462 * DESCRIPTION: The subsystem's equivalent of malloc.
464 ******************************************************************************/
467 acpi_ut_allocate_and_track (
473 struct acpi_debug_mem_block *allocation;
477 allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header),
478 component, module, line);
483 status = acpi_ut_track_allocation (allocation, size,
484 ACPI_MEM_MALLOC, component, module, line);
485 if (ACPI_FAILURE (status)) {
486 acpi_os_free (allocation);
490 acpi_gbl_global_list->total_allocated++;
491 acpi_gbl_global_list->current_total_size += (u32) size;
493 return ((void *) &allocation->user_space);
497 /*******************************************************************************
499 * FUNCTION: acpi_ut_callocate_and_track
501 * PARAMETERS: Size - Size of the allocation
502 * Component - Component type of caller
503 * Module - Source file name of caller
504 * Line - Line number of caller
506 * RETURN: Address of the allocated memory on success, NULL on failure.
508 * DESCRIPTION: Subsystem equivalent of calloc.
510 ******************************************************************************/
513 acpi_ut_callocate_and_track (
519 struct acpi_debug_mem_block *allocation;
523 allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header),
524 component, module, line);
526 /* Report allocation error */
528 _ACPI_REPORT_ERROR (module, line, component,
529 ("ut_callocate: Could not allocate size %X\n", (u32) size));
533 status = acpi_ut_track_allocation (allocation, size,
534 ACPI_MEM_CALLOC, component, module, line);
535 if (ACPI_FAILURE (status)) {
536 acpi_os_free (allocation);
540 acpi_gbl_global_list->total_allocated++;
541 acpi_gbl_global_list->current_total_size += (u32) size;
543 return ((void *) &allocation->user_space);
547 /*******************************************************************************
549 * FUNCTION: acpi_ut_free_and_track
551 * PARAMETERS: Allocation - Address of the memory to deallocate
552 * Component - Component type of caller
553 * Module - Source file name of caller
554 * Line - Line number of caller
558 * DESCRIPTION: Frees the memory at Allocation
560 ******************************************************************************/
563 acpi_ut_free_and_track (
569 struct acpi_debug_mem_block *debug_block;
573 ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
576 if (NULL == allocation) {
577 _ACPI_REPORT_ERROR (module, line, component,
578 ("acpi_ut_free: Attempt to delete a NULL address\n"));
583 debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
584 (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
586 acpi_gbl_global_list->total_freed++;
587 acpi_gbl_global_list->current_total_size -= debug_block->size;
589 status = acpi_ut_remove_allocation (debug_block,
590 component, module, line);
591 if (ACPI_FAILURE (status)) {
592 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
593 acpi_format_exception (status)));
596 acpi_os_free (debug_block);
598 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
604 /*******************************************************************************
606 * FUNCTION: acpi_ut_find_allocation
608 * PARAMETERS: Allocation - Address of allocated memory
610 * RETURN: A list element if found; NULL otherwise.
612 * DESCRIPTION: Searches for an element in the global allocation tracking list.
614 ******************************************************************************/
616 static struct acpi_debug_mem_block *
617 acpi_ut_find_allocation (
620 struct acpi_debug_mem_block *element;
623 ACPI_FUNCTION_ENTRY ();
626 element = acpi_gbl_global_list->list_head;
628 /* Search for the address. */
631 if (element == allocation) {
635 element = element->next;
642 /*******************************************************************************
644 * FUNCTION: acpi_ut_track_allocation
646 * PARAMETERS: Allocation - Address of allocated memory
647 * Size - Size of the allocation
648 * alloc_type - MEM_MALLOC or MEM_CALLOC
649 * Component - Component type of caller
650 * Module - Source file name of caller
651 * Line - Line number of caller
655 * DESCRIPTION: Inserts an element into the global allocation tracking list.
657 ******************************************************************************/
660 acpi_ut_track_allocation (
661 struct acpi_debug_mem_block *allocation,
668 struct acpi_memory_list *mem_list;
669 struct acpi_debug_mem_block *element;
670 acpi_status status = AE_OK;
673 ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
676 mem_list = acpi_gbl_global_list;
677 status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
678 if (ACPI_FAILURE (status)) {
679 return_ACPI_STATUS (status);
683 * Search list for this address to make sure it is not already on the list.
684 * This will catch several kinds of problems.
686 element = acpi_ut_find_allocation (allocation);
689 "ut_track_allocation: Allocation already present in list! (%p)\n",
692 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n",
693 element, allocation));
695 goto unlock_and_exit;
698 /* Fill in the instance data. */
700 allocation->size = (u32) size;
701 allocation->alloc_type = alloc_type;
702 allocation->component = component;
703 allocation->line = line;
705 ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
706 allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
708 /* Insert at list head */
710 if (mem_list->list_head) {
711 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
714 allocation->next = mem_list->list_head;
715 allocation->previous = NULL;
717 mem_list->list_head = allocation;
721 status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
722 return_ACPI_STATUS (status);
726 /*******************************************************************************
728 * FUNCTION: acpi_ut_remove_allocation
730 * PARAMETERS: Allocation - Address of allocated memory
731 * Component - Component type of caller
732 * Module - Source file name of caller
733 * Line - Line number of caller
737 * DESCRIPTION: Deletes an element from the global allocation tracking list.
739 ******************************************************************************/
742 acpi_ut_remove_allocation (
743 struct acpi_debug_mem_block *allocation,
748 struct acpi_memory_list *mem_list;
752 ACPI_FUNCTION_TRACE ("ut_remove_allocation");
755 mem_list = acpi_gbl_global_list;
756 if (NULL == mem_list->list_head) {
757 /* No allocations! */
759 _ACPI_REPORT_ERROR (module, line, component,
760 ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
762 return_ACPI_STATUS (AE_OK);
765 status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
766 if (ACPI_FAILURE (status)) {
767 return_ACPI_STATUS (status);
772 if (allocation->previous) {
773 (allocation->previous)->next = allocation->next;
776 mem_list->list_head = allocation->next;
779 if (allocation->next) {
780 (allocation->next)->previous = allocation->previous;
783 /* Mark the segment as deleted */
785 ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
787 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
790 status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
791 return_ACPI_STATUS (status);
795 /*******************************************************************************
797 * FUNCTION: acpi_ut_dump_allocation_info
803 * DESCRIPTION: Print some info about the outstanding allocations.
805 ******************************************************************************/
807 #ifdef ACPI_FUTURE_USAGE
809 acpi_ut_dump_allocation_info (
813 struct acpi_memory_list *mem_list;
816 ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
819 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
820 ("%30s: %4d (%3d Kb)\n", "Current allocations",
821 mem_list->current_count,
822 ROUND_UP_TO_1K (mem_list->current_size)));
824 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
825 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
826 mem_list->max_concurrent_count,
827 ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
830 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
831 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
832 running_object_count,
833 ROUND_UP_TO_1K (running_object_size)));
835 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
836 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
838 ROUND_UP_TO_1K (running_alloc_size)));
841 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
842 ("%30s: %4d (%3d Kb)\n", "Current Nodes",
843 acpi_gbl_current_node_count,
844 ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
846 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
847 ("%30s: %4d (%3d Kb)\n", "Max Nodes",
848 acpi_gbl_max_concurrent_node_count,
849 ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
850 sizeof (struct acpi_namespace_node)))));
854 #endif /* ACPI_FUTURE_USAGE */
857 /*******************************************************************************
859 * FUNCTION: acpi_ut_dump_allocations
861 * PARAMETERS: Component - Component(s) to dump info for.
862 * Module - Module to dump info for. NULL means all.
866 * DESCRIPTION: Print a list of all outstanding allocations.
868 ******************************************************************************/
871 acpi_ut_dump_allocations (
875 struct acpi_debug_mem_block *element;
876 union acpi_descriptor *descriptor;
877 u32 num_outstanding = 0;
880 ACPI_FUNCTION_TRACE ("ut_dump_allocations");
884 * Walk the allocation list.
886 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
890 element = acpi_gbl_global_list->list_head;
892 if ((element->component & component) &&
893 ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
894 /* Ignore allocated objects that are in a cache */
896 descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
897 if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
898 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
899 descriptor, element->size, element->module,
900 element->line, acpi_ut_get_descriptor_name (descriptor));
902 /* Most of the elements will be Operand objects. */
904 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
905 case ACPI_DESC_TYPE_OPERAND:
906 acpi_os_printf ("%12.12s R%hd",
907 acpi_ut_get_type_name (descriptor->object.common.type),
908 descriptor->object.common.reference_count);
911 case ACPI_DESC_TYPE_PARSER:
912 acpi_os_printf ("aml_opcode %04hX",
913 descriptor->op.asl.aml_opcode);
916 case ACPI_DESC_TYPE_NAMED:
917 acpi_os_printf ("%4.4s",
918 acpi_ut_get_node_name (&descriptor->node));
925 acpi_os_printf ( "\n");
929 element = element->next;
932 (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
936 if (!num_outstanding) {
937 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
938 "No outstanding allocations.\n"));
941 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
942 "%d(%X) Outstanding allocations\n",
943 num_outstanding, num_outstanding));
949 #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */