|
1 /* |
|
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
|
3 * |
|
4 * Use of this source code is governed by a BSD-style license |
|
5 * that can be found in the LICENSE file in the root of the source |
|
6 * tree. An additional intellectual property rights grant can be found |
|
7 * in the file PATENTS. All contributing project authors may |
|
8 * be found in the AUTHORS file in the root of the source tree. |
|
9 */ |
|
10 |
|
11 |
|
12 #define __VPX_MEM_C__ |
|
13 |
|
14 #include "vpx_mem.h" |
|
15 #include <stdio.h> |
|
16 #include <stdlib.h> |
|
17 #include <string.h> |
|
18 #include "include/vpx_mem_intrnl.h" |
|
19 |
|
20 #if CONFIG_MEM_TRACKER |
|
21 #ifndef VPX_NO_GLOBALS |
|
22 static unsigned long g_alloc_count = 0; |
|
23 #else |
|
24 #include "vpx_global_handling.h" |
|
25 #define g_alloc_count vpxglobalm(vpxmem,g_alloc_count) |
|
26 #endif |
|
27 #endif |
|
28 |
|
29 #if CONFIG_MEM_MANAGER |
|
30 # include "heapmm.h" |
|
31 # include "hmm_intrnl.h" |
|
32 |
|
33 # define SHIFT_HMM_ADDR_ALIGN_UNIT 5 |
|
34 # define TOTAL_MEMORY_TO_ALLOCATE 20971520 /* 20 * 1024 * 1024 */ |
|
35 |
|
36 # define MM_DYNAMIC_MEMORY 1 |
|
37 # if MM_DYNAMIC_MEMORY |
|
38 static unsigned char *g_p_mng_memory_raw = NULL; |
|
39 static unsigned char *g_p_mng_memory = NULL; |
|
40 # else |
|
41 static unsigned char g_p_mng_memory[TOTAL_MEMORY_TO_ALLOCATE]; |
|
42 # endif |
|
43 |
|
44 static size_t g_mm_memory_size = TOTAL_MEMORY_TO_ALLOCATE; |
|
45 |
|
46 static hmm_descriptor hmm_d; |
|
47 static int g_mng_memory_allocated = 0; |
|
48 |
|
49 static int vpx_mm_create_heap_memory(); |
|
50 static void *vpx_mm_realloc(void *memblk, size_t size); |
|
51 #endif /*CONFIG_MEM_MANAGER*/ |
|
52 |
|
53 #if USE_GLOBAL_FUNCTION_POINTERS |
|
54 struct GLOBAL_FUNC_POINTERS { |
|
55 g_malloc_func g_malloc; |
|
56 g_calloc_func g_calloc; |
|
57 g_realloc_func g_realloc; |
|
58 g_free_func g_free; |
|
59 g_memcpy_func g_memcpy; |
|
60 g_memset_func g_memset; |
|
61 g_memmove_func g_memmove; |
|
62 } *g_func = NULL; |
|
63 |
|
64 # define VPX_MALLOC_L g_func->g_malloc |
|
65 # define VPX_REALLOC_L g_func->g_realloc |
|
66 # define VPX_FREE_L g_func->g_free |
|
67 # define VPX_MEMCPY_L g_func->g_memcpy |
|
68 # define VPX_MEMSET_L g_func->g_memset |
|
69 # define VPX_MEMMOVE_L g_func->g_memmove |
|
70 #else |
|
71 # define VPX_MALLOC_L malloc |
|
72 # define VPX_REALLOC_L realloc |
|
73 # define VPX_FREE_L free |
|
74 # define VPX_MEMCPY_L memcpy |
|
75 # define VPX_MEMSET_L memset |
|
76 # define VPX_MEMMOVE_L memmove |
|
77 #endif /* USE_GLOBAL_FUNCTION_POINTERS */ |
|
78 |
|
79 unsigned int vpx_mem_get_version() { |
|
80 unsigned int ver = ((unsigned int)(unsigned char)VPX_MEM_VERSION_CHIEF << 24 | |
|
81 (unsigned int)(unsigned char)VPX_MEM_VERSION_MAJOR << 16 | |
|
82 (unsigned int)(unsigned char)VPX_MEM_VERSION_MINOR << 8 | |
|
83 (unsigned int)(unsigned char)VPX_MEM_VERSION_PATCH); |
|
84 return ver; |
|
85 } |
|
86 |
|
87 int vpx_mem_set_heap_size(size_t size) { |
|
88 int ret = -1; |
|
89 |
|
90 #if CONFIG_MEM_MANAGER |
|
91 #if MM_DYNAMIC_MEMORY |
|
92 |
|
93 if (!g_mng_memory_allocated && size) { |
|
94 g_mm_memory_size = size; |
|
95 ret = 0; |
|
96 } else |
|
97 ret = -3; |
|
98 |
|
99 #else |
|
100 ret = -2; |
|
101 #endif |
|
102 #else |
|
103 (void)size; |
|
104 #endif |
|
105 |
|
106 return ret; |
|
107 } |
|
108 |
|
109 void *vpx_memalign(size_t align, size_t size) { |
|
110 void *addr, |
|
111 * x = NULL; |
|
112 |
|
113 #if CONFIG_MEM_MANAGER |
|
114 int number_aau; |
|
115 |
|
116 if (vpx_mm_create_heap_memory() < 0) { |
|
117 _P(printf("[vpx][mm] ERROR vpx_memalign() Couldn't create memory for Heap.\n");) |
|
118 } |
|
119 |
|
120 number_aau = ((size + align - 1 + ADDRESS_STORAGE_SIZE) >> |
|
121 SHIFT_HMM_ADDR_ALIGN_UNIT) + 1; |
|
122 |
|
123 addr = hmm_alloc(&hmm_d, number_aau); |
|
124 #else |
|
125 addr = VPX_MALLOC_L(size + align - 1 + ADDRESS_STORAGE_SIZE); |
|
126 #endif /*CONFIG_MEM_MANAGER*/ |
|
127 |
|
128 if (addr) { |
|
129 x = align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, (int)align); |
|
130 /* save the actual malloc address */ |
|
131 ((size_t *)x)[-1] = (size_t)addr; |
|
132 } |
|
133 |
|
134 return x; |
|
135 } |
|
136 |
|
137 void *vpx_malloc(size_t size) { |
|
138 return vpx_memalign(DEFAULT_ALIGNMENT, size); |
|
139 } |
|
140 |
|
141 void *vpx_calloc(size_t num, size_t size) { |
|
142 void *x; |
|
143 |
|
144 x = vpx_memalign(DEFAULT_ALIGNMENT, num * size); |
|
145 |
|
146 if (x) |
|
147 VPX_MEMSET_L(x, 0, num * size); |
|
148 |
|
149 return x; |
|
150 } |
|
151 |
|
152 void *vpx_realloc(void *memblk, size_t size) { |
|
153 void *addr, |
|
154 * new_addr = NULL; |
|
155 int align = DEFAULT_ALIGNMENT; |
|
156 |
|
157 /* |
|
158 The realloc() function changes the size of the object pointed to by |
|
159 ptr to the size specified by size, and returns a pointer to the |
|
160 possibly moved block. The contents are unchanged up to the lesser |
|
161 of the new and old sizes. If ptr is null, realloc() behaves like |
|
162 malloc() for the specified size. If size is zero (0) and ptr is |
|
163 not a null pointer, the object pointed to is freed. |
|
164 */ |
|
165 if (!memblk) |
|
166 new_addr = vpx_malloc(size); |
|
167 else if (!size) |
|
168 vpx_free(memblk); |
|
169 else { |
|
170 addr = (void *)(((size_t *)memblk)[-1]); |
|
171 memblk = NULL; |
|
172 |
|
173 #if CONFIG_MEM_MANAGER |
|
174 new_addr = vpx_mm_realloc(addr, size + align + ADDRESS_STORAGE_SIZE); |
|
175 #else |
|
176 new_addr = VPX_REALLOC_L(addr, size + align + ADDRESS_STORAGE_SIZE); |
|
177 #endif |
|
178 |
|
179 if (new_addr) { |
|
180 addr = new_addr; |
|
181 new_addr = (void *)(((size_t) |
|
182 ((unsigned char *)new_addr + ADDRESS_STORAGE_SIZE) + (align - 1)) & |
|
183 (size_t) - align); |
|
184 /* save the actual malloc address */ |
|
185 ((size_t *)new_addr)[-1] = (size_t)addr; |
|
186 } |
|
187 } |
|
188 |
|
189 return new_addr; |
|
190 } |
|
191 |
|
192 void vpx_free(void *memblk) { |
|
193 if (memblk) { |
|
194 void *addr = (void *)(((size_t *)memblk)[-1]); |
|
195 #if CONFIG_MEM_MANAGER |
|
196 hmm_free(&hmm_d, addr); |
|
197 #else |
|
198 VPX_FREE_L(addr); |
|
199 #endif |
|
200 } |
|
201 } |
|
202 |
|
203 #if CONFIG_MEM_TRACKER |
|
204 void *xvpx_memalign(size_t align, size_t size, char *file, int line) { |
|
205 #if TRY_BOUNDS_CHECK |
|
206 unsigned char *x_bounds; |
|
207 #endif |
|
208 |
|
209 void *x; |
|
210 |
|
211 if (g_alloc_count == 0) { |
|
212 #if TRY_BOUNDS_CHECK |
|
213 int i_rv = vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE); |
|
214 #else |
|
215 int i_rv = vpx_memory_tracker_init(0, 0); |
|
216 #endif |
|
217 |
|
218 if (i_rv < 0) { |
|
219 _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");) |
|
220 } |
|
221 } |
|
222 |
|
223 #if TRY_BOUNDS_CHECK |
|
224 { |
|
225 int i; |
|
226 unsigned int tempme = BOUNDS_CHECK_VALUE; |
|
227 |
|
228 x_bounds = vpx_memalign(align, size + (BOUNDS_CHECK_PAD_SIZE * 2)); |
|
229 |
|
230 if (x_bounds) { |
|
231 /*we're aligning the address twice here but to keep things |
|
232 consistent we want to have the padding come before the stored |
|
233 address so no matter what free function gets called we will |
|
234 attempt to free the correct address*/ |
|
235 x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]); |
|
236 x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE, |
|
237 (int)align); |
|
238 /* save the actual malloc address */ |
|
239 ((size_t *)x)[-1] = (size_t)x_bounds; |
|
240 |
|
241 for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int)) { |
|
242 VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int)); |
|
243 VPX_MEMCPY_L((unsigned char *)x + size + i, |
|
244 &tempme, sizeof(unsigned int)); |
|
245 } |
|
246 } else |
|
247 x = NULL; |
|
248 } |
|
249 #else |
|
250 x = vpx_memalign(align, size); |
|
251 #endif /*TRY_BOUNDS_CHECK*/ |
|
252 |
|
253 g_alloc_count++; |
|
254 |
|
255 vpx_memory_tracker_add((size_t)x, (unsigned int)size, file, line, 1); |
|
256 |
|
257 return x; |
|
258 } |
|
259 |
|
260 void *xvpx_malloc(size_t size, char *file, int line) { |
|
261 return xvpx_memalign(DEFAULT_ALIGNMENT, size, file, line); |
|
262 } |
|
263 |
|
264 void *xvpx_calloc(size_t num, size_t size, char *file, int line) { |
|
265 void *x = xvpx_memalign(DEFAULT_ALIGNMENT, num * size, file, line); |
|
266 |
|
267 if (x) |
|
268 VPX_MEMSET_L(x, 0, num * size); |
|
269 |
|
270 return x; |
|
271 } |
|
272 |
|
273 void *xvpx_realloc(void *memblk, size_t size, char *file, int line) { |
|
274 struct mem_block *p = NULL; |
|
275 int orig_size = 0, |
|
276 orig_line = 0; |
|
277 char *orig_file = NULL; |
|
278 |
|
279 #if TRY_BOUNDS_CHECK |
|
280 unsigned char *x_bounds = memblk ? |
|
281 (unsigned char *)(((size_t *)memblk)[-1]) : |
|
282 NULL; |
|
283 #endif |
|
284 |
|
285 void *x; |
|
286 |
|
287 if (g_alloc_count == 0) { |
|
288 #if TRY_BOUNDS_CHECK |
|
289 |
|
290 if (!vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE)) |
|
291 #else |
|
292 if (!vpx_memory_tracker_init(0, 0)) |
|
293 #endif |
|
294 { |
|
295 _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");) |
|
296 } |
|
297 } |
|
298 |
|
299 if ((p = vpx_memory_tracker_find((size_t)memblk))) { |
|
300 orig_size = p->size; |
|
301 orig_file = p->file; |
|
302 orig_line = p->line; |
|
303 } |
|
304 |
|
305 #if TRY_BOUNDS_CHECK_ON_FREE |
|
306 vpx_memory_tracker_check_integrity(file, line); |
|
307 #endif |
|
308 |
|
309 /* have to do this regardless of success, because |
|
310 * the memory that does get realloc'd may change |
|
311 * the bounds values of this block |
|
312 */ |
|
313 vpx_memory_tracker_remove((size_t)memblk); |
|
314 |
|
315 #if TRY_BOUNDS_CHECK |
|
316 { |
|
317 int i; |
|
318 unsigned int tempme = BOUNDS_CHECK_VALUE; |
|
319 |
|
320 x_bounds = vpx_realloc(memblk, size + (BOUNDS_CHECK_PAD_SIZE * 2)); |
|
321 |
|
322 if (x_bounds) { |
|
323 x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]); |
|
324 x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE, |
|
325 (int)DEFAULT_ALIGNMENT); |
|
326 /* save the actual malloc address */ |
|
327 ((size_t *)x)[-1] = (size_t)x_bounds; |
|
328 |
|
329 for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int)) { |
|
330 VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int)); |
|
331 VPX_MEMCPY_L((unsigned char *)x + size + i, |
|
332 &tempme, sizeof(unsigned int)); |
|
333 } |
|
334 } else |
|
335 x = NULL; |
|
336 } |
|
337 #else |
|
338 x = vpx_realloc(memblk, size); |
|
339 #endif /*TRY_BOUNDS_CHECK*/ |
|
340 |
|
341 if (!memblk) ++g_alloc_count; |
|
342 |
|
343 if (x) |
|
344 vpx_memory_tracker_add((size_t)x, (unsigned int)size, file, line, 1); |
|
345 else |
|
346 vpx_memory_tracker_add((size_t)memblk, orig_size, orig_file, orig_line, 1); |
|
347 |
|
348 return x; |
|
349 } |
|
350 |
|
351 void xvpx_free(void *p_address, char *file, int line) { |
|
352 #if TRY_BOUNDS_CHECK |
|
353 unsigned char *p_bounds_address = (unsigned char *)p_address; |
|
354 /*p_bounds_address -= BOUNDS_CHECK_PAD_SIZE;*/ |
|
355 #endif |
|
356 |
|
357 #if !TRY_BOUNDS_CHECK_ON_FREE |
|
358 (void)file; |
|
359 (void)line; |
|
360 #endif |
|
361 |
|
362 if (p_address) { |
|
363 #if TRY_BOUNDS_CHECK_ON_FREE |
|
364 vpx_memory_tracker_check_integrity(file, line); |
|
365 #endif |
|
366 |
|
367 /* if the addr isn't found in the list, assume it was allocated via |
|
368 * vpx_ calls not xvpx_, therefore it does not contain any padding |
|
369 */ |
|
370 if (vpx_memory_tracker_remove((size_t)p_address) == -2) { |
|
371 p_bounds_address = p_address; |
|
372 _P(fprintf(stderr, "[vpx_mem][xvpx_free] addr: %p not found in" |
|
373 " list; freed from file:%s" |
|
374 " line:%d\n", p_address, file, line)); |
|
375 } else |
|
376 --g_alloc_count; |
|
377 |
|
378 #if TRY_BOUNDS_CHECK |
|
379 vpx_free(p_bounds_address); |
|
380 #else |
|
381 vpx_free(p_address); |
|
382 #endif |
|
383 |
|
384 if (!g_alloc_count) |
|
385 vpx_memory_tracker_destroy(); |
|
386 } |
|
387 } |
|
388 |
|
389 #endif /*CONFIG_MEM_TRACKER*/ |
|
390 |
|
391 #if CONFIG_MEM_CHECKS |
|
392 #if defined(VXWORKS) |
|
393 #include <task_lib.h> /*for task_delay()*/ |
|
394 /* This function is only used to get a stack trace of the player |
|
395 object so we can se where we are having a problem. */ |
|
396 static int get_my_tt(int task) { |
|
397 tt(task); |
|
398 |
|
399 return 0; |
|
400 } |
|
401 |
|
402 static void vx_sleep(int msec) { |
|
403 int ticks_to_sleep = 0; |
|
404 |
|
405 if (msec) { |
|
406 int msec_per_tick = 1000 / sys_clk_rate_get(); |
|
407 |
|
408 if (msec < msec_per_tick) |
|
409 ticks_to_sleep++; |
|
410 else |
|
411 ticks_to_sleep = msec / msec_per_tick; |
|
412 } |
|
413 |
|
414 task_delay(ticks_to_sleep); |
|
415 } |
|
416 #endif |
|
417 #endif |
|
418 |
|
419 void *vpx_memcpy(void *dest, const void *source, size_t length) { |
|
420 #if CONFIG_MEM_CHECKS |
|
421 |
|
422 if (((int)dest < 0x4000) || ((int)source < 0x4000)) { |
|
423 _P(printf("WARNING: vpx_memcpy dest:0x%x source:0x%x len:%d\n", (int)dest, (int)source, length);) |
|
424 |
|
425 #if defined(VXWORKS) |
|
426 sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0); |
|
427 |
|
428 vx_sleep(10000); |
|
429 #endif |
|
430 } |
|
431 |
|
432 #endif |
|
433 |
|
434 return VPX_MEMCPY_L(dest, source, length); |
|
435 } |
|
436 |
|
437 void *vpx_memset(void *dest, int val, size_t length) { |
|
438 #if CONFIG_MEM_CHECKS |
|
439 |
|
440 if ((int)dest < 0x4000) { |
|
441 _P(printf("WARNING: vpx_memset dest:0x%x val:%d len:%d\n", (int)dest, val, length);) |
|
442 |
|
443 #if defined(VXWORKS) |
|
444 sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0); |
|
445 |
|
446 vx_sleep(10000); |
|
447 #endif |
|
448 } |
|
449 |
|
450 #endif |
|
451 |
|
452 return VPX_MEMSET_L(dest, val, length); |
|
453 } |
|
454 |
|
455 void *vpx_memmove(void *dest, const void *src, size_t count) { |
|
456 #if CONFIG_MEM_CHECKS |
|
457 |
|
458 if (((int)dest < 0x4000) || ((int)src < 0x4000)) { |
|
459 _P(printf("WARNING: vpx_memmove dest:0x%x src:0x%x count:%d\n", (int)dest, (int)src, count);) |
|
460 |
|
461 #if defined(VXWORKS) |
|
462 sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0); |
|
463 |
|
464 vx_sleep(10000); |
|
465 #endif |
|
466 } |
|
467 |
|
468 #endif |
|
469 |
|
470 return VPX_MEMMOVE_L(dest, src, count); |
|
471 } |
|
472 |
|
473 #if CONFIG_MEM_MANAGER |
|
474 |
|
475 static int vpx_mm_create_heap_memory() { |
|
476 int i_rv = 0; |
|
477 |
|
478 if (!g_mng_memory_allocated) { |
|
479 #if MM_DYNAMIC_MEMORY |
|
480 g_p_mng_memory_raw = |
|
481 (unsigned char *)malloc(g_mm_memory_size + HMM_ADDR_ALIGN_UNIT); |
|
482 |
|
483 if (g_p_mng_memory_raw) { |
|
484 g_p_mng_memory = (unsigned char *)((((unsigned int)g_p_mng_memory_raw) + |
|
485 HMM_ADDR_ALIGN_UNIT - 1) & |
|
486 -(int)HMM_ADDR_ALIGN_UNIT); |
|
487 |
|
488 _P(printf("[vpx][mm] total memory size:%d g_p_mng_memory_raw:0x%x g_p_mng_memory:0x%x\n" |
|
489 , g_mm_memory_size + HMM_ADDR_ALIGN_UNIT |
|
490 , (unsigned int)g_p_mng_memory_raw |
|
491 , (unsigned int)g_p_mng_memory);) |
|
492 } else { |
|
493 _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n" |
|
494 , g_mm_memory_size);) |
|
495 |
|
496 i_rv = -1; |
|
497 } |
|
498 |
|
499 if (g_p_mng_memory) |
|
500 #endif |
|
501 { |
|
502 int chunk_size = 0; |
|
503 |
|
504 g_mng_memory_allocated = 1; |
|
505 |
|
506 hmm_init(&hmm_d); |
|
507 |
|
508 chunk_size = g_mm_memory_size >> SHIFT_HMM_ADDR_ALIGN_UNIT; |
|
509 |
|
510 chunk_size -= DUMMY_END_BLOCK_BAUS; |
|
511 |
|
512 _P(printf("[vpx][mm] memory size:%d for vpx memory manager. g_p_mng_memory:0x%x chunk_size:%d\n" |
|
513 , g_mm_memory_size |
|
514 , (unsigned int)g_p_mng_memory |
|
515 , chunk_size);) |
|
516 |
|
517 hmm_new_chunk(&hmm_d, (void *)g_p_mng_memory, chunk_size); |
|
518 } |
|
519 |
|
520 #if MM_DYNAMIC_MEMORY |
|
521 else { |
|
522 _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n" |
|
523 , g_mm_memory_size);) |
|
524 |
|
525 i_rv = -1; |
|
526 } |
|
527 |
|
528 #endif |
|
529 } |
|
530 |
|
531 return i_rv; |
|
532 } |
|
533 |
|
534 static void *vpx_mm_realloc(void *memblk, size_t size) { |
|
535 void *p_ret = NULL; |
|
536 |
|
537 if (vpx_mm_create_heap_memory() < 0) { |
|
538 _P(printf("[vpx][mm] ERROR vpx_mm_realloc() Couldn't create memory for Heap.\n");) |
|
539 } else { |
|
540 int i_rv = 0; |
|
541 int old_num_aaus; |
|
542 int new_num_aaus; |
|
543 |
|
544 old_num_aaus = hmm_true_size(memblk); |
|
545 new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1; |
|
546 |
|
547 if (old_num_aaus == new_num_aaus) { |
|
548 p_ret = memblk; |
|
549 } else { |
|
550 i_rv = hmm_resize(&hmm_d, memblk, new_num_aaus); |
|
551 |
|
552 if (i_rv == 0) { |
|
553 p_ret = memblk; |
|
554 } else { |
|
555 /* Error. Try to malloc and then copy data. */ |
|
556 void *p_from_malloc; |
|
557 |
|
558 new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1; |
|
559 p_from_malloc = hmm_alloc(&hmm_d, new_num_aaus); |
|
560 |
|
561 if (p_from_malloc) { |
|
562 vpx_memcpy(p_from_malloc, memblk, size); |
|
563 hmm_free(&hmm_d, memblk); |
|
564 |
|
565 p_ret = p_from_malloc; |
|
566 } |
|
567 } |
|
568 } |
|
569 } |
|
570 |
|
571 return p_ret; |
|
572 } |
|
573 #endif /*CONFIG_MEM_MANAGER*/ |
|
574 |
|
575 #if USE_GLOBAL_FUNCTION_POINTERS |
|
576 # if CONFIG_MEM_TRACKER |
|
577 extern int vpx_memory_tracker_set_functions(g_malloc_func g_malloc_l |
|
578 , g_calloc_func g_calloc_l |
|
579 , g_realloc_func g_realloc_l |
|
580 , g_free_func g_free_l |
|
581 , g_memcpy_func g_memcpy_l |
|
582 , g_memset_func g_memset_l |
|
583 , g_memmove_func g_memmove_l); |
|
584 # endif |
|
585 #endif /*USE_GLOBAL_FUNCTION_POINTERS*/ |
|
586 int vpx_mem_set_functions(g_malloc_func g_malloc_l |
|
587 , g_calloc_func g_calloc_l |
|
588 , g_realloc_func g_realloc_l |
|
589 , g_free_func g_free_l |
|
590 , g_memcpy_func g_memcpy_l |
|
591 , g_memset_func g_memset_l |
|
592 , g_memmove_func g_memmove_l) { |
|
593 #if USE_GLOBAL_FUNCTION_POINTERS |
|
594 |
|
595 /* If use global functions is turned on then the |
|
596 application must set the global functions before |
|
597 it does anything else or vpx_mem will have |
|
598 unpredictable results. */ |
|
599 if (!g_func) { |
|
600 g_func = (struct GLOBAL_FUNC_POINTERS *) |
|
601 g_malloc_l(sizeof(struct GLOBAL_FUNC_POINTERS)); |
|
602 |
|
603 if (!g_func) { |
|
604 return -1; |
|
605 } |
|
606 } |
|
607 |
|
608 #if CONFIG_MEM_TRACKER |
|
609 { |
|
610 int rv = 0; |
|
611 rv = vpx_memory_tracker_set_functions(g_malloc_l |
|
612 , g_calloc_l |
|
613 , g_realloc_l |
|
614 , g_free_l |
|
615 , g_memcpy_l |
|
616 , g_memset_l |
|
617 , g_memmove_l); |
|
618 |
|
619 if (rv < 0) { |
|
620 return rv; |
|
621 } |
|
622 } |
|
623 #endif |
|
624 |
|
625 g_func->g_malloc = g_malloc_l; |
|
626 g_func->g_calloc = g_calloc_l; |
|
627 g_func->g_realloc = g_realloc_l; |
|
628 g_func->g_free = g_free_l; |
|
629 g_func->g_memcpy = g_memcpy_l; |
|
630 g_func->g_memset = g_memset_l; |
|
631 g_func->g_memmove = g_memmove_l; |
|
632 |
|
633 return 0; |
|
634 #else |
|
635 (void)g_malloc_l; |
|
636 (void)g_calloc_l; |
|
637 (void)g_realloc_l; |
|
638 (void)g_free_l; |
|
639 (void)g_memcpy_l; |
|
640 (void)g_memset_l; |
|
641 (void)g_memmove_l; |
|
642 return -1; |
|
643 #endif |
|
644 } |
|
645 |
|
646 int vpx_mem_unset_functions() { |
|
647 #if USE_GLOBAL_FUNCTION_POINTERS |
|
648 |
|
649 if (g_func) { |
|
650 g_free_func temp_free = g_func->g_free; |
|
651 temp_free(g_func); |
|
652 g_func = NULL; |
|
653 } |
|
654 |
|
655 #endif |
|
656 return 0; |
|
657 } |