uttrack.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /******************************************************************************
  2. *
  3. * Module Name: uttrack - Memory allocation tracking routines (debug only)
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2015, Intel Corp.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. /*
  43. * These procedures are used for tracking memory leaks in the subsystem, and
  44. * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
  45. *
  46. * Each memory allocation is tracked via a doubly linked list. Each
  47. * element contains the caller's component, module name, function name, and
  48. * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call
  49. * acpi_ut_track_allocation to add an element to the list; deletion
  50. * occurs in the body of acpi_ut_free.
  51. */
  52. #include <acpi/acpi.h>
  53. #include "accommon.h"
  54. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  55. #define _COMPONENT ACPI_UTILITIES
  56. ACPI_MODULE_NAME("uttrack")
  57. /* Local prototypes */
  58. static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
  59. acpi_debug_mem_block
  60. *allocation);
  61. static acpi_status
  62. acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
  63. acpi_size size,
  64. u8 alloc_type,
  65. u32 component, const char *module, u32 line);
  66. static acpi_status
  67. acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
  68. u32 component, const char *module, u32 line);
  69. /*******************************************************************************
  70. *
  71. * FUNCTION: acpi_ut_create_list
  72. *
  73. * PARAMETERS: cache_name - Ascii name for the cache
  74. * object_size - Size of each cached object
  75. * return_cache - Where the new cache object is returned
  76. *
  77. * RETURN: Status
  78. *
  79. * DESCRIPTION: Create a local memory list for tracking purposed
  80. *
  81. ******************************************************************************/
  82. acpi_status
  83. acpi_ut_create_list(char *list_name,
  84. u16 object_size, struct acpi_memory_list **return_cache)
  85. {
  86. struct acpi_memory_list *cache;
  87. cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
  88. if (!cache) {
  89. return (AE_NO_MEMORY);
  90. }
  91. memset(cache, 0, sizeof(struct acpi_memory_list));
  92. cache->list_name = list_name;
  93. cache->object_size = object_size;
  94. *return_cache = cache;
  95. return (AE_OK);
  96. }
  97. /*******************************************************************************
  98. *
  99. * FUNCTION: acpi_ut_allocate_and_track
  100. *
  101. * PARAMETERS: size - Size of the allocation
  102. * component - Component type of caller
  103. * module - Source file name of caller
  104. * line - Line number of caller
  105. *
  106. * RETURN: Address of the allocated memory on success, NULL on failure.
  107. *
  108. * DESCRIPTION: The subsystem's equivalent of malloc.
  109. *
  110. ******************************************************************************/
  111. void *acpi_ut_allocate_and_track(acpi_size size,
  112. u32 component, const char *module, u32 line)
  113. {
  114. struct acpi_debug_mem_block *allocation;
  115. acpi_status status;
  116. /* Check for an inadvertent size of zero bytes */
  117. if (!size) {
  118. ACPI_WARNING((module, line,
  119. "Attempt to allocate zero bytes, allocating 1 byte"));
  120. size = 1;
  121. }
  122. allocation =
  123. acpi_os_allocate(size + sizeof(struct acpi_debug_mem_header));
  124. if (!allocation) {
  125. /* Report allocation error */
  126. ACPI_WARNING((module, line,
  127. "Could not allocate size %u", (u32)size));
  128. return (NULL);
  129. }
  130. status = acpi_ut_track_allocation(allocation, size,
  131. ACPI_MEM_MALLOC, component, module,
  132. line);
  133. if (ACPI_FAILURE(status)) {
  134. acpi_os_free(allocation);
  135. return (NULL);
  136. }
  137. acpi_gbl_global_list->total_allocated++;
  138. acpi_gbl_global_list->total_size += (u32)size;
  139. acpi_gbl_global_list->current_total_size += (u32)size;
  140. if (acpi_gbl_global_list->current_total_size >
  141. acpi_gbl_global_list->max_occupied) {
  142. acpi_gbl_global_list->max_occupied =
  143. acpi_gbl_global_list->current_total_size;
  144. }
  145. return ((void *)&allocation->user_space);
  146. }
  147. /*******************************************************************************
  148. *
  149. * FUNCTION: acpi_ut_allocate_zeroed_and_track
  150. *
  151. * PARAMETERS: size - Size of the allocation
  152. * component - Component type of caller
  153. * module - Source file name of caller
  154. * line - Line number of caller
  155. *
  156. * RETURN: Address of the allocated memory on success, NULL on failure.
  157. *
  158. * DESCRIPTION: Subsystem equivalent of calloc.
  159. *
  160. ******************************************************************************/
  161. void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
  162. u32 component,
  163. const char *module, u32 line)
  164. {
  165. struct acpi_debug_mem_block *allocation;
  166. acpi_status status;
  167. /* Check for an inadvertent size of zero bytes */
  168. if (!size) {
  169. ACPI_WARNING((module, line,
  170. "Attempt to allocate zero bytes, allocating 1 byte"));
  171. size = 1;
  172. }
  173. allocation =
  174. acpi_os_allocate_zeroed(size +
  175. sizeof(struct acpi_debug_mem_header));
  176. if (!allocation) {
  177. /* Report allocation error */
  178. ACPI_ERROR((module, line,
  179. "Could not allocate size %u", (u32)size));
  180. return (NULL);
  181. }
  182. status = acpi_ut_track_allocation(allocation, size,
  183. ACPI_MEM_CALLOC, component, module,
  184. line);
  185. if (ACPI_FAILURE(status)) {
  186. acpi_os_free(allocation);
  187. return (NULL);
  188. }
  189. acpi_gbl_global_list->total_allocated++;
  190. acpi_gbl_global_list->total_size += (u32)size;
  191. acpi_gbl_global_list->current_total_size += (u32)size;
  192. if (acpi_gbl_global_list->current_total_size >
  193. acpi_gbl_global_list->max_occupied) {
  194. acpi_gbl_global_list->max_occupied =
  195. acpi_gbl_global_list->current_total_size;
  196. }
  197. return ((void *)&allocation->user_space);
  198. }
  199. /*******************************************************************************
  200. *
  201. * FUNCTION: acpi_ut_free_and_track
  202. *
  203. * PARAMETERS: allocation - Address of the memory to deallocate
  204. * component - Component type of caller
  205. * module - Source file name of caller
  206. * line - Line number of caller
  207. *
  208. * RETURN: None
  209. *
  210. * DESCRIPTION: Frees the memory at Allocation
  211. *
  212. ******************************************************************************/
  213. void
  214. acpi_ut_free_and_track(void *allocation,
  215. u32 component, const char *module, u32 line)
  216. {
  217. struct acpi_debug_mem_block *debug_block;
  218. acpi_status status;
  219. ACPI_FUNCTION_TRACE_PTR(ut_free, allocation);
  220. if (NULL == allocation) {
  221. ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
  222. return_VOID;
  223. }
  224. debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
  225. (((char *)allocation) -
  226. sizeof(struct acpi_debug_mem_header)));
  227. acpi_gbl_global_list->total_freed++;
  228. acpi_gbl_global_list->current_total_size -= debug_block->size;
  229. status = acpi_ut_remove_allocation(debug_block,
  230. component, module, line);
  231. if (ACPI_FAILURE(status)) {
  232. ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
  233. }
  234. acpi_os_free(debug_block);
  235. ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n",
  236. allocation, debug_block));
  237. return_VOID;
  238. }
  239. /*******************************************************************************
  240. *
  241. * FUNCTION: acpi_ut_find_allocation
  242. *
  243. * PARAMETERS: allocation - Address of allocated memory
  244. *
  245. * RETURN: Three cases:
  246. * 1) List is empty, NULL is returned.
  247. * 2) Element was found. Returns Allocation parameter.
  248. * 3) Element was not found. Returns position where it should be
  249. * inserted into the list.
  250. *
  251. * DESCRIPTION: Searches for an element in the global allocation tracking list.
  252. * If the element is not found, returns the location within the
  253. * list where the element should be inserted.
  254. *
  255. * Note: The list is ordered by larger-to-smaller addresses.
  256. *
  257. * This global list is used to detect memory leaks in ACPICA as
  258. * well as other issues such as an attempt to release the same
  259. * internal object more than once. Although expensive as far
  260. * as cpu time, this list is much more helpful for finding these
  261. * types of issues than using memory leak detectors outside of
  262. * the ACPICA code.
  263. *
  264. ******************************************************************************/
  265. static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
  266. acpi_debug_mem_block
  267. *allocation)
  268. {
  269. struct acpi_debug_mem_block *element;
  270. element = acpi_gbl_global_list->list_head;
  271. if (!element) {
  272. return (NULL);
  273. }
  274. /*
  275. * Search for the address.
  276. *
  277. * Note: List is ordered by larger-to-smaller addresses, on the
  278. * assumption that a new allocation usually has a larger address
  279. * than previous allocations.
  280. */
  281. while (element > allocation) {
  282. /* Check for end-of-list */
  283. if (!element->next) {
  284. return (element);
  285. }
  286. element = element->next;
  287. }
  288. if (element == allocation) {
  289. return (element);
  290. }
  291. return (element->previous);
  292. }
  293. /*******************************************************************************
  294. *
  295. * FUNCTION: acpi_ut_track_allocation
  296. *
  297. * PARAMETERS: allocation - Address of allocated memory
  298. * size - Size of the allocation
  299. * alloc_type - MEM_MALLOC or MEM_CALLOC
  300. * component - Component type of caller
  301. * module - Source file name of caller
  302. * line - Line number of caller
  303. *
  304. * RETURN: Status
  305. *
  306. * DESCRIPTION: Inserts an element into the global allocation tracking list.
  307. *
  308. ******************************************************************************/
  309. static acpi_status
  310. acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
  311. acpi_size size,
  312. u8 alloc_type,
  313. u32 component, const char *module, u32 line)
  314. {
  315. struct acpi_memory_list *mem_list;
  316. struct acpi_debug_mem_block *element;
  317. acpi_status status = AE_OK;
  318. ACPI_FUNCTION_TRACE_PTR(ut_track_allocation, allocation);
  319. if (acpi_gbl_disable_mem_tracking) {
  320. return_ACPI_STATUS(AE_OK);
  321. }
  322. mem_list = acpi_gbl_global_list;
  323. status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  324. if (ACPI_FAILURE(status)) {
  325. return_ACPI_STATUS(status);
  326. }
  327. /*
  328. * Search the global list for this address to make sure it is not
  329. * already present. This will catch several kinds of problems.
  330. */
  331. element = acpi_ut_find_allocation(allocation);
  332. if (element == allocation) {
  333. ACPI_ERROR((AE_INFO,
  334. "UtTrackAllocation: Allocation (%p) already present in global list!",
  335. allocation));
  336. goto unlock_and_exit;
  337. }
  338. /* Fill in the instance data */
  339. allocation->size = (u32)size;
  340. allocation->alloc_type = alloc_type;
  341. allocation->component = component;
  342. allocation->line = line;
  343. strncpy(allocation->module, module, ACPI_MAX_MODULE_NAME);
  344. allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
  345. if (!element) {
  346. /* Insert at list head */
  347. if (mem_list->list_head) {
  348. ((struct acpi_debug_mem_block *)(mem_list->list_head))->
  349. previous = allocation;
  350. }
  351. allocation->next = mem_list->list_head;
  352. allocation->previous = NULL;
  353. mem_list->list_head = allocation;
  354. } else {
  355. /* Insert after element */
  356. allocation->next = element->next;
  357. allocation->previous = element;
  358. if (element->next) {
  359. (element->next)->previous = allocation;
  360. }
  361. element->next = allocation;
  362. }
  363. unlock_and_exit:
  364. status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  365. return_ACPI_STATUS(status);
  366. }
  367. /*******************************************************************************
  368. *
  369. * FUNCTION: acpi_ut_remove_allocation
  370. *
  371. * PARAMETERS: allocation - Address of allocated memory
  372. * component - Component type of caller
  373. * module - Source file name of caller
  374. * line - Line number of caller
  375. *
  376. * RETURN: Status
  377. *
  378. * DESCRIPTION: Deletes an element from the global allocation tracking list.
  379. *
  380. ******************************************************************************/
  381. static acpi_status
  382. acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
  383. u32 component, const char *module, u32 line)
  384. {
  385. struct acpi_memory_list *mem_list;
  386. acpi_status status;
  387. ACPI_FUNCTION_NAME(ut_remove_allocation);
  388. if (acpi_gbl_disable_mem_tracking) {
  389. return (AE_OK);
  390. }
  391. mem_list = acpi_gbl_global_list;
  392. if (NULL == mem_list->list_head) {
  393. /* No allocations! */
  394. ACPI_ERROR((module, line,
  395. "Empty allocation list, nothing to free!"));
  396. return (AE_OK);
  397. }
  398. status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  399. if (ACPI_FAILURE(status)) {
  400. return (status);
  401. }
  402. /* Unlink */
  403. if (allocation->previous) {
  404. (allocation->previous)->next = allocation->next;
  405. } else {
  406. mem_list->list_head = allocation->next;
  407. }
  408. if (allocation->next) {
  409. (allocation->next)->previous = allocation->previous;
  410. }
  411. ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n",
  412. &allocation->user_space, allocation->size));
  413. /* Mark the segment as deleted */
  414. memset(&allocation->user_space, 0xEA, allocation->size);
  415. status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  416. return (status);
  417. }
  418. /*******************************************************************************
  419. *
  420. * FUNCTION: acpi_ut_dump_allocation_info
  421. *
  422. * PARAMETERS: None
  423. *
  424. * RETURN: None
  425. *
  426. * DESCRIPTION: Print some info about the outstanding allocations.
  427. *
  428. ******************************************************************************/
  429. void acpi_ut_dump_allocation_info(void)
  430. {
  431. /*
  432. struct acpi_memory_list *mem_list;
  433. */
  434. ACPI_FUNCTION_TRACE(ut_dump_allocation_info);
  435. /*
  436. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  437. ("%30s: %4d (%3d Kb)\n", "Current allocations",
  438. mem_list->current_count,
  439. ROUND_UP_TO_1K (mem_list->current_size)));
  440. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  441. ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
  442. mem_list->max_concurrent_count,
  443. ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
  444. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  445. ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
  446. running_object_count,
  447. ROUND_UP_TO_1K (running_object_size)));
  448. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  449. ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
  450. running_alloc_count,
  451. ROUND_UP_TO_1K (running_alloc_size)));
  452. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  453. ("%30s: %4d (%3d Kb)\n", "Current Nodes",
  454. acpi_gbl_current_node_count,
  455. ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
  456. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  457. ("%30s: %4d (%3d Kb)\n", "Max Nodes",
  458. acpi_gbl_max_concurrent_node_count,
  459. ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
  460. sizeof (struct acpi_namespace_node)))));
  461. */
  462. return_VOID;
  463. }
  464. /*******************************************************************************
  465. *
  466. * FUNCTION: acpi_ut_dump_allocations
  467. *
  468. * PARAMETERS: component - Component(s) to dump info for.
  469. * module - Module to dump info for. NULL means all.
  470. *
  471. * RETURN: None
  472. *
  473. * DESCRIPTION: Print a list of all outstanding allocations.
  474. *
  475. ******************************************************************************/
  476. void acpi_ut_dump_allocations(u32 component, const char *module)
  477. {
  478. struct acpi_debug_mem_block *element;
  479. union acpi_descriptor *descriptor;
  480. u32 num_outstanding = 0;
  481. u8 descriptor_type;
  482. ACPI_FUNCTION_TRACE(ut_dump_allocations);
  483. if (acpi_gbl_disable_mem_tracking) {
  484. return_VOID;
  485. }
  486. /*
  487. * Walk the allocation list.
  488. */
  489. if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
  490. return_VOID;
  491. }
  492. element = acpi_gbl_global_list->list_head;
  493. while (element) {
  494. if ((element->component & component) &&
  495. ((module == NULL)
  496. || (0 == strcmp(module, element->module)))) {
  497. descriptor =
  498. ACPI_CAST_PTR(union acpi_descriptor,
  499. &element->user_space);
  500. if (element->size <
  501. sizeof(struct acpi_common_descriptor)) {
  502. acpi_os_printf("%p Length 0x%04X %9.9s-%u "
  503. "[Not a Descriptor - too small]\n",
  504. descriptor, element->size,
  505. element->module, element->line);
  506. } else {
  507. /* Ignore allocated objects that are in a cache */
  508. if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
  509. ACPI_DESC_TYPE_CACHED) {
  510. acpi_os_printf
  511. ("%p Length 0x%04X %9.9s-%u [%s] ",
  512. descriptor, element->size,
  513. element->module, element->line,
  514. acpi_ut_get_descriptor_name
  515. (descriptor));
  516. /* Validate the descriptor type using Type field and length */
  517. descriptor_type = 0; /* Not a valid descriptor type */
  518. switch (ACPI_GET_DESCRIPTOR_TYPE
  519. (descriptor)) {
  520. case ACPI_DESC_TYPE_OPERAND:
  521. if (element->size ==
  522. sizeof(union
  523. acpi_operand_object))
  524. {
  525. descriptor_type =
  526. ACPI_DESC_TYPE_OPERAND;
  527. }
  528. break;
  529. case ACPI_DESC_TYPE_PARSER:
  530. if (element->size ==
  531. sizeof(union
  532. acpi_parse_object)) {
  533. descriptor_type =
  534. ACPI_DESC_TYPE_PARSER;
  535. }
  536. break;
  537. case ACPI_DESC_TYPE_NAMED:
  538. if (element->size ==
  539. sizeof(struct
  540. acpi_namespace_node))
  541. {
  542. descriptor_type =
  543. ACPI_DESC_TYPE_NAMED;
  544. }
  545. break;
  546. default:
  547. break;
  548. }
  549. /* Display additional info for the major descriptor types */
  550. switch (descriptor_type) {
  551. case ACPI_DESC_TYPE_OPERAND:
  552. acpi_os_printf
  553. ("%12.12s RefCount 0x%04X\n",
  554. acpi_ut_get_type_name
  555. (descriptor->object.common.
  556. type),
  557. descriptor->object.common.
  558. reference_count);
  559. break;
  560. case ACPI_DESC_TYPE_PARSER:
  561. acpi_os_printf
  562. ("AmlOpcode 0x%04hX\n",
  563. descriptor->op.asl.
  564. aml_opcode);
  565. break;
  566. case ACPI_DESC_TYPE_NAMED:
  567. acpi_os_printf("%4.4s\n",
  568. acpi_ut_get_node_name
  569. (&descriptor->
  570. node));
  571. break;
  572. default:
  573. acpi_os_printf("\n");
  574. break;
  575. }
  576. }
  577. }
  578. num_outstanding++;
  579. }
  580. element = element->next;
  581. }
  582. (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  583. /* Print summary */
  584. if (!num_outstanding) {
  585. ACPI_INFO((AE_INFO, "No outstanding allocations"));
  586. } else {
  587. ACPI_ERROR((AE_INFO, "%u(0x%X) Outstanding allocations",
  588. num_outstanding, num_outstanding));
  589. }
  590. return_VOID;
  591. }
  592. #endif /* ACPI_DBG_TRACK_ALLOCATIONS */