luat_malloc_air101.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // 这个文件包含 系统heap和lua heap的默认实现
  2. #include <stdlib.h>
  3. #include <string.h>//add for memset
  4. #include "bget.h"
  5. #include "luat_malloc.h"
  6. #include "FreeRTOS.h"
  7. #define LUAT_LOG_TAG "heap"
  8. #include "luat_log.h"
  9. #include "wm_mem.h"
  10. #ifdef LUAT_USE_WLAN
  11. #define LUAT_HEAP_MIN_SIZE (100*1024)
  12. #undef LUAT_HEAP_SIZE
  13. #define LUAT_HEAP_SIZE LUAT_HEAP_MIN_SIZE
  14. #else
  15. #define LUAT_HEAP_MIN_SIZE (128*1024)
  16. #endif
  17. #ifndef LUAT_HEAP_SIZE
  18. #ifdef LUAT_USE_NIMBLE
  19. #define LUAT_HEAP_SIZE (128+16)*1024
  20. #else
  21. #define LUAT_HEAP_SIZE (128+48)*1024
  22. #endif
  23. #endif
  24. #if (LUAT_HEAP_SIZE < LUAT_HEAP_MIN_SIZE)
  25. #undef LUAT_HEAP_SIZE
  26. #define LUAT_HEAP_SIZE LUAT_HEAP_MIN_SIZE
  27. #endif
  28. #if (LUAT_HEAP_SIZE > LUAT_HEAP_MIN_SIZE)
  29. __attribute__((aligned(8))) static uint64_t heap_ext[(LUAT_HEAP_SIZE - LUAT_HEAP_MIN_SIZE) / 8];
  30. #endif
  31. #ifdef LUAT_USE_TLSF
  32. #include "tlsf.h"
  33. tlsf_t luavm_tlsf;
  34. pool_t luavm_tlsf_ext;
  35. #endif
  36. #ifdef LUAT_USE_PROFILER
  37. #include "luat_profiler.h"
  38. extern int luat_profiler_memdebug;
  39. extern luat_profiler_mem_t profiler_memregs[];
  40. #endif
  41. void luat_heap_init(void) {
  42. // 毕竟sram还是快很多的, 优先sram吧
  43. #ifndef LUAT_USE_TLSF
  44. bpool((void*)(0x20048000 - LUAT_HEAP_MIN_SIZE), LUAT_HEAP_MIN_SIZE);
  45. #else
  46. luavm_tlsf = tlsf_create_with_pool((void*)(0x20048000 - LUAT_HEAP_MIN_SIZE), LUAT_HEAP_MIN_SIZE);
  47. #endif
  48. #ifdef LUAT_USE_PSRAM
  49. char test[] = {0xAA, 0xBB, 0xCC, 0xDD};
  50. char* psram_ptr = (void*)0x30010000;
  51. LLOGD("check psram ...");
  52. memcpy(psram_ptr, test, 4);
  53. if (memcmp(psram_ptr, test, 4)) {
  54. LLOGE("psram is enable, but can't access!!");
  55. }
  56. else {
  57. LLOGD("psram is ok");
  58. memset(psram_ptr, 0, 1024);
  59. // 存在psram, 加入到内存次, 就不使用系统额外的内存了.
  60. #ifdef LUAT_USE_TLSF
  61. luavm_tlsf_ext = tlsf_add_pool(luavm_tlsf, psram_ptr, 4*1024*1024);
  62. #else
  63. bpool(psram_ptr, 4*1024*1024); // 如果是8M内存, 改成 8也可以.
  64. #endif
  65. luat_main();
  66. return;
  67. }
  68. #else
  69. // 暂时还是放在这里吧, 考虑改到0x20028000之前
  70. #if (LUAT_HEAP_SIZE > LUAT_HEAP_MIN_SIZE)
  71. #ifndef LUAT_USE_TLSF
  72. bpool((void*)heap_ext, LUAT_HEAP_SIZE - LUAT_HEAP_MIN_SIZE);
  73. #else
  74. luavm_tlsf_ext = tlsf_add_pool(luavm_tlsf, heap_ext, LUAT_HEAP_SIZE - LUAT_HEAP_MIN_SIZE);
  75. #endif
  76. #endif
  77. #endif
  78. }
  79. //------------------------------------------------
  80. // 管理系统内存
  81. void* luat_heap_malloc(size_t len) {
  82. return tls_mem_alloc(len);
  83. }
  84. void luat_heap_free(void* ptr) {
  85. if (ptr == NULL)
  86. return;
  87. tls_mem_free(ptr);
  88. }
  89. void* luat_heap_realloc(void* ptr, size_t len) {
  90. return tls_mem_realloc(ptr, len);
  91. }
  92. void* luat_heap_calloc(size_t count, size_t _size) {
  93. return tls_mem_calloc(count, _size);
  94. }
  95. extern unsigned int heap_size_max;
  96. extern unsigned int total_mem_size;
  97. extern size_t __heap_start;
  98. extern size_t __heap_end;
  99. void luat_meminfo_sys(size_t* total, size_t* used, size_t* max_used)
  100. {
  101. #if configUSE_HEAP4
  102. extern void vPortGetHeapStats( HeapStats_t *pxHeapStats );
  103. HeapStats_t stat = {0};
  104. vPortGetHeapStats(&stat);
  105. *total = (size_t)(&__heap_end) - (size_t)(&__heap_start);
  106. *max_used = *total - stat.xMinimumEverFreeBytesRemaining;
  107. *used = (*total) - (stat.xAvailableHeapSpaceInBytes);
  108. #else
  109. *used = heap_size_max - total_mem_size;
  110. *max_used = *used;
  111. *total = heap_size_max;
  112. #endif
  113. }
  114. //------------------------------------------------
  115. //------------------------------------------------
  116. // ---------- 管理 LuaVM所使用的内存----------------
  117. #ifdef LUAT_USE_TLSF
  118. #include "tlsf.h"
  119. // extern tlsf_t luavm_tlsf;
  120. // extern pool_t luavm_tlsf_ext;
  121. void* __attribute__((section (".ram_run"))) luat_heap_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  122. if (ptr == NULL && nsize == 0)
  123. return NULL;
  124. #ifdef LUAT_USE_MEMORY_OPTIMIZATION_CODE_MMAP
  125. if (ptr != NULL) {
  126. uint32_t ptrv = (uint32_t)ptr;
  127. if (ptrv >= 0x08000000 && ptrv < 0x08200000) {
  128. //LLOGD("??? %p %d %d", ptr, osize, nsize);
  129. if (nsize == 0)
  130. return NULL;
  131. }
  132. }
  133. #endif
  134. return tlsf_realloc(luavm_tlsf, ptr, nsize);
  135. }
  136. void luat_meminfo_luavm(size_t *total, size_t *used, size_t *max_used) {
  137. *total = 0;
  138. *used = 0;
  139. *max_used = 0;
  140. tlsf_stat(tlsf_get_pool(luavm_tlsf), total, used, max_used);
  141. if (luavm_tlsf_ext) {
  142. tlsf_stat(luavm_tlsf_ext, total, used, max_used);
  143. }
  144. }
  145. #else
  146. void* __attribute__((section (".ram_run"))) luat_heap_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  147. (void)ud;
  148. if (ptr == NULL && nsize == 0)
  149. return NULL;
  150. #ifdef LUAT_USE_MEMORY_OPTIMIZATION_CODE_MMAP
  151. if (ptr != NULL) {
  152. uint32_t ptrv = (uint32_t)ptr;
  153. if (ptrv >= 0x08000000 && ptrv < 0x08200000) {
  154. // LLOGD("??? %p %d %d", ptr, osize, nsize);
  155. return NULL;
  156. }
  157. }
  158. #endif
  159. if (0) {
  160. if (ptr) {
  161. if (nsize) {
  162. // 缩放内存块
  163. LLOGD("realloc %p from %d to %d", ptr, osize, nsize);
  164. }
  165. else {
  166. // 释放内存块
  167. LLOGD("free %p ", ptr);
  168. brel(ptr);
  169. return NULL;
  170. }
  171. }
  172. else {
  173. // 申请内存块
  174. ptr = bget(nsize);
  175. LLOGD("malloc %p type=%d size=%d", ptr, osize, nsize);
  176. return ptr;
  177. }
  178. }
  179. if (nsize)
  180. {
  181. void* ptmp = bgetr(ptr, nsize);
  182. if(ptmp == NULL && osize >= nsize)
  183. {
  184. return ptr;
  185. }
  186. return ptmp;
  187. }
  188. brel(ptr);
  189. return NULL;
  190. }
  191. void luat_meminfo_luavm(size_t *total, size_t *used, size_t *max_used) {
  192. long curalloc, totfree, maxfree;
  193. unsigned long nget, nrel;
  194. bstats(&curalloc, &totfree, &maxfree, &nget, &nrel);
  195. *used = curalloc;
  196. *max_used = bstatsmaxget();
  197. *total = curalloc + totfree;
  198. }
  199. #endif
  200. //-----------------------------------------------------------------------------
  201. #include "wm_include.h"
  202. #include "FreeRTOS.h"
  203. #include "stdio.h"
  204. #ifdef LUAT_USE_PROFILER
  205. void* __wrap_malloc(size_t len) {
  206. #ifdef LUAT_USE_PROFILER
  207. void* ptr = pvPortMalloc(len);
  208. if (luat_profiler_memdebug) {
  209. printf("malloc %d %p\n", len, ptr);
  210. if (ptr == NULL)
  211. return NULL;
  212. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  213. {
  214. if (profiler_memregs[i].addr == 0) {
  215. profiler_memregs[i].addr = (uint32)ptr;
  216. profiler_memregs[i].len = len;
  217. break;
  218. }
  219. }
  220. }
  221. return ptr;
  222. #else
  223. return pvPortMalloc(len);
  224. #endif
  225. }
  226. void __wrap_free(void* ptr) {
  227. if (ptr == NULL)
  228. return;
  229. #ifdef LUAT_USE_PROFILER
  230. if (luat_profiler_memdebug)
  231. printf("free %p\n", ptr);
  232. #endif
  233. u32 addr = (u32)ptr;
  234. if (addr >= 0x20000000 && addr <= 0x40000000) {
  235. // printf("free %p\n", ptr);
  236. vPortFree(ptr);
  237. #ifdef LUAT_USE_PROFILER
  238. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  239. {
  240. if (profiler_memregs[i].addr == addr) {
  241. profiler_memregs[i].len = 0;
  242. profiler_memregs[i].addr = 0;
  243. break;
  244. }
  245. }
  246. #endif
  247. }
  248. }
  249. void *pvPortRealloc( void *pv, size_t xWantedSize );
  250. void* __wrap_realloc(void*ptr, size_t len) {
  251. #ifdef LUAT_USE_PROFILER
  252. void* newptr = pvPortRealloc(ptr, len);
  253. if (luat_profiler_memdebug && newptr) {
  254. printf("realloc %p %d %p\n", ptr, len, newptr);
  255. uint32_t addr = (uint32_t)ptr;
  256. uint32_t naddr = (uint32_t)newptr;
  257. if (ptr == newptr) {
  258. // 相同内存地址, 只是扩容了
  259. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  260. {
  261. if (profiler_memregs[i].addr == addr) {
  262. profiler_memregs[i].len = len;
  263. addr = 0;
  264. break;
  265. }
  266. }
  267. if (0 != addr) {
  268. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  269. {
  270. if (profiler_memregs[i].addr == 0) {
  271. profiler_memregs[i].addr = addr;
  272. profiler_memregs[i].len = len;
  273. break;
  274. }
  275. }
  276. }
  277. }
  278. else {
  279. if (ptr == NULL) {
  280. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  281. {
  282. if (profiler_memregs[i].addr == 0) {
  283. profiler_memregs[i].addr = naddr;
  284. profiler_memregs[i].len = len;
  285. break;
  286. }
  287. }
  288. }
  289. else {
  290. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  291. {
  292. if (profiler_memregs[i].addr == addr) {
  293. profiler_memregs[i].addr = 0;
  294. profiler_memregs[i].len = 0;
  295. break;
  296. }
  297. }
  298. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  299. {
  300. if (profiler_memregs[i].addr == 0) {
  301. profiler_memregs[i].addr = naddr;
  302. profiler_memregs[i].len = len;
  303. break;
  304. }
  305. }
  306. }
  307. }
  308. }
  309. return newptr;
  310. #endif
  311. return pvPortRealloc(ptr, len);
  312. }
  313. void* __wrap_calloc(size_t itemCount, size_t itemSize) {
  314. void* ptr = pvPortMalloc(itemCount * itemSize);
  315. #ifdef LUAT_USE_PROFILER
  316. if (luat_profiler_memdebug) {
  317. printf("calloc %p %d\n", ptr, itemCount * itemSize);
  318. if (ptr) {
  319. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  320. {
  321. if (profiler_memregs[i].addr == 0) {
  322. profiler_memregs[i].addr = (uint32_t)ptr;
  323. profiler_memregs[i].len = itemCount * itemSize;
  324. break;
  325. }
  326. }
  327. }
  328. }
  329. #endif
  330. if (ptr == NULL)
  331. return NULL;
  332. memset(ptr, 0, itemCount * itemSize);
  333. return ptr;
  334. }
  335. void* __wrap_zalloc(size_t size) {
  336. void* ptr = pvPortMalloc(size);
  337. #ifdef LUAT_USE_PROFILER
  338. if (luat_profiler_memdebug) {
  339. printf("zalloc %p %d\n", ptr, size);
  340. if (ptr) {
  341. for (size_t i = 0; i < LUAT_PROFILER_MEMDEBUG_ADDR_COUNT; i++)
  342. {
  343. if (profiler_memregs[i].addr == 0) {
  344. profiler_memregs[i].addr = (uint32_t)ptr;
  345. profiler_memregs[i].len = size;
  346. break;
  347. }
  348. }
  349. }
  350. }
  351. #endif
  352. if (ptr == NULL)
  353. return NULL;
  354. memset(ptr, 0, size);
  355. return ptr;
  356. }
  357. #else
  358. // 标准实现
  359. void* __wrap_malloc(size_t len) {
  360. return pvPortMalloc(len);
  361. }
  362. void __wrap_free(void* ptr) {
  363. if (ptr == NULL)
  364. return;
  365. u32 addr = (u32)ptr;
  366. if (addr >= 0x20000000 && addr <= 0x40000000) {
  367. vPortFree(ptr);
  368. }
  369. }
  370. void *pvPortRealloc( void *pv, size_t xWantedSize );
  371. void* __wrap_realloc(void*ptr, size_t len) {
  372. return pvPortRealloc(ptr, len);
  373. }
  374. void* __wrap_calloc(size_t itemCount, size_t itemSize) {
  375. void* ptr = pvPortMalloc(itemCount * itemSize);
  376. if (ptr == NULL)
  377. return NULL;
  378. memset(ptr, 0, itemCount * itemSize);
  379. return ptr;
  380. }
  381. void* __wrap_zalloc(size_t size) {
  382. void* ptr = pvPortMalloc(size);
  383. if (ptr == NULL)
  384. return NULL;
  385. memset(ptr, 0, size);
  386. return ptr;
  387. }
  388. #endif