1 #include "stdlib.h"
2 #include "stdint.h"
3 #include "string.h"
4 #include "aos_system.h"
5 #include "amp_memmgt.h"
6
7 typedef struct amp_memmgt_rec_stru_tag {
8 void *ptr;
9 unsigned int size;
10 unsigned int lr;
11 unsigned int seq;
12 struct amp_memmgt_rec_stru_tag *next;
13 struct amp_memmgt_rec_stru_tag *prev;
14 } amp_memmgt_rec_stru;
15
16 static amp_memmgt_rec_stru *g_mem_rec_head = NULL;
17 static amp_memmgt_rec_stru *g_mem_rec_tail = NULL;
18 static amp_memmgt_config_t g_mem_config;
19
20 static unsigned int g_mem_rec_num = 0;
21 static unsigned int g_mem_max[MEMMGT_TOTAL_PT_NUM] = {0};
22 static unsigned int g_mem_total[MEMMGT_TOTAL_PT_NUM] = {0};
23 static aos_mutex_t g_mem_rec_lock = NULL;
24
25 #ifdef MEMMGT_MEM_DBG_STATIC
add_node(void * ptr,unsigned int size,unsigned int lr,int ptno)26 static void add_node(void *ptr, unsigned int size, unsigned int lr, int ptno)
27 {
28 amp_memmgt_rec_stru * node = NULL;
29
30 node = g_mem_config.malloc_fn(sizeof(amp_memmgt_rec_stru));
31 if(NULL == node) {
32 return;
33 }
34 memset(node, 0, sizeof(amp_memmgt_rec_stru));
35
36 aos_mutex_lock(&g_mem_rec_lock, AOS_WAIT_FOREVER);
37 g_mem_rec_tail->next = node;
38 node->prev = g_mem_rec_tail;
39 g_mem_rec_tail = node;
40
41 node->ptr = ptr;
42 node->size = size;
43 node->seq = g_mem_rec_num;
44 node->lr = lr;
45
46 *(unsigned int *)ptr = (unsigned int)node;
47
48 g_mem_rec_num ++;
49 aos_mutex_unlock(&g_mem_rec_lock);
50 }
51
delete_node(amp_memmgt_rec_stru * node)52 static void delete_node(amp_memmgt_rec_stru *node)
53 {
54 if(node == NULL) {
55 return;
56 }
57 aos_mutex_lock(&g_mem_rec_lock, AOS_WAIT_FOREVER);
58 if(node == g_mem_rec_tail) {
59 g_mem_rec_tail = node->prev;
60 }
61 if(NULL != node->prev) {
62 node->prev->next = node->next;
63 }
64
65 if(NULL != node->next) {
66 node->next->prev = node->prev;
67 }
68
69 if (g_mem_config.free_fn) {
70 g_mem_config.free_fn(node);
71 }
72
73 aos_mutex_unlock(&g_mem_rec_lock);
74 }
75 #endif
76
77
amp_memmgt_init(amp_memmgt_config_t * config)78 int amp_memmgt_init(amp_memmgt_config_t *config)
79 {
80 if ((config->malloc_fn == NULL) || (config->free_fn == NULL)) {
81 return -1;
82 }
83
84 memcpy(&g_mem_config, config, sizeof(amp_memmgt_config_t));
85
86 #ifdef MEMMGT_MEM_DBG_STATIC
87 if(NULL == g_mem_rec_head) {
88 g_mem_rec_head = config->malloc_fn(sizeof(amp_memmgt_rec_stru));
89 memset(g_mem_rec_head, 0, sizeof(amp_memmgt_rec_stru));
90 aos_mutex_new(&g_mem_rec_lock);
91 g_mem_rec_tail = g_mem_rec_head;
92 }
93 #endif
94
95 return 0;
96 }
97
amp_memmgt_mem_show_rec()98 void amp_memmgt_mem_show_rec()
99 {
100 #ifdef MEMMGT_MEM_DBG_STATIC
101 aos_mutex_lock(&g_mem_rec_lock, AOS_WAIT_FOREVER);
102 amp_memmgt_rec_stru *rec_node = g_mem_rec_head;
103 if(rec_node != NULL) {
104 aos_printf("seq addr size LR\r\n");
105
106 while(rec_node) {
107 if(rec_node->ptr) {
108 aos_printf("%4u ", rec_node->seq);
109 aos_printf("0x%x ", rec_node->ptr);
110 aos_printf("0x%x ", rec_node->size);
111 aos_printf("0x%x \n", rec_node->lr);
112 }
113 rec_node = rec_node->next;
114 }
115 }
116 aos_mutex_unlock(&g_mem_rec_lock);
117 #endif
118
119 for (int i = 0; i < g_mem_config.pt_num; i++) {
120 aos_printf("\r\nPT[%d]: max mem %u, now mem %u \n", i, g_mem_max[i], g_mem_total[i]);
121 }
122 }
123
amp_memmgt_malloc(unsigned int size,unsigned int lr,int ptno)124 void *amp_memmgt_malloc(unsigned int size, unsigned int lr, int ptno)
125 {
126 void *ptr = NULL;
127
128 unsigned int alloc_size = size + MEMMGT_OFFSET;
129 unsigned int once_size = alloc_size;
130
131 if(NULL == g_mem_config.malloc_fn) {
132 return NULL;
133 }
134
135 #ifdef MEMMGT_MEM_SIZE_CHECK
136 #ifdef MEMMGT_MEM_DBG_STATIC
137 once_size += sizeof(amp_memmgt_rec_stru);
138 #endif
139 if((g_mem_config.mem_limit[ptno] != 0) && (g_mem_total[ptno] + once_size > g_mem_config.mem_limit[ptno])) {
140 aos_printf("[amp_memory] memory leak, pt %d, size %d, lr 0x%x, total size 0x%x, limit 0x%x\n", ptno, size, lr, g_mem_total[ptno], g_mem_config.mem_limit[ptno]);
141 return NULL;
142 }
143 #endif
144 ptr = g_mem_config.malloc_fn(alloc_size);
145 if(NULL == ptr) {
146 aos_printf("[amp_memory%s] lr 0x%x memory alloc failed, system will stop !!!\n", __TIME__, lr);
147 amp_memmgt_mem_show_rec();
148 while(1) {
149 aos_msleep(1000);
150 }
151 return NULL;
152 }
153
154 g_mem_total[ptno] += alloc_size;
155
156 #ifdef MEMMGT_MEM_DBG_STATIC
157 add_node(ptr, alloc_size, lr, ptno);
158 g_mem_total[ptno] += sizeof(amp_memmgt_rec_stru);
159 #else
160 *(unsigned int *)ptr = alloc_size;
161 #endif
162
163 if(g_mem_total[ptno] > g_mem_max[ptno]) {
164 g_mem_max[ptno] = g_mem_total[ptno];
165 }
166 #ifdef MEMMGT_MEM_TRACE
167 if(((1<<ptno) & g_mem_config.trace_pt) != 0) {
168 aos_printf("[amp_memory:%s] lr 0x%x alloc %p, size %d\n", __TIME__, lr, (void *)((unsigned int)ptr + MEMMGT_OFFSET), size);
169 aos_printf(" now total malloc %u, max malloc %u\n", g_mem_total[ptno], g_mem_max[ptno]);
170 }
171 #endif
172 return (void *)((unsigned int)ptr + MEMMGT_OFFSET);
173 }
174
amp_memmgt_realloc(void * ptr,unsigned int size,unsigned int lr,int ptno)175 void *amp_memmgt_realloc(void *ptr, unsigned int size, unsigned int lr, int ptno)
176 {
177 void *ptr_new = NULL;
178 void *origin_ptr = NULL;
179
180 unsigned int alloc_size = size + MEMMGT_OFFSET;
181 unsigned int old_size = size;
182 unsigned int once_size = alloc_size;
183
184 if (size == 0) {
185 amp_memmgt_free(ptr, lr, ptno);
186 return NULL;
187 }
188
189 if(NULL == g_mem_config.realloc_fn) {
190 return NULL;
191 }
192
193 #ifdef MEMMGT_MEM_TRACE
194 if(((1<<ptno) & g_mem_config.trace_pt) != 0) {
195 aos_printf("[amp_memory:%s] lr 0x%x realloc %p, size %d\n", __TIME__, lr, ptr, size);
196 }
197 #endif
198
199 #ifdef MEMMGT_MEM_DBG_STATIC
200 amp_memmgt_rec_stru *node = *(unsigned int *)((uint32_t)ptr - MEMMGT_OFFSET);
201 amp_memmgt_rec_stru tmp_node;
202 memcpy(&tmp_node, node, sizeof(amp_memmgt_rec_stru));
203
204 old_size = node->size;
205 #else
206 old_size = *(unsigned int *)((unsigned int)ptr - 4);
207 #endif
208 origin_ptr = (void *)((unsigned int)ptr - 4);
209
210 #ifdef MEMMGT_MEM_SIZE_CHECK
211 #ifdef MEMMGT_MEM_DBG_STATIC
212 once_size += sizeof(amp_memmgt_rec_stru);
213 #endif
214 once_size -= old_size;
215 if((g_mem_config.mem_limit[ptno] != 0) && (g_mem_total[ptno] + once_size > g_mem_config.mem_limit[ptno])) {
216 aos_printf("[amp_memory:%s] memory leak, pt %d, size %d, lr 0x%x, total size 0x%x, limit 0x%x\n", __TIME__,
217 ptno, size, lr, g_mem_total[ptno], g_mem_config.mem_limit[ptno]);
218 return NULL;
219 }
220 #endif
221
222 ptr_new = g_mem_config.realloc_fn(origin_ptr, alloc_size);
223 if(NULL == ptr_new) {
224 aos_printf("[amp_memory:%s] lr 0x%x memory realloc failed, system will stop !!!\n", __TIME__, lr);
225 amp_memmgt_mem_show_rec();
226 while(1) {
227 aos_msleep(1000);
228 }
229 return NULL;
230 }
231
232 g_mem_total[ptno] += alloc_size - old_size;
233 if(g_mem_total[ptno] > g_mem_max[ptno]) {
234 g_mem_max[ptno] = g_mem_total[ptno];
235 }
236
237 #ifdef MEMMGT_MEM_DBG_STATIC
238 if(origin_ptr != ptr_new) {
239 delete_node(node);
240 add_node(ptr_new, alloc_size, lr, ptno);
241 } else {
242 node->size = size;
243 }
244 #else
245 *(unsigned int *)ptr_new = alloc_size;
246 #endif
247
248 #ifdef MEMMGT_MEM_TRACE
249 if(((1<<ptno) & g_mem_config.trace_pt) != 0) {
250 aos_printf("[amp_memory:%s] lr 0x%x realloc result %p\n", __TIME__, lr, (void *)((unsigned int)ptr_new + MEMMGT_OFFSET));
251 aos_printf(" now total malloc %u, max malloc %u\n", g_mem_total[ptno], g_mem_max[ptno]);
252 }
253 #endif
254
255 return (void *)((unsigned int)ptr_new + MEMMGT_OFFSET);
256 }
257
amp_memmgt_free(void * ptr,unsigned int lr,int ptno)258 void amp_memmgt_free(void *ptr, unsigned int lr, int ptno)
259 {
260 void *origin_ptr = (void *)((uint32_t)ptr - MEMMGT_OFFSET);
261 unsigned int free_size = 0;
262
263 if (ptr == NULL) {
264 return;
265 }
266
267 #ifdef MEMMGT_MEM_DBG_STATIC
268 amp_memmgt_rec_stru *node = NULL;
269 node = (amp_memmgt_rec_stru *)(*(unsigned int *)origin_ptr);
270 free_size = node->size;
271 #else
272 free_size = *(unsigned int *)((unsigned int)origin_ptr);
273 #endif
274 g_mem_total[ptno] -= free_size;
275
276 #ifdef MEMMGT_MEM_DBG_STATIC
277 delete_node(node);
278 #endif
279 g_mem_config.free_fn(origin_ptr);
280
281 #ifdef MEMMGT_MEM_TRACE
282 if(((1<<ptno) & g_mem_config.trace_pt) != 0) {
283 aos_printf("[amp_memory:%s] lr 0x%x free %p\n", __TIME__, lr, ptr);
284 aos_printf(" now total malloc %u, max malloc %u\n", g_mem_total[ptno], g_mem_max[ptno]);
285 }
286 #endif
287 }
288
amp_malloc_usable_size(void * ptr)289 unsigned int amp_malloc_usable_size(void *ptr)
290 {
291 void *origin_ptr = (void *)((uint32_t)ptr - MEMMGT_OFFSET);
292 uint32_t size = 0;
293
294 if (ptr == NULL) {
295 return 0;
296 }
297
298 #ifdef MEMMGT_MEM_DBG_STATIC
299 amp_memmgt_rec_stru *node = NULL;
300 node = (amp_memmgt_rec_stru *)(*(unsigned int *)origin_ptr);
301 if (node != NULL) {
302 size = node->size;
303 }
304 #else
305 size = *(unsigned int *)((unsigned int)origin_ptr);
306 #endif
307 return size - MEMMGT_OFFSET;
308 }
309