dump.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include <os_common_api.h>
  2. #include <buddy_inner.h>
  3. #include <page_inner.h>
  4. #include <mem_buddy.h>
  5. extern void pagepool_use_dump(uint32_t use_size);
  6. void dump_mem_register_callback(void (*cb)(int32_t prio, uint32_t alloc_size, uint32_t in_isr));
  7. extern struct mem_info sys_meminfo;
  8. #ifdef CONFIG_MEMORY_ANALYSIS
  9. #define MAX_THREAD_NUM 16
  10. uint32_t alloc_num[6];
  11. uint32_t isr_alloc_size;
  12. struct heap_info
  13. {
  14. uint32_t prio:8;
  15. uint32_t size:24;
  16. };
  17. struct heap_info thread_heap_info[MAX_THREAD_NUM];
  18. static const char alloc_type[][5] =
  19. {
  20. "<=16",
  21. "<=32",
  22. "<=48",
  23. "<=64",
  24. "< 2k",
  25. ">=2k",
  26. };
  27. static void _mem_buddy_debug_info_reset(void)
  28. {
  29. memset(alloc_num, 0, sizeof(alloc_num));
  30. }
  31. static void _mem_buddy_debug_info_dump(void)
  32. {
  33. uint32_t i;
  34. uint32_t cur_size;
  35. uint32_t total_size = 0;
  36. for(i = 0; i < ARRAY_SIZE(alloc_num); i++){
  37. k_busy_wait(5000);
  38. if(i < (ARRAY_SIZE(alloc_num) - 1)){
  39. cur_size = (alloc_num[i] * ((i + 1) << 4));
  40. printk("alloc type(%s):\t%5u (%2u %%)\n", &alloc_type[i][0], alloc_num[i], \
  41. cur_size * 100 / sys_meminfo.alloc_size);
  42. total_size += cur_size;
  43. }else{
  44. printk("alloc type(%s):\t%5u (%2u %%)\n", &alloc_type[i][0], alloc_num[i], \
  45. (sys_meminfo.alloc_size - total_size) * 100 / sys_meminfo.alloc_size);
  46. }
  47. }
  48. }
  49. static void _mem_buddy_thread_heap_reset(void)
  50. {
  51. uint32_t i;
  52. for(i = 0; i < MAX_THREAD_NUM; i++){
  53. thread_heap_info[i].size = 0;
  54. thread_heap_info[i].prio = 0xff;
  55. }
  56. isr_alloc_size = 0;
  57. }
  58. static void _mem_buddy_thread_heap_use(int prio, uint32_t size, uint32_t in_isr)
  59. {
  60. uint32_t i;
  61. if(in_isr){
  62. isr_alloc_size += size;
  63. return;
  64. }
  65. for(i = 0; i < MAX_THREAD_NUM; i++){
  66. if(thread_heap_info[i].prio == prio){
  67. thread_heap_info[i].size += size;
  68. return;
  69. }
  70. }
  71. for(i = 0; i < MAX_THREAD_NUM; i++){
  72. if(thread_heap_info[i].prio == 0xff){
  73. thread_heap_info[i].prio = prio;
  74. thread_heap_info[i].size += size;
  75. return;
  76. }
  77. }
  78. return;
  79. }
  80. static int _mem_buddy_thread_heap_dump(void)
  81. {
  82. uint32_t i;
  83. uint32_t alloc_size = 0;
  84. for(i = 0; i < MAX_THREAD_NUM; i++){
  85. if(thread_heap_info[i].prio != 0xff){
  86. printk("alloc task(%4d):\t%5u (%2u %%) prio (%d)\n", thread_heap_info[i].prio, thread_heap_info[i].size, \
  87. thread_heap_info[i].size * 100 / sys_meminfo.alloc_size, \
  88. thread_heap_info[i].prio);
  89. alloc_size += thread_heap_info[i].size;
  90. }
  91. }
  92. printk("alloc isr: \t%5u (%2u %%)\n", isr_alloc_size, \
  93. isr_alloc_size * 100 / sys_meminfo.alloc_size);
  94. alloc_size += isr_alloc_size;
  95. printk("others : \t%5u (%2u %%)\n", (sys_meminfo.alloc_size - alloc_size), \
  96. (sys_meminfo.alloc_size - alloc_size) * 100 / sys_meminfo.alloc_size);
  97. return 0;
  98. }
  99. static void _mem_buddy_dump_callback(int32_t prio, uint32_t alloc_size, uint32_t in_isr)
  100. {
  101. if(alloc_size >= 80 && alloc_size < 2048){
  102. alloc_size = 80;
  103. }
  104. if(alloc_size != 2048){
  105. alloc_num[(alloc_size >> 4) - 1]++;
  106. }else{
  107. alloc_num[5]++;
  108. }
  109. _mem_buddy_thread_heap_use(prio, alloc_size, in_isr);
  110. }
  111. #endif
  112. static void _mem_buddy_dump_memory(struct mem_info *mem_info, uint32_t dump_detail, const char *match_str)
  113. {
  114. int i, page_num;
  115. int8_t buddy_no;
  116. void *page;
  117. #ifdef CONFIG_SYS_IRQ_LOCK
  118. SYS_IRQ_FLAGS flags;
  119. if(dump_detail){
  120. sys_irq_lock(&flags);
  121. }
  122. #endif
  123. for(i = 0; i < sizeof(mem_info->buddys)/sizeof(mem_info->buddys[0]); i++)
  124. {
  125. if(mem_info->buddys[i] == (uint8_t)-1)
  126. break;
  127. buddy_no = mem_info->buddys[i] & 0x7f;
  128. if((mem_info->buddys[i] & 0x80) == 0)
  129. {
  130. if(buddy_dump(buddy_no, dump_detail, match_str) == false)
  131. os_printk("BUG:buddy %d broken, maybe overflow happened!\n", buddy_no);
  132. continue;
  133. }
  134. if(i == 0)
  135. continue;
  136. page = pagepool_convert_index_to_addr(buddy_no);
  137. if(i + 1 < sizeof(mem_info->buddys)/sizeof(mem_info->buddys[0])
  138. && mem_info->buddys[i + 1] != 0xff
  139. && (mem_info->buddys[i + 1] & (int8_t)0xc0) == (int8_t)0xc0)
  140. {
  141. page_num = mem_info->buddys[i + 1] & (int8_t)0x3f;
  142. i++;
  143. }
  144. else
  145. {
  146. page_num = 1;
  147. }
  148. dump_show_info(page, page_num * PAGE_SIZE,
  149. (void *)((char *)page + (page_num * PAGE_SIZE) - 8),
  150. dump_detail,match_str);
  151. }
  152. #ifdef CONFIG_SYS_IRQ_LOCK
  153. if(dump_detail){
  154. sys_irq_unlock(&flags);
  155. }
  156. #endif
  157. }
  158. void mem_buddy_dump_info(uint32_t dump_detail, const char *match_str)
  159. {
  160. pagepool_use_dump(sys_meminfo.alloc_size);
  161. #ifdef CONFIG_MEMORY_ANALYSIS
  162. dump_mem_register_callback(_mem_buddy_dump_callback);
  163. _mem_buddy_debug_info_reset();
  164. _mem_buddy_thread_heap_reset();
  165. #endif
  166. printk("\nsys memory used:\n");
  167. printk("\ttotal size: %d\n", sys_meminfo.alloc_size);
  168. printk("\toriginal size: %d\n", sys_meminfo.original_size);
  169. if(dump_detail){
  170. printk("\tmalloc detail:\n");
  171. printk("%4s (%4s %4s) %12s %12s\n","addr","asize","rsize", "thread", "tag");
  172. _mem_buddy_dump_memory(&sys_meminfo, dump_detail, match_str);
  173. #ifdef CONFIG_MEMORY_ANALYSIS
  174. _mem_buddy_debug_info_dump();
  175. _mem_buddy_thread_heap_dump();
  176. #endif
  177. }
  178. }