malloc.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "heap.h"
  2. #ifdef CONFIG_ACTIONS_TRACE
  3. #include <trace.h>
  4. #endif
  5. #include <os_common_api.h>
  6. #include <kernel.h>
  7. #include <kernel_structs.h>
  8. #include <mem_manager_version.h>
  9. #define enableFuncSect 0
  10. extern void trace_set_panic(void);
  11. void malloc_err_print(int who, unsigned int data, void *caller, int result)
  12. {
  13. const char *whos_name[2] = {"malloc", "malloc_anon"};
  14. #ifdef CONFIG_ACTIONS_TRACE
  15. trace_set_panic();
  16. #endif
  17. mem_buddy_dump_info(DUMP_DETAIL_TYPE, NULL);
  18. os_printk("%s 0x%x failed, caller 0x%p error ret %d\n", whos_name[who], data, caller, result);
  19. //panic("buddy malloc error");
  20. }
  21. void * mem_buddy_malloc(int size, int need_size, struct mem_info *mem_info, void *caller)
  22. {
  23. #ifdef CONFIG_SYS_IRQ_LOCK
  24. SYS_IRQ_FLAGS flags;
  25. #endif
  26. int i, real, result;
  27. uint8_t page_no, new_buddy;
  28. void *page, *addr;
  29. struct buddy_debug_info buddy_debug;
  30. if(size == 0 || mem_info == NULL)
  31. return NULL;
  32. real = size;
  33. #ifdef CONFIG_SYS_IRQ_LOCK
  34. sys_irq_lock(&flags);
  35. #endif
  36. if(size > get_buddy_max())
  37. {
  38. int page_num = SIZE2PAGE(size);
  39. result = (mem_info->buddys[BUDDYS_SIZE - 2] != (uint8_t)-1);
  40. if(result){
  41. result = 1;
  42. goto err_ret;
  43. }
  44. page = pmalloc(size, caller);
  45. if(page == NULL){
  46. result = 2;
  47. goto err_ret;
  48. }
  49. page_no = pagepool_convert_addr_to_pageindex(page);
  50. result = (mem_info->buddys[BUDDYS_SIZE - 2] != (uint8_t)-1);
  51. if(result)
  52. {
  53. pfree(page, page_num, caller);
  54. result = 3;
  55. goto err_ret;
  56. }
  57. for(i = 0; i < BUDDYS_SIZE; i++)
  58. {
  59. if(mem_info->buddys[i] == (uint8_t)-1)
  60. break;
  61. }
  62. mem_info->buddys[i] = page_no | 0x80;
  63. // if(page_num > 1)
  64. mem_info->buddys[i + 1] = page_num | 0xc0;
  65. addr = page;
  66. real = PAGE2SIZE(page_num);
  67. goto success;
  68. }
  69. for(i = 0; i < BUDDYS_SIZE; i++)
  70. {
  71. if(mem_info->buddys[i] == (uint8_t)-1)
  72. break;
  73. if(mem_info->buddys[i] & 0x80)
  74. continue;
  75. addr = buddy_alloc(mem_info->buddys[i], &real);
  76. if(addr != NULL)
  77. {
  78. goto success;
  79. }
  80. }
  81. result = (mem_info->buddys[BUDDYS_SIZE - 1] != (uint8_t)-1);
  82. if(result){
  83. result = 4;
  84. goto err_ret;
  85. }
  86. page = pmalloc(PAGE_SIZE, caller);
  87. if(page == NULL){
  88. result = 5;
  89. goto err_ret;
  90. }
  91. page_no = pagepool_convert_addr_to_pageindex(page);
  92. new_buddy = rom_new_buddy_no(page_no, &g_rom_buddy_data);
  93. addr = buddy_alloc(new_buddy, &real);
  94. result = (mem_info->buddys[BUDDYS_SIZE - 1] != (uint8_t)-1);
  95. if(result)
  96. {
  97. pfree(page, 1, caller);
  98. result = 6;
  99. goto err_ret;
  100. }
  101. for(i = 0; i < BUDDYS_SIZE; i++)
  102. {
  103. if(mem_info->buddys[i] == (uint8_t)-1)
  104. break;
  105. }
  106. mem_info->buddys[i] = new_buddy;
  107. success:
  108. #ifdef CONFIG_SYS_IRQ_LOCK
  109. sys_irq_unlock(&flags);
  110. #endif
  111. size = ((size + 3) / 4) * 4;
  112. buddy_debug.caller = PTR_DEFLATE(caller);
  113. if(os_is_in_isr()){
  114. buddy_debug.prio = INVALID_THREAD_PRIO;
  115. }else{
  116. buddy_debug.prio = k_thread_priority_get(k_current_get());
  117. }
  118. buddy_debug.size = size;
  119. buddy_debug.size_mask = (~((unsigned short)size + (unsigned short)0x1234));
  120. memcpy((void **)((char *)addr + real - 8), &buddy_debug, sizeof(buddy_debug));
  121. memset(addr, 0, need_size);
  122. #ifdef CONFIG_SYS_IRQ_LOCK
  123. sys_irq_lock(&flags);
  124. #endif
  125. mem_info->alloc_size += real;
  126. mem_info->original_size += size;
  127. #ifdef CONFIG_SYS_IRQ_LOCK
  128. sys_irq_unlock(&flags);
  129. #endif
  130. #ifdef CONFIG_ACTIONS_TRACE
  131. TRACE_MALLOC(addr, size, caller);
  132. #endif
  133. return addr;
  134. err_ret:
  135. malloc_err_print(1, size, caller, result);
  136. #ifdef CONFIG_SYS_IRQ_LOCK
  137. sys_irq_unlock(&flags);
  138. #endif
  139. return NULL;
  140. }
  141. /**
  142. *
  143. * @brief Return the libmem manager version of the present build
  144. *
  145. * The libmem manager version is a four-byte value, whose format is described in the
  146. * file "mem_manager_version.h".
  147. *
  148. * @return mem manager version
  149. */
  150. uint32_t libmemmgr_version_get(void)
  151. {
  152. return LIBMEMMGR_VERSION_NUMBER;
  153. }