1 /******************************************************************************
3 * Module Name: utalloc - local cache and 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 (
59 acpi_ut_track_allocation (
61 struct acpi_debug_mem_block
*address
,
69 acpi_ut_remove_allocation (
71 struct acpi_debug_mem_block
*address
,
75 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
78 /*******************************************************************************
80 * FUNCTION: acpi_ut_release_to_cache
82 * PARAMETERS: list_id - Memory list/cache ID
83 * Object - The object to be released
87 * DESCRIPTION: Release an object to the specified cache. If cache is full,
88 * the object is deleted.
90 ******************************************************************************/
93 acpi_ut_release_to_cache (
97 struct acpi_memory_list
*cache_info
;
100 ACPI_FUNCTION_ENTRY ();
103 cache_info
= &acpi_gbl_memory_lists
[list_id
];
105 #ifdef ACPI_ENABLE_OBJECT_CACHE
107 /* If walk cache is full, just free this wallkstate object */
109 if (cache_info
->cache_depth
>= cache_info
->max_cache_depth
) {
110 ACPI_MEM_FREE (object
);
111 ACPI_MEM_TRACKING (cache_info
->total_freed
++);
114 /* Otherwise put this object back into the cache */
117 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES
))) {
121 /* Mark the object as cached */
123 ACPI_MEMSET (object
, 0xCA, cache_info
->object_size
);
124 ACPI_SET_DESCRIPTOR_TYPE (object
, ACPI_DESC_TYPE_CACHED
);
126 /* Put the object at the head of the cache list */
128 * (ACPI_CAST_INDIRECT_PTR (char,
129 &(((char *) object
)[cache_info
->link_offset
]))) = cache_info
->list_head
;
130 cache_info
->list_head
= object
;
131 cache_info
->cache_depth
++;
133 (void) acpi_ut_release_mutex (ACPI_MTX_CACHES
);
138 /* Object cache is disabled; just free the object */
140 ACPI_MEM_FREE (object
);
141 ACPI_MEM_TRACKING (cache_info
->total_freed
++);
146 /*******************************************************************************
148 * FUNCTION: acpi_ut_acquire_from_cache
150 * PARAMETERS: list_id - Memory list ID
152 * RETURN: A requested object. NULL if the object could not be
155 * DESCRIPTION: Get an object from the specified cache. If cache is empty,
156 * the object is allocated.
158 ******************************************************************************/
161 acpi_ut_acquire_from_cache (
164 struct acpi_memory_list
*cache_info
;
168 ACPI_FUNCTION_NAME ("ut_acquire_from_cache");
171 cache_info
= &acpi_gbl_memory_lists
[list_id
];
173 #ifdef ACPI_ENABLE_OBJECT_CACHE
175 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES
))) {
179 ACPI_MEM_TRACKING (cache_info
->cache_requests
++);
181 /* Check the cache first */
183 if (cache_info
->list_head
) {
184 /* There is an object available, use it */
186 object
= cache_info
->list_head
;
187 cache_info
->list_head
= *(ACPI_CAST_INDIRECT_PTR (char,
188 &(((char *) object
)[cache_info
->link_offset
])));
190 ACPI_MEM_TRACKING (cache_info
->cache_hits
++);
191 cache_info
->cache_depth
--;
193 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
194 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "Object %p from %s\n",
195 object
, acpi_gbl_memory_lists
[list_id
].list_name
));
198 if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES
))) {
202 /* Clear (zero) the previously used Object */
204 ACPI_MEMSET (object
, 0, cache_info
->object_size
);
208 /* The cache is empty, create a new object */
210 /* Avoid deadlock with ACPI_MEM_CALLOCATE */
212 if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES
))) {
216 object
= ACPI_MEM_CALLOCATE (cache_info
->object_size
);
217 ACPI_MEM_TRACKING (cache_info
->total_allocated
++);
222 /* Object cache is disabled; just allocate the object */
224 object
= ACPI_MEM_CALLOCATE (cache_info
->object_size
);
225 ACPI_MEM_TRACKING (cache_info
->total_allocated
++);
232 #ifdef ACPI_ENABLE_OBJECT_CACHE
233 /*******************************************************************************
235 * FUNCTION: acpi_ut_delete_generic_cache
237 * PARAMETERS: list_id - Memory list ID
241 * DESCRIPTION: Free all objects within the requested cache.
243 ******************************************************************************/
246 acpi_ut_delete_generic_cache (
249 struct acpi_memory_list
*cache_info
;
253 ACPI_FUNCTION_ENTRY ();
256 cache_info
= &acpi_gbl_memory_lists
[list_id
];
257 while (cache_info
->list_head
) {
258 /* Delete one cached state object */
260 next
= *(ACPI_CAST_INDIRECT_PTR (char,
261 &(((char *) cache_info
->list_head
)[cache_info
->link_offset
])));
262 ACPI_MEM_FREE (cache_info
->list_head
);
264 cache_info
->list_head
= next
;
265 cache_info
->cache_depth
--;
271 /*******************************************************************************
273 * FUNCTION: acpi_ut_validate_buffer
275 * PARAMETERS: Buffer - Buffer descriptor to be validated
279 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
281 ******************************************************************************/
284 acpi_ut_validate_buffer (
285 struct acpi_buffer
*buffer
)
288 /* Obviously, the structure pointer must be valid */
291 return (AE_BAD_PARAMETER
);
294 /* Special semantics for the length */
296 if ((buffer
->length
== ACPI_NO_BUFFER
) ||
297 (buffer
->length
== ACPI_ALLOCATE_BUFFER
) ||
298 (buffer
->length
== ACPI_ALLOCATE_LOCAL_BUFFER
)) {
302 /* Length is valid, the buffer pointer must be also */
304 if (!buffer
->pointer
) {
305 return (AE_BAD_PARAMETER
);
312 /*******************************************************************************
314 * FUNCTION: acpi_ut_initialize_buffer
316 * PARAMETERS: Buffer - Buffer to be validated
317 * required_length - Length needed
321 * DESCRIPTION: Validate that the buffer is of the required length or
322 * allocate a new buffer. Returned buffer is always zeroed.
324 ******************************************************************************/
327 acpi_ut_initialize_buffer (
328 struct acpi_buffer
*buffer
,
329 acpi_size required_length
)
331 acpi_status status
= AE_OK
;
334 switch (buffer
->length
) {
337 /* Set the exception and returned the required length */
339 status
= AE_BUFFER_OVERFLOW
;
343 case ACPI_ALLOCATE_BUFFER
:
345 /* Allocate a new buffer */
347 buffer
->pointer
= acpi_os_allocate (required_length
);
348 if (!buffer
->pointer
) {
349 return (AE_NO_MEMORY
);
352 /* Clear the buffer */
354 ACPI_MEMSET (buffer
->pointer
, 0, required_length
);
358 case ACPI_ALLOCATE_LOCAL_BUFFER
:
360 /* Allocate a new buffer with local interface to allow tracking */
362 buffer
->pointer
= ACPI_MEM_CALLOCATE (required_length
);
363 if (!buffer
->pointer
) {
364 return (AE_NO_MEMORY
);
371 /* Existing buffer: Validate the size of the buffer */
373 if (buffer
->length
< required_length
) {
374 status
= AE_BUFFER_OVERFLOW
;
378 /* Clear the buffer */
380 ACPI_MEMSET (buffer
->pointer
, 0, required_length
);
384 buffer
->length
= required_length
;
389 /*******************************************************************************
391 * FUNCTION: acpi_ut_allocate
393 * PARAMETERS: Size - Size of the allocation
394 * Component - Component type of caller
395 * Module - Source file name of caller
396 * Line - Line number of caller
398 * RETURN: Address of the allocated memory on success, NULL on failure.
400 * DESCRIPTION: The subsystem's equivalent of malloc.
402 ******************************************************************************/
414 ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size
);
417 /* Check for an inadvertent size of zero bytes */
420 _ACPI_REPORT_ERROR (module
, line
, component
,
421 ("ut_allocate: Attempt to allocate zero bytes\n"));
425 allocation
= acpi_os_allocate (size
);
427 /* Report allocation error */
429 _ACPI_REPORT_ERROR (module
, line
, component
,
430 ("ut_allocate: Could not allocate size %X\n", (u32
) size
));
435 return_PTR (allocation
);
439 /*******************************************************************************
441 * FUNCTION: acpi_ut_callocate
443 * PARAMETERS: Size - Size of the allocation
444 * Component - Component type of caller
445 * Module - Source file name of caller
446 * Line - Line number of caller
448 * RETURN: Address of the allocated memory on success, NULL on failure.
450 * DESCRIPTION: Subsystem equivalent of calloc.
452 ******************************************************************************/
464 ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size
);
467 /* Check for an inadvertent size of zero bytes */
470 _ACPI_REPORT_ERROR (module
, line
, component
,
471 ("ut_callocate: Attempt to allocate zero bytes\n"));
475 allocation
= acpi_os_allocate (size
);
477 /* Report allocation error */
479 _ACPI_REPORT_ERROR (module
, line
, component
,
480 ("ut_callocate: Could not allocate size %X\n", (u32
) size
));
484 /* Clear the memory block */
486 ACPI_MEMSET (allocation
, 0, size
);
487 return_PTR (allocation
);
491 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
493 * These procedures are used for tracking memory leaks in the subsystem, and
494 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
496 * Each memory allocation is tracked via a doubly linked list. Each
497 * element contains the caller's component, module name, function name, and
498 * line number. acpi_ut_allocate and acpi_ut_callocate call
499 * acpi_ut_track_allocation to add an element to the list; deletion
500 * occurs in the body of acpi_ut_free.
504 /*******************************************************************************
506 * FUNCTION: acpi_ut_allocate_and_track
508 * PARAMETERS: Size - Size of the allocation
509 * Component - Component type of caller
510 * Module - Source file name of caller
511 * Line - Line number of caller
513 * RETURN: Address of the allocated memory on success, NULL on failure.
515 * DESCRIPTION: The subsystem's equivalent of malloc.
517 ******************************************************************************/
520 acpi_ut_allocate_and_track (
526 struct acpi_debug_mem_block
*allocation
;
530 allocation
= acpi_ut_allocate (size
+ sizeof (struct acpi_debug_mem_header
),
531 component
, module
, line
);
536 status
= acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL
, allocation
, size
,
537 ACPI_MEM_MALLOC
, component
, module
, line
);
538 if (ACPI_FAILURE (status
)) {
539 acpi_os_free (allocation
);
543 acpi_gbl_memory_lists
[ACPI_MEM_LIST_GLOBAL
].total_allocated
++;
544 acpi_gbl_memory_lists
[ACPI_MEM_LIST_GLOBAL
].current_total_size
+= (u32
) size
;
546 return ((void *) &allocation
->user_space
);
550 /*******************************************************************************
552 * FUNCTION: acpi_ut_callocate_and_track
554 * PARAMETERS: Size - Size of the allocation
555 * Component - Component type of caller
556 * Module - Source file name of caller
557 * Line - Line number of caller
559 * RETURN: Address of the allocated memory on success, NULL on failure.
561 * DESCRIPTION: Subsystem equivalent of calloc.
563 ******************************************************************************/
566 acpi_ut_callocate_and_track (
572 struct acpi_debug_mem_block
*allocation
;
576 allocation
= acpi_ut_callocate (size
+ sizeof (struct acpi_debug_mem_header
),
577 component
, module
, line
);
579 /* Report allocation error */
581 _ACPI_REPORT_ERROR (module
, line
, component
,
582 ("ut_callocate: Could not allocate size %X\n", (u32
) size
));
586 status
= acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL
, allocation
, size
,
587 ACPI_MEM_CALLOC
, component
, module
, line
);
588 if (ACPI_FAILURE (status
)) {
589 acpi_os_free (allocation
);
593 acpi_gbl_memory_lists
[ACPI_MEM_LIST_GLOBAL
].total_allocated
++;
594 acpi_gbl_memory_lists
[ACPI_MEM_LIST_GLOBAL
].current_total_size
+= (u32
) size
;
596 return ((void *) &allocation
->user_space
);
600 /*******************************************************************************
602 * FUNCTION: acpi_ut_free_and_track
604 * PARAMETERS: Allocation - Address of the memory to deallocate
605 * Component - Component type of caller
606 * Module - Source file name of caller
607 * Line - Line number of caller
611 * DESCRIPTION: Frees the memory at Allocation
613 ******************************************************************************/
616 acpi_ut_free_and_track (
622 struct acpi_debug_mem_block
*debug_block
;
626 ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation
);
629 if (NULL
== allocation
) {
630 _ACPI_REPORT_ERROR (module
, line
, component
,
631 ("acpi_ut_free: Attempt to delete a NULL address\n"));
636 debug_block
= ACPI_CAST_PTR (struct acpi_debug_mem_block
,
637 (((char *) allocation
) - sizeof (struct acpi_debug_mem_header
)));
639 acpi_gbl_memory_lists
[ACPI_MEM_LIST_GLOBAL
].total_freed
++;
640 acpi_gbl_memory_lists
[ACPI_MEM_LIST_GLOBAL
].current_total_size
-= debug_block
->size
;
642 status
= acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL
, debug_block
,
643 component
, module
, line
);
644 if (ACPI_FAILURE (status
)) {
645 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Could not free memory, %s\n",
646 acpi_format_exception (status
)));
649 acpi_os_free (debug_block
);
651 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS
, "%p freed\n", allocation
));
657 /*******************************************************************************
659 * FUNCTION: acpi_ut_find_allocation
661 * PARAMETERS: list_id - Memory list to search
662 * Allocation - Address of allocated memory
664 * RETURN: A list element if found; NULL otherwise.
666 * DESCRIPTION: Searches for an element in the global allocation tracking list.
668 ******************************************************************************/
670 static struct acpi_debug_mem_block
*
671 acpi_ut_find_allocation (
675 struct acpi_debug_mem_block
*element
;
678 ACPI_FUNCTION_ENTRY ();
681 if (list_id
> ACPI_MEM_LIST_MAX
) {
685 element
= acpi_gbl_memory_lists
[list_id
].list_head
;
687 /* Search for the address. */
690 if (element
== allocation
) {
694 element
= element
->next
;
701 /*******************************************************************************
703 * FUNCTION: acpi_ut_track_allocation
705 * PARAMETERS: list_id - Memory list to search
706 * Allocation - Address of allocated memory
707 * Size - Size of the allocation
708 * alloc_type - MEM_MALLOC or MEM_CALLOC
709 * Component - Component type of caller
710 * Module - Source file name of caller
711 * Line - Line number of caller
715 * DESCRIPTION: Inserts an element into the global allocation tracking list.
717 ******************************************************************************/
720 acpi_ut_track_allocation (
722 struct acpi_debug_mem_block
*allocation
,
729 struct acpi_memory_list
*mem_list
;
730 struct acpi_debug_mem_block
*element
;
731 acpi_status status
= AE_OK
;
734 ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation
);
737 if (list_id
> ACPI_MEM_LIST_MAX
) {
738 return_ACPI_STATUS (AE_BAD_PARAMETER
);
741 mem_list
= &acpi_gbl_memory_lists
[list_id
];
742 status
= acpi_ut_acquire_mutex (ACPI_MTX_MEMORY
);
743 if (ACPI_FAILURE (status
)) {
744 return_ACPI_STATUS (status
);
748 * Search list for this address to make sure it is not already on the list.
749 * This will catch several kinds of problems.
752 element
= acpi_ut_find_allocation (list_id
, allocation
);
755 "ut_track_allocation: Allocation already present in list! (%p)\n",
758 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
, "Element %p Address %p\n",
759 element
, allocation
));
761 goto unlock_and_exit
;
764 /* Fill in the instance data. */
766 allocation
->size
= (u32
) size
;
767 allocation
->alloc_type
= alloc_type
;
768 allocation
->component
= component
;
769 allocation
->line
= line
;
771 ACPI_STRNCPY (allocation
->module
, module
, ACPI_MAX_MODULE_NAME
);
772 allocation
->module
[ACPI_MAX_MODULE_NAME
-1] = 0;
774 /* Insert at list head */
776 if (mem_list
->list_head
) {
777 ((struct acpi_debug_mem_block
*)(mem_list
->list_head
))->previous
= allocation
;
780 allocation
->next
= mem_list
->list_head
;
781 allocation
->previous
= NULL
;
783 mem_list
->list_head
= allocation
;
787 status
= acpi_ut_release_mutex (ACPI_MTX_MEMORY
);
788 return_ACPI_STATUS (status
);
792 /*******************************************************************************
794 * FUNCTION: acpi_ut_remove_allocation
796 * PARAMETERS: list_id - Memory list to search
797 * Allocation - Address of allocated memory
798 * Component - Component type of caller
799 * Module - Source file name of caller
800 * Line - Line number of caller
804 * DESCRIPTION: Deletes an element from the global allocation tracking list.
806 ******************************************************************************/
809 acpi_ut_remove_allocation (
811 struct acpi_debug_mem_block
*allocation
,
816 struct acpi_memory_list
*mem_list
;
820 ACPI_FUNCTION_TRACE ("ut_remove_allocation");
823 if (list_id
> ACPI_MEM_LIST_MAX
) {
824 return_ACPI_STATUS (AE_BAD_PARAMETER
);
827 mem_list
= &acpi_gbl_memory_lists
[list_id
];
828 if (NULL
== mem_list
->list_head
) {
829 /* No allocations! */
831 _ACPI_REPORT_ERROR (module
, line
, component
,
832 ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
834 return_ACPI_STATUS (AE_OK
);
837 status
= acpi_ut_acquire_mutex (ACPI_MTX_MEMORY
);
838 if (ACPI_FAILURE (status
)) {
839 return_ACPI_STATUS (status
);
844 if (allocation
->previous
) {
845 (allocation
->previous
)->next
= allocation
->next
;
848 mem_list
->list_head
= allocation
->next
;
851 if (allocation
->next
) {
852 (allocation
->next
)->previous
= allocation
->previous
;
855 /* Mark the segment as deleted */
857 ACPI_MEMSET (&allocation
->user_space
, 0xEA, allocation
->size
);
859 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS
, "Freeing size 0%X\n",
862 status
= acpi_ut_release_mutex (ACPI_MTX_MEMORY
);
863 return_ACPI_STATUS (status
);
867 /*******************************************************************************
869 * FUNCTION: acpi_ut_dump_allocation_info
875 * DESCRIPTION: Print some info about the outstanding allocations.
877 ******************************************************************************/
879 #ifdef ACPI_FUTURE_USAGE
881 acpi_ut_dump_allocation_info (
885 struct acpi_memory_list *mem_list;
888 ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
891 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
892 ("%30s: %4d (%3d Kb)\n", "Current allocations",
893 mem_list->current_count,
894 ROUND_UP_TO_1K (mem_list->current_size)));
896 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
897 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
898 mem_list->max_concurrent_count,
899 ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
902 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
903 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
904 running_object_count,
905 ROUND_UP_TO_1K (running_object_size)));
907 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
908 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
910 ROUND_UP_TO_1K (running_alloc_size)));
913 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
914 ("%30s: %4d (%3d Kb)\n", "Current Nodes",
915 acpi_gbl_current_node_count,
916 ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
918 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
919 ("%30s: %4d (%3d Kb)\n", "Max Nodes",
920 acpi_gbl_max_concurrent_node_count,
921 ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
922 sizeof (struct acpi_namespace_node)))));
926 #endif /* ACPI_FUTURE_USAGE */
929 /*******************************************************************************
931 * FUNCTION: acpi_ut_dump_allocations
933 * PARAMETERS: Component - Component(s) to dump info for.
934 * Module - Module to dump info for. NULL means all.
938 * DESCRIPTION: Print a list of all outstanding allocations.
940 ******************************************************************************/
943 acpi_ut_dump_allocations (
947 struct acpi_debug_mem_block
*element
;
948 union acpi_descriptor
*descriptor
;
949 u32 num_outstanding
= 0;
952 ACPI_FUNCTION_TRACE ("ut_dump_allocations");
956 * Walk the allocation list.
958 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY
))) {
962 element
= acpi_gbl_memory_lists
[0].list_head
;
964 if ((element
->component
& component
) &&
965 ((module
== NULL
) || (0 == ACPI_STRCMP (module
, element
->module
)))) {
966 /* Ignore allocated objects that are in a cache */
968 descriptor
= ACPI_CAST_PTR (union acpi_descriptor
, &element
->user_space
);
969 if (descriptor
->descriptor_id
!= ACPI_DESC_TYPE_CACHED
) {
970 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
971 descriptor
, element
->size
, element
->module
,
972 element
->line
, acpi_ut_get_descriptor_name (descriptor
));
974 /* Most of the elements will be Operand objects. */
976 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor
)) {
977 case ACPI_DESC_TYPE_OPERAND
:
978 acpi_os_printf ("%12.12s R%hd",
979 acpi_ut_get_type_name (descriptor
->object
.common
.type
),
980 descriptor
->object
.common
.reference_count
);
983 case ACPI_DESC_TYPE_PARSER
:
984 acpi_os_printf ("aml_opcode %04hX",
985 descriptor
->op
.asl
.aml_opcode
);
988 case ACPI_DESC_TYPE_NAMED
:
989 acpi_os_printf ("%4.4s",
990 acpi_ut_get_node_name (&descriptor
->node
));
997 acpi_os_printf ( "\n");
1001 element
= element
->next
;
1004 (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY
);
1008 if (!num_outstanding
) {
1009 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
,
1010 "No outstanding allocations.\n"));
1013 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR
,
1014 "%d(%X) Outstanding allocations\n",
1015 num_outstanding
, num_outstanding
));
1021 #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */