allocator.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2014 Google, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include "bt_common.h"
  21. #include "osi/allocator.h"
  22. extern void *pvPortZalloc(size_t size);
  23. extern void vPortFree(void *pv);
  24. #if HEAP_MEMORY_DEBUG
  25. #define OSI_MEM_DBG_INFO_MAX 1024*3
  26. typedef struct {
  27. void *p;
  28. int size;
  29. const char *func;
  30. int line;
  31. } osi_mem_dbg_info_t;
  32. static uint32_t mem_dbg_count = 0;
  33. static osi_mem_dbg_info_t mem_dbg_info[OSI_MEM_DBG_INFO_MAX];
  34. static uint32_t mem_dbg_current_size = 0;
  35. static uint32_t mem_dbg_max_size = 0;
  36. #define OSI_MEM_DBG_MAX_SECTION_NUM 5
  37. typedef struct {
  38. bool used;
  39. uint32_t max_size;
  40. } osi_mem_dbg_max_size_section_t;
  41. static osi_mem_dbg_max_size_section_t mem_dbg_max_size_section[OSI_MEM_DBG_MAX_SECTION_NUM];
  42. void osi_mem_dbg_init(void)
  43. {
  44. int i;
  45. for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
  46. mem_dbg_info[i].p = NULL;
  47. mem_dbg_info[i].size = 0;
  48. mem_dbg_info[i].func = NULL;
  49. mem_dbg_info[i].line = 0;
  50. }
  51. mem_dbg_count = 0;
  52. mem_dbg_current_size = 0;
  53. mem_dbg_max_size = 0;
  54. for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){
  55. mem_dbg_max_size_section[i].used = false;
  56. mem_dbg_max_size_section[i].max_size = 0;
  57. }
  58. }
  59. void osi_mem_dbg_record(void *p, int size, const char *func, int line)
  60. {
  61. int i;
  62. if (!p || size == 0) {
  63. OSI_TRACE_ERROR("%s invalid !!\n", __func__);
  64. return;
  65. }
  66. for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
  67. if (mem_dbg_info[i].p == NULL) {
  68. mem_dbg_info[i].p = p;
  69. mem_dbg_info[i].size = size;
  70. mem_dbg_info[i].func = func;
  71. mem_dbg_info[i].line = line;
  72. mem_dbg_count++;
  73. break;
  74. }
  75. }
  76. if (i >= OSI_MEM_DBG_INFO_MAX) {
  77. OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line);
  78. }
  79. mem_dbg_current_size += size;
  80. if(mem_dbg_max_size < mem_dbg_current_size) {
  81. mem_dbg_max_size = mem_dbg_current_size;
  82. }
  83. for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){
  84. if (mem_dbg_max_size_section[i].used) {
  85. if(mem_dbg_max_size_section[i].max_size < mem_dbg_current_size) {
  86. mem_dbg_max_size_section[i].max_size = mem_dbg_current_size;
  87. }
  88. }
  89. }
  90. }
  91. void osi_mem_dbg_clean(void *p, const char *func, int line)
  92. {
  93. int i;
  94. if (!p) {
  95. OSI_TRACE_ERROR("%s invalid\n", __func__);
  96. return;
  97. }
  98. for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
  99. if (mem_dbg_info[i].p == p) {
  100. mem_dbg_current_size -= mem_dbg_info[i].size;
  101. mem_dbg_info[i].p = NULL;
  102. mem_dbg_info[i].size = 0;
  103. mem_dbg_info[i].func = NULL;
  104. mem_dbg_info[i].line = 0;
  105. mem_dbg_count--;
  106. break;
  107. }
  108. }
  109. if (i >= OSI_MEM_DBG_INFO_MAX) {
  110. OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line);
  111. }
  112. }
  113. void osi_mem_dbg_show(void)
  114. {
  115. int i;
  116. for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
  117. if (mem_dbg_info[i].p || mem_dbg_info[i].size != 0 ) {
  118. OSI_TRACE_ERROR("--> p %p, s %d, f %s, l %d\n", mem_dbg_info[i].p, mem_dbg_info[i].size, mem_dbg_info[i].func, mem_dbg_info[i].line);
  119. }
  120. }
  121. OSI_TRACE_ERROR("--> count %d\n", mem_dbg_count);
  122. OSI_TRACE_ERROR("--> size %dB\n--> max size %dB\n", mem_dbg_current_size, mem_dbg_max_size);
  123. }
  124. uint32_t osi_mem_dbg_get_max_size(void)
  125. {
  126. return mem_dbg_max_size;
  127. }
  128. uint32_t osi_mem_dbg_get_current_size(void)
  129. {
  130. return mem_dbg_current_size;
  131. }
  132. void osi_men_dbg_set_section_start(uint8_t index)
  133. {
  134. if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) {
  135. OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
  136. OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
  137. return;
  138. }
  139. if (mem_dbg_max_size_section[index].used) {
  140. OSI_TRACE_WARNING("This index(%d) has been started, restart it.\n", index);
  141. }
  142. mem_dbg_max_size_section[index].used = true;
  143. mem_dbg_max_size_section[index].max_size = mem_dbg_current_size;
  144. }
  145. void osi_men_dbg_set_section_end(uint8_t index)
  146. {
  147. if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) {
  148. OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
  149. OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
  150. return;
  151. }
  152. if (!mem_dbg_max_size_section[index].used) {
  153. OSI_TRACE_ERROR("This index(%d) has not been started.\n", index);
  154. return;
  155. }
  156. mem_dbg_max_size_section[index].used = false;
  157. }
  158. uint32_t osi_mem_dbg_get_max_size_section(uint8_t index)
  159. {
  160. if (index >= OSI_MEM_DBG_MAX_SECTION_NUM){
  161. OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n",
  162. OSI_MEM_DBG_MAX_SECTION_NUM - 1, index);
  163. return 0;
  164. }
  165. return mem_dbg_max_size_section[index].max_size;
  166. }
  167. #endif
  168. char *osi_strdup(const char *str)
  169. {
  170. size_t size = strlen(str) + 1; // + 1 for the null terminator
  171. char *new_string = (char *)osi_calloc(size);
  172. if (!new_string) {
  173. return NULL;
  174. }
  175. memcpy(new_string, str, size);
  176. return new_string;
  177. }
  178. void *osi_malloc_func(size_t size)
  179. {
  180. #if HEAP_MEMORY_DEBUG
  181. void *p;
  182. #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
  183. p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
  184. #else
  185. p = malloc(size);
  186. #endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
  187. osi_mem_dbg_record(p, size, __func__, __LINE__);
  188. return p;
  189. #else
  190. #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
  191. return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
  192. #else
  193. return malloc(size);
  194. #endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
  195. #endif /* #if HEAP_MEMORY_DEBUG */
  196. }
  197. void *osi_calloc_func(size_t size)
  198. {
  199. #if HEAP_MEMORY_DEBUG
  200. void *p;
  201. #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
  202. p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
  203. #else
  204. p = calloc(1, size);
  205. #endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
  206. osi_mem_dbg_record(p, size, __func__, __LINE__);
  207. return p;
  208. #else
  209. #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
  210. return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
  211. #else
  212. return calloc(1, size);
  213. #endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
  214. #endif /* #if HEAP_MEMORY_DEBUG */
  215. }
  216. void osi_free_func(void *ptr)
  217. {
  218. #if HEAP_MEMORY_DEBUG
  219. osi_mem_dbg_clean(ptr, __func__, __LINE__);
  220. #endif
  221. free(ptr);
  222. }