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