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