luat_malloc_air101.c 12 KB

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