xref: /OK3568_Linux_fs/external/mpp/osal/mpp_mem.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "mpp_mem"
18 
19 #include <string.h>
20 
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_list.h"
24 #include "mpp_debug.h"
25 #include "mpp_common.h"
26 
27 #include "os_mem.h"
28 
29 // mpp_mem_debug bit mask
30 #define MEM_DEBUG_EN            (0x00000001)
31 // NOTE: runtime log need debug enable
32 #define MEM_RUNTIME_LOG         (0x00000002)
33 #define MEM_NODE_LOG            (0x00000004)
34 #define MEM_EXT_ROOM            (0x00000010)
35 #define MEM_POISON              (0x00000020)
36 
37 // default memory align size is set to 32
38 #define MEM_MAX_INDEX           (0x7fffffff)
39 #define MEM_ALIGN               32
40 #define MEM_ALIGN_MASK          (MEM_ALIGN - 1)
41 #define MEM_ALIGNED(x)          (((x) + MEM_ALIGN) & (~MEM_ALIGN_MASK))
42 #define MEM_HEAD_ROOM(debug)    ((debug & MEM_EXT_ROOM) ? (MEM_ALIGN) : (0))
43 #define MEM_NODE_MAX            (1024)
44 #define MEM_FREE_MAX            (512)
45 #define MEM_LOG_MAX             (1024)
46 #define MEM_CHECK_MARK          (0xdd)
47 #define MEM_HEAD_MASK           (0xab)
48 #define MEM_TAIL_MASK           (0xcd)
49 
50 #define MPP_MEM_ASSERT(cond) \
51     do { \
52         if (!(cond)) { \
53             mpp_err("found mpp_mem assert failed, start dumping:\n"); \
54             service.dump(__FUNCTION__); \
55             mpp_assert(cond); \
56         } \
57     } while (0)
58 
59 typedef enum MppMemOps_e {
60     MEM_MALLOC,
61     MEM_REALLOC,
62     MEM_FREE,
63     MEM_FREE_DELAY,
64 
65     MEM_OPS_BUTT,
66 } MppMemOps;
67 
68 /*
69  * Here we combined valid flag with index value to keep node structure small
70  * If index >= 0 this node is valid otherwise it is invalid
71  * When we need to invalid one index use ~ to revert all bit
72  * Then max valid index is 0x7fffffff. When index goes beyond it and becomes
73  * negative value index will be reset to zero.
74  */
75 typedef struct MppMemNode_s {
76     RK_S32      index;
77     size_t      size;
78     void        *ptr;
79     const char  *caller;
80 } MppMemNode;
81 
82 typedef struct MppMemLog_s {
83     RK_U32      index;
84     MppMemOps   ops;
85     size_t      size_0;         // size at input
86     size_t      size_1;         // size at output
87     void        *ptr;           // ptr  at input
88     void        *ret;           // ptr  at output
89     MppMemNode  *node;          // node for operation
90     const char  *caller;
91 } MppMemLog;
92 
93 class MppMemService
94 {
95 public:
96     // avoid any unwanted function
97     MppMemService();
98     ~MppMemService();
99 
100     void    add_node(const char *caller, void *ptr, size_t size);
101     /*
102      * try delete node will return index in nodes
103      * return 1 for need os_free call to real free
104      * return 0 for reserve memory for check
105      */
106     RK_S32  find_node(const char *caller, void *ptr, size_t *size, RK_S32 *idx);
107     /*
108      */
109     void    del_node(const char *caller, void *ptr, size_t *size);
110     void*   delay_del_node(const char *caller, void *ptr, size_t *size);
111     void    reset_node(const char *caller, void *ptr, void *ret, size_t size);
112 
113     void    chk_node(const char *caller, MppMemNode *node);
114     void    chk_mem(const char *caller, void *ptr, size_t size);
115     RK_S32  chk_poison(MppMemNode *node);
116 
117     void    add_log(MppMemOps ops, const char *caller, void *ptr, void *ret,
118                     size_t size_0, size_t size_1);
119 
120     void    dump(const char *caller);
total_now(void)121     RK_U32  total_now(void) { return m_total_size; }
total_max(void)122     RK_U32  total_max(void) { return m_total_max; }
123 
124     Mutex       lock;
125     RK_U32      debug;
126 
127 private:
128     // data for node record and delay free check
129     RK_S32      nodes_max;
130     RK_S32      nodes_idx;
131     RK_S32      nodes_cnt;
132     RK_S32      frees_max;
133     RK_S32      frees_idx;
134     RK_S32      frees_cnt;
135 
136     MppMemNode  *nodes;
137     MppMemNode  *frees;
138 
139     // data for log record
140     RK_U32      log_index;
141     RK_S32      log_max;
142     RK_S32      log_idx;
143     RK_S32      log_cnt;
144 
145     MppMemLog   *logs;
146     RK_U32      m_total_size;
147     RK_U32      m_total_max;
148 
149     MppMemService(const MppMemService &);
150     MppMemService &operator=(const MppMemService &);
151 };
152 
153 static MppMemService service;
154 
155 static const char *ops2str[MEM_OPS_BUTT] = {
156     "malloc",
157     "realloc",
158     "free",
159     "delayed",
160 };
161 
show_mem(RK_U32 * buf,RK_S32 size)162 static void show_mem(RK_U32 *buf, RK_S32 size)
163 {
164     mpp_err("dumping buf %p size %d start\n", buf, size);
165     while (size > 0) {
166         if (size >= 16) {
167             mpp_err("%08x %08x %08x %08x\n", buf[0], buf[1], buf[2], buf[3]);
168             buf += 4;
169             size -= 16;
170         } else if (size >= 12) {
171             mpp_err("%08x %08x %08x\n", buf[0], buf[1], buf[2]);
172             buf += 3;
173             size -= 12;
174         } else if (size >= 8) {
175             mpp_err("%08x %08x\n", buf[0], buf[1]);
176             buf += 2;
177             size -= 8;
178         } else if (size >= 4) {
179             mpp_err("%08x\n", buf[0]);
180             buf += 1;
181             size -= 4;
182         } else {
183             mpp_log("end with size %d\n", size);
184             break;
185         }
186     }
187     mpp_err("dumping buf %p size %d end\n", buf, size);
188 }
189 
set_mem_ext_room(void * p,size_t size)190 static void set_mem_ext_room(void *p, size_t size)
191 {
192     memset((RK_U8 *)p - MEM_ALIGN, MEM_HEAD_MASK, MEM_ALIGN);
193     memset((RK_U8 *)p + size,      MEM_TAIL_MASK, MEM_ALIGN);
194 }
195 
MppMemService()196 MppMemService::MppMemService()
197     : debug(0),
198       nodes_max(MEM_NODE_MAX),
199       nodes_idx(0),
200       nodes_cnt(0),
201       frees_max(MEM_FREE_MAX),
202       frees_idx(0),
203       frees_cnt(0),
204       nodes(NULL),
205       frees(NULL),
206       log_index(0),
207       log_max(MEM_LOG_MAX),
208       log_idx(0),
209       log_cnt(0),
210       logs(NULL),
211       m_total_size(0),
212       m_total_max(0)
213 {
214     mpp_env_get_u32("mpp_mem_debug", &debug, 0);
215 
216     // add more flag if debug enabled
217     if (debug)
218         debug |= MEM_DEBUG_EN;
219 
220     if (debug & MEM_DEBUG_EN) {
221         mpp_env_get_u32("mpp_mem_node_max", (RK_U32 *)&nodes_max, MEM_NODE_MAX);
222 
223         mpp_log_f("mpp_mem_debug enabled %x max node %d\n",
224                   debug, nodes_max);
225 
226         size_t size = nodes_max * sizeof(MppMemNode);
227         os_malloc((void **)&nodes, MEM_ALIGN, size);
228         mpp_assert(nodes);
229         memset(nodes, 0xff, size);
230         add_node(__FUNCTION__, nodes, size);
231 
232         size = frees_max * sizeof(MppMemNode);
233         os_malloc((void **)&frees, MEM_ALIGN, size);
234         mpp_assert(frees);
235         memset(frees, 0xff, size);
236         add_node(__FUNCTION__, frees, size);
237 
238         size = log_max * sizeof(MppMemLog);
239         os_malloc((void **)&logs, MEM_ALIGN, size);
240         mpp_assert(logs);
241         add_node(__FUNCTION__, logs, size);
242 
243         add_node(__FUNCTION__, this, sizeof(MppMemService));
244     }
245 }
246 
~MppMemService()247 MppMemService::~MppMemService()
248 {
249     if (debug & MEM_DEBUG_EN) {
250         AutoMutex auto_lock(&lock);
251 
252         RK_S32 i = 0;
253         MppMemNode *node = nodes;
254 
255         // delete self node first
256         size_t size = 0;
257 
258         del_node(__FUNCTION__, this,  &size);
259         del_node(__FUNCTION__, nodes, &size);
260         del_node(__FUNCTION__, frees, &size);
261         del_node(__FUNCTION__, logs,  &size);
262 
263         // then check leak memory
264         if (nodes_cnt) {
265             for (i = 0; i < nodes_max; i++, node++) {
266                 if (node->index >= 0) {
267                     mpp_log("found idx %8d mem %10p size %d leaked\n",
268                             node->index, node->ptr, node->size);
269                     nodes_cnt--;
270                     add_log(MEM_FREE, __FUNCTION__, node->ptr, NULL,
271                             node->size, 0);
272                 }
273             }
274 
275             mpp_assert(nodes_cnt == 0);
276         }
277 
278         // finally release all delay free memory
279         if (frees_cnt) {
280             node = frees;
281 
282             for (i = 0; i < frees_max; i++, node++) {
283                 if (node->index >= 0) {
284                     os_free((RK_U8 *)node->ptr - MEM_HEAD_ROOM(debug));
285                     node->index = ~node->index;
286                     frees_cnt--;
287                     add_log(MEM_FREE_DELAY, __FUNCTION__, node->ptr, NULL,
288                             node->size, 0);
289                 }
290             }
291 
292             mpp_assert(frees_cnt == 0);
293         }
294 
295         os_free(nodes);
296         os_free(frees);
297         os_free(logs);
298     }
299 }
300 
add_node(const char * caller,void * ptr,size_t size)301 void MppMemService::add_node(const char *caller, void *ptr, size_t size)
302 {
303     RK_S32 i = 0;
304 
305     if (debug & MEM_NODE_LOG)
306         mpp_log("mem cnt: %5d total %8d inc size %8d at %s\n",
307                 nodes_cnt, m_total_size, size, caller);
308 
309     if (nodes_cnt >= nodes_max) {
310         mpp_err("******************************************************\n");
311         mpp_err("* Reach max limit of mpp_mem counter %5d           *\n", nodes_max);
312         mpp_err("* Increase limit by setup env mpp_mem_node_max or    *\n");
313         mpp_err("* recompile mpp with larger macro MEM_NODE_MAX value *\n");
314         mpp_err("******************************************************\n");
315         mpp_abort();
316     }
317 
318     MppMemNode *node = nodes;
319     for (i = 0; i < nodes_max; i++, node++) {
320         if (node->index < 0) {
321             node->index = nodes_idx++;
322             node->size  = size;
323             node->ptr   = ptr;
324             node->caller = caller;
325 
326             // NOTE: reset node index on revert
327             if (nodes_idx < 0)
328                 nodes_idx = 0;
329 
330             nodes_cnt++;
331             m_total_size += size;
332             if (m_total_size > m_total_max)
333                 m_total_max = m_total_size;
334             break;
335         }
336     }
337 }
338 
find_node(const char * caller,void * ptr,size_t * size,RK_S32 * idx)339 RK_S32 MppMemService::find_node(const char *caller, void *ptr, size_t *size, RK_S32 *idx)
340 {
341     RK_S32 i = 0;
342     MppMemNode *node = nodes;
343 
344     MPP_MEM_ASSERT(nodes_cnt <= nodes_max);
345     for (i = 0; i < nodes_max; i++, node++) {
346         if (node->index >= 0 && node->ptr == ptr) {
347             *size = node->size;
348             *idx  = i;
349             return 1;
350         }
351     }
352 
353     mpp_err("%s can NOT found node with ptr %p\n", caller, ptr);
354     mpp_abort();
355     return 0;
356 }
357 
del_node(const char * caller,void * ptr,size_t * size)358 void MppMemService::del_node(const char *caller, void *ptr, size_t *size)
359 {
360     RK_S32 i = 0;
361     MppMemNode *node = nodes;
362 
363     MPP_MEM_ASSERT(nodes_cnt <= nodes_max);
364 
365     for (i = 0; i < nodes_max; i++, node++) {
366         if (node->index >= 0 && node->ptr == ptr) {
367             *size = node->size;
368             node->index = ~node->index;
369             nodes_cnt--;
370             m_total_size -= node->size;
371 
372             if (debug & MEM_NODE_LOG)
373                 mpp_log("mem cnt: %5d total %8d dec size %8d at %s\n",
374                         nodes_cnt, m_total_size, node->size, caller);
375             return ;
376         }
377     }
378 
379     mpp_err("%s fail to find node with ptr %p\n", caller, ptr);
380     mpp_abort();
381     return ;
382 }
383 
delay_del_node(const char * caller,void * ptr,size_t * size)384 void *MppMemService::delay_del_node(const char *caller, void *ptr, size_t *size)
385 {
386     RK_S32 i = 0;
387     MppMemNode *node = nodes;
388 
389     // clear output first
390     void *ret = NULL;
391     *size = 0;
392 
393     // find the node to save
394     MPP_MEM_ASSERT(nodes_cnt <= nodes_max);
395     for (i = 0; i < nodes_max; i++, node++) {
396         if (node->index >= 0 && node->ptr == ptr) {
397             chk_node(caller, node);
398             break;
399         }
400     }
401 
402     MPP_MEM_ASSERT(i < nodes_max);
403     if (debug & MEM_NODE_LOG)
404         mpp_log("mem cnt: %5d total %8d dec size %8d at %s\n",
405                 nodes_cnt, m_total_size, node->size, caller);
406 
407     MppMemNode *free_node = NULL;
408 
409     MPP_MEM_ASSERT(frees_cnt <= frees_max);
410 
411     if (frees_cnt) {
412         MppMemNode *tmp = frees;
413 
414         // NODE: check all data here
415         for (i = 0; i < frees_max; i++, tmp++) {
416             if (tmp->index >= 0) {
417                 chk_node(caller, tmp);
418                 chk_poison(tmp);
419             }
420         }
421     }
422 
423     if (frees_cnt >= frees_max) {
424         // free list full start del
425         RK_S32 frees_last = frees_idx - frees_cnt;
426         if (frees_last < 0)
427             frees_last += frees_max;
428 
429         free_node = &frees[frees_last];
430 
431         if (free_node->index >= 0) {
432             chk_node(caller, free_node);
433             chk_poison(free_node);
434             ret = free_node->ptr;
435             *size = free_node->size;
436             free_node->index = ~free_node->index;
437             frees_cnt--;
438         }
439     }
440 
441     MPP_MEM_ASSERT(frees_cnt <= frees_max);
442 
443     // free list is NOT full just store
444     free_node = &frees[frees_idx];
445     frees_idx++;
446     if (frees_idx >= frees_max)
447         frees_idx = 0;
448     if (frees_cnt < frees_max)
449         frees_cnt++;
450 
451     MPP_MEM_ASSERT(frees_cnt <= frees_max);
452 
453     memcpy(&frees[frees_idx], node, sizeof(*node));
454 
455     if ((debug & MEM_POISON) && (node->size < 1024))
456         memset(node->ptr, MEM_CHECK_MARK, node->size);
457 
458     node->index = ~node->index;
459     m_total_size -= node->size;
460     nodes_cnt--;
461 
462     return ret;
463 }
464 
chk_node(const char * caller,MppMemNode * node)465 void MppMemService::chk_node(const char *caller, MppMemNode *node)
466 {
467     if ((debug & MEM_EXT_ROOM) == 0)
468         return ;
469 
470     chk_mem(caller, node->ptr, node->size);
471 }
472 
chk_mem(const char * caller,void * ptr,size_t size)473 void MppMemService::chk_mem(const char *caller, void *ptr, size_t size)
474 {
475     if ((debug & MEM_EXT_ROOM) == 0)
476         return ;
477 
478     RK_S32 i = 0;
479     RK_U8 *p = (RK_U8 *)ptr - MEM_ALIGN;
480 
481     for (i = 0; i < MEM_ALIGN; i++) {
482         if (p[i] != MEM_HEAD_MASK) {
483             mpp_err("%s checking ptr %p head room found error!\n", caller, ptr);
484             dump(caller);
485             show_mem((RK_U32 *)p, MEM_ALIGN);
486             mpp_abort();
487         }
488     }
489 
490     p = (RK_U8 *)ptr + size;
491     for (i = 0; i < MEM_ALIGN; i++) {
492         if (p[i] != MEM_TAIL_MASK) {
493             mpp_err("%s checking ptr %p tail room found error!\n", caller, ptr);
494             dump(caller);
495             show_mem((RK_U32 *)p, MEM_ALIGN);
496             mpp_abort();
497         }
498     }
499 }
500 
chk_poison(MppMemNode * node)501 RK_S32 MppMemService::chk_poison(MppMemNode *node)
502 {
503     if ((debug & MEM_POISON) == 0)
504         return 0;
505 
506     // check oldest memory and free it
507     RK_U8 *node_ptr = (RK_U8 *)node->ptr;
508     RK_S32 size = node->size;
509     RK_S32 i = 0;
510     RK_S32 start = -1;
511     RK_S32 end = -1;
512 
513     if (size >= 1024)
514         return 0;
515 
516     for (; i < size; i++) {
517         if (node_ptr[i] != MEM_CHECK_MARK) {
518             if (start < 0) {
519                 start = i;
520             }
521             end = i + 1;
522         }
523     }
524 
525     if (start >= 0 || end >= 0) {
526         mpp_err_f("found memory %p size %d caller %s overwrite from %d to %d\n",
527                   node_ptr, size, node->caller, start, end);
528         dump(node->caller);
529     }
530 
531     return end - start;
532 }
533 
reset_node(const char * caller,void * ptr,void * ret,size_t size)534 void MppMemService::reset_node(const char *caller, void *ptr, void *ret, size_t size)
535 {
536     RK_S32 i = 0;
537     MppMemNode *node = nodes;
538 
539     if (debug & MEM_NODE_LOG)
540         mpp_log("mem cnt: %5d total %8d equ size %8d at %s\n",
541                 nodes_cnt, m_total_size, size, __FUNCTION__);
542 
543     MPP_MEM_ASSERT(nodes_cnt <= nodes_max);
544 
545     for (i = 0; i < nodes_max; i++, node++) {
546         if (node->index >= 0 && node->ptr == ptr) {
547             m_total_size += size;
548             m_total_size -= node->size;
549 
550             node->ptr   = ret;
551             node->size  = size;
552             node->caller = caller;
553 
554             if (debug & MEM_EXT_ROOM)
555                 set_mem_ext_room(ret, size);
556             break;
557         }
558     }
559 }
560 
add_log(MppMemOps ops,const char * caller,void * ptr,void * ret,size_t size_0,size_t size_1)561 void MppMemService::add_log(MppMemOps ops, const char *caller,
562                             void *ptr, void *ret, size_t size_0, size_t size_1)
563 {
564     MppMemLog *log = &logs[log_idx];
565 
566     if (service.debug & MEM_RUNTIME_LOG)
567         mpp_log("%-7s ptr %010p %010p size %8u %8u at %s\n",
568                 ops2str[ops], ptr, ret, size_0, size_1, caller);
569 
570     log->index  = log_index++;
571     log->ops    = ops;
572     log->size_0 = size_0;
573     log->size_1 = size_1;
574     log->ptr    = ptr;
575     log->ret    = ret;
576     log->node   = NULL;
577     log->caller = caller;
578 
579     log_idx++;
580     if (log_idx >= log_max)
581         log_idx = 0;
582 
583     if (log_cnt < log_max)
584         log_cnt++;
585 }
586 
dump(const char * caller)587 void MppMemService::dump(const char *caller)
588 {
589     RK_S32 i;
590     MppMemNode *node = nodes;
591 
592     mpp_log("mpp_mem enter status dumping from %s:\n", caller);
593 
594     mpp_log("mpp_mem node count %d:\n", nodes_cnt);
595     if (nodes_cnt) {
596         for (i = 0; i < nodes_max; i++, node++) {
597             if (node->index < 0)
598                 continue;
599 
600             mpp_log("mpp_memory index %d caller %-32s size %-8u ptr %p\n",
601                     node->index, node->caller, node->size, node->ptr);
602         }
603     }
604 
605     node = frees;
606     mpp_log("mpp_mem free count %d:\n", frees_cnt);
607     if (frees_cnt) {
608         for (i = 0; i < frees_max; i++, node++) {
609             if (node->index < 0)
610                 continue;
611 
612             mpp_log("mpp_freed  index %d caller %-32s size %-8u ptr %p\n",
613                     node->index, node->caller, node->size, node->ptr);
614         }
615     }
616 
617     RK_S32 start = log_idx - log_cnt;
618     RK_S32 tmp_cnt = log_cnt;
619 
620     if (start < 0)
621         start += log_max;
622 
623     mpp_log("mpp_mem enter log dumping:\n");
624 
625     while (tmp_cnt) {
626         MppMemLog *log = &logs[start];
627 
628         mpp_log("idx %-8d op: %-7s from %-32s ptr %10p %10p size %7d %7d\n",
629                 log->index, ops2str[log->ops], log->caller,
630                 log->ptr, log->ret, log->size_0, log->size_1);
631 
632         start++;
633         if (start >= log_max)
634             start = 0;
635 
636         tmp_cnt--;
637     }
638 }
639 
mpp_osal_malloc(const char * caller,size_t size)640 void *mpp_osal_malloc(const char *caller, size_t size)
641 {
642     RK_U32 debug = service.debug;
643     size_t size_align = MEM_ALIGNED(size);
644     size_t size_real = (debug & MEM_EXT_ROOM) ? (size_align + 2 * MEM_ALIGN) :
645                        (size_align);
646     void *ptr;
647 
648     os_malloc(&ptr, MEM_ALIGN, size_real);
649 
650     if (debug) {
651         AutoMutex auto_lock(&service.lock);
652         service.add_log(MEM_MALLOC, caller, NULL, ptr, size, size_real);
653 
654         if (ptr) {
655             if (debug & MEM_EXT_ROOM) {
656                 ptr = (RK_U8 *)ptr + MEM_ALIGN;
657                 set_mem_ext_room(ptr, size);
658             }
659 
660             service.add_node(caller, ptr, size);
661         }
662     }
663 
664     return ptr;
665 }
666 
mpp_osal_calloc(const char * caller,size_t size)667 void *mpp_osal_calloc(const char *caller, size_t size)
668 {
669     void *ptr = mpp_osal_malloc(caller, size);
670     if (ptr)
671         memset(ptr, 0, size);
672     return ptr;
673 }
674 
mpp_osal_realloc(const char * caller,void * ptr,size_t size)675 void *mpp_osal_realloc(const char *caller, void *ptr, size_t size)
676 {
677     RK_U32 debug = service.debug;
678     void *ret;
679 
680     if (NULL == ptr)
681         return mpp_osal_malloc(caller, size);
682 
683     if (0 == size) {
684         mpp_err("warning: realloc %p to zero size\n", ptr);
685         return NULL;
686     }
687 
688     size_t size_align = MEM_ALIGNED(size);
689     size_t size_real = (debug & MEM_EXT_ROOM) ? (size_align + 2 * MEM_ALIGN) :
690                        (size_align);
691     void *ptr_real = (RK_U8 *)ptr - MEM_HEAD_ROOM(debug);
692 
693     os_realloc(ptr_real, &ret, MEM_ALIGN, size_align);
694 
695     if (NULL == ret) {
696         // if realloc fail the original buffer will be kept the same.
697         mpp_err("mpp_realloc ptr %p to size %d failed\n", ptr, size);
698     } else {
699         AutoMutex auto_lock(&service.lock);
700 
701         // if realloc success reset the node and record
702         if (debug) {
703             void *ret_ptr = (debug & MEM_EXT_ROOM) ?
704                             ((RK_U8 *)ret + MEM_ALIGN) : (ret);
705 
706             service.reset_node(caller, ptr, ret_ptr, size);
707             service.add_log(MEM_REALLOC, caller, ptr, ret_ptr, size, size_real);
708             ret = ret_ptr;
709         }
710     }
711 
712     return ret;
713 }
714 
mpp_osal_free(const char * caller,void * ptr)715 void mpp_osal_free(const char *caller, void *ptr)
716 {
717     RK_U32 debug = service.debug;
718     if (NULL == ptr)
719         return;
720 
721     if (!debug) {
722         os_free(ptr);
723         return ;
724     }
725 
726     size_t size = 0;
727 
728     AutoMutex auto_lock(&service.lock);
729     if (debug & MEM_POISON) {
730         // NODE: keep this node and  delete delay node
731         void *ret = service.delay_del_node(caller, ptr, &size);
732         if (ret)
733             os_free((RK_U8 *)ret - MEM_ALIGN);
734 
735         service.add_log(MEM_FREE_DELAY, caller, ptr, ret, size, 0);
736     } else {
737         void *ptr_real = (RK_U8 *)ptr - MEM_HEAD_ROOM(debug);
738         // NODE: delete node and return size here
739         service.del_node(caller, ptr, &size);
740         service.chk_mem(caller, ptr, size);
741         os_free(ptr_real);
742         service.add_log(MEM_FREE, caller, ptr, ptr_real, size, 0);
743     }
744 }
745 
746 /* dump memory status */
mpp_show_mem_status()747 void mpp_show_mem_status()
748 {
749     AutoMutex auto_lock(&service.lock);
750     if (service.debug & MEM_DEBUG_EN)
751         service.dump(__FUNCTION__);
752 }
753 
mpp_mem_total_now()754 RK_U32 mpp_mem_total_now()
755 {
756     AutoMutex auto_lock(&service.lock);
757     return service.total_now();
758 }
759 
mpp_mem_total_max()760 RK_U32 mpp_mem_total_max()
761 {
762     AutoMutex auto_lock(&service.lock);
763     return service.total_max();
764 }
765