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 19 #ifndef CONFIG_MEM_MANAGER 20 # if defined(VXWORKS) 21 # define CONFIG_MEM_MANAGER 1 //include heap manager functionality, 22 //default: enabled on vxworks 23 # else 24 # define CONFIG_MEM_MANAGER 0 //include heap manager functionality 25 # endif 26 #endif 27 28 #ifndef CONFIG_MEM_TRACKER 29 # define CONFIG_MEM_TRACKER 1 //include xvpx_* calls in the lib 30 #endif 31 32 #ifndef CONFIG_MEM_CHECKS 33 # define CONFIG_MEM_CHECKS 0 //include some basic safety checks in 34 //vpx_memcpy, _memset, and _memmove 35 #endif 36 37 #ifndef USE_GLOBAL_FUNCTION_POINTERS 38 # define USE_GLOBAL_FUNCTION_POINTERS 0 //use function pointers instead of compiled functions. 39 #endif 40 41 #if CONFIG_MEM_TRACKER 42 # include "vpx_mem_tracker.h" 43 # if VPX_MEM_TRACKER_VERSION_CHIEF != 2 || VPX_MEM_TRACKER_VERSION_MAJOR != 5 44 # error "vpx_mem requires memory tracker version 2.5 to track memory usage" 45 # endif 46 #endif 47 48 #define ADDRESS_STORAGE_SIZE sizeof(size_t) 49 50 #ifndef DEFAULT_ALIGNMENT 51 # if defined(VXWORKS) 52 # define DEFAULT_ALIGNMENT 32 //default addr alignment to use in 53 //calls to vpx_* functions other 54 //than vpx_memalign 55 # else 56 # define DEFAULT_ALIGNMENT 1 57 # endif 58 #endif 59 60 #if DEFAULT_ALIGNMENT < 1 61 # error "DEFAULT_ALIGNMENT must be >= 1!" 62 #endif 63 64 #if CONFIG_MEM_TRACKER 65 # define TRY_BOUNDS_CHECK 1 //when set to 1 pads each allocation, 66 //integrity can be checked using 67 //vpx_memory_tracker_check_integrity 68 //or on free by defining 69 //TRY_BOUNDS_CHECK_ON_FREE 70 static unsigned long g_alloc_count = 0; 71 72 #else 73 # define TRY_BOUNDS_CHECK 0 74 #endif 75 76 #if TRY_BOUNDS_CHECK 77 # define TRY_BOUNDS_CHECK_ON_FREE 0 //checks mem integrity on every 78 //free, very expensive 79 # define BOUNDS_CHECK_VALUE 0xdeadbeef //value stored before/after ea. 80 //mem addr for bounds checking 81 # define BOUNDS_CHECK_PAD_SIZE 32 //size of the padding before and 82 //after ea allocation to be filled 83 //with BOUNDS_CHECK_VALUE. 84 //this should be a multiple of 4 85 #else 86 # define BOUNDS_CHECK_VALUE 0 87 # define BOUNDS_CHECK_PAD_SIZE 0 88 #endif 89 90 #if CONFIG_MEM_MANAGER 91 # include "heapmm.h" 92 # include "hmm_intrnl.h" 93 94 # define SHIFT_HMM_ADDR_ALIGN_UNIT 5 95 # define TOTAL_MEMORY_TO_ALLOCATE 20971520 // 20 * 1024 * 1024 96 97 # define MM_DYNAMIC_MEMORY 1 98 # if MM_DYNAMIC_MEMORY 99 static unsigned char *g_p_mng_memory_raw = NULL; 100 static unsigned char *g_p_mng_memory = NULL; 101 # else 102 static unsigned char g_p_mng_memory[TOTAL_MEMORY_TO_ALLOCATE]; 103 # endif 104 105 static size_t g_mm_memory_size = TOTAL_MEMORY_TO_ALLOCATE; 106 107 static hmm_descriptor hmm_d; 108 static int g_mng_memory_allocated = 0; 109 110 static int vpx_mm_create_heap_memory(); 111 static void *vpx_mm_realloc(void *memblk, size_t size); 112 #endif //CONFIG_MEM_MANAGER 113 114 #if USE_GLOBAL_FUNCTION_POINTERS 115 116 struct GLOBAL_FUNC_POINTERS 117 { 118 g_malloc_func g_malloc; 119 g_calloc_func g_calloc; 120 g_realloc_func g_realloc; 121 g_free_func g_free; 122 g_memcpy_func g_memcpy; 123 g_memset_func g_memset; 124 g_memmove_func g_memmove; 125 }; 126 struct GLOBAL_FUNC_POINTERS *g_func = 0; 127 128 # define VPX_MALLOC_L g_func->g_malloc 129 # define VPX_REALLOC_L g_func->g_realloc 130 # define VPX_FREE_L g_func->g_free 131 # define VPX_MEMCPY_L g_func->g_memcpy 132 # define VPX_MEMSET_L g_func->g_memset 133 # define VPX_MEMMOVE_L g_func->g_memmove 134 135 #else 136 # define VPX_MALLOC_L malloc 137 # define VPX_REALLOC_L realloc 138 # define VPX_FREE_L free 139 # define VPX_MEMCPY_L memcpy 140 # define VPX_MEMSET_L memset 141 # define VPX_MEMMOVE_L memmove 142 #endif // USE_GLOBAL_FUNCTION_POINTERS 143 144 /* Should probably use a vpx_mem logger function. */ 145 #define __REMOVE_PRINTFS 146 #ifdef __REMOVE_PRINTFS 147 #define _P(x) 148 #else 149 #define _P(x) x 150 #endif 151 152 /*returns an addr aligned to the byte boundary specified by align*/ 153 #define align_addr(addr,align) \ 154 (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align)) 155 156 unsigned int vpx_mem_get_version() 157 { 158 unsigned int ver = ((unsigned int)(unsigned char)VPX_MEM_VERSION_CHIEF << 24 | 159 (unsigned int)(unsigned char)VPX_MEM_VERSION_MAJOR << 16 | 160 (unsigned int)(unsigned char)VPX_MEM_VERSION_MINOR << 8 | 161 (unsigned int)(unsigned char)VPX_MEM_VERSION_PATCH); 162 return ver; 163 } 164 165 int vpx_mem_set_heap_size(size_t size) 166 { 167 int ret = -1; 168 169 #if CONFIG_MEM_MANAGER 170 #if MM_DYNAMIC_MEMORY 171 172 if (!g_mng_memory_allocated && size) 173 { 174 g_mm_memory_size = size; 175 ret = 0; 176 } 177 else 178 ret = -3; 179 180 #else 181 ret = -2; 182 #endif 183 #else 184 (void)size; 185 #endif 186 187 return ret; 188 } 189 190 void *vpx_memalign(size_t align, size_t size) 191 { 192 void *addr, 193 * x = NULL; 194 195 #if CONFIG_MEM_MANAGER 196 int number_aau; 197 198 if (vpx_mm_create_heap_memory() < 0) 199 { 200 _P(printf("[vpx][mm] ERROR vpx_memalign() Couldn't create memory for Heap.\n");) 201 } 202 203 number_aau = ((size + align - 1 + ADDRESS_STORAGE_SIZE) >> 204 SHIFT_HMM_ADDR_ALIGN_UNIT) + 1; 205 206 addr = hmm_alloc(&hmm_d, number_aau); 207 #else 208 addr = VPX_MALLOC_L(size + align - 1 + ADDRESS_STORAGE_SIZE); 209 #endif //CONFIG_MEM_MANAGER 210 211 if (addr) 212 { 213 x = align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, (int)align); 214 /* save the actual malloc address */ 215 ((size_t *)x)[-1] = (size_t)addr; 216 } 217 218 return x; 219 } 220 221 void *vpx_malloc(size_t size) 222 { 223 return vpx_memalign(DEFAULT_ALIGNMENT, size); 224 } 225 226 void *vpx_calloc(size_t num, size_t size) 227 { 228 void *x; 229 230 x = vpx_memalign(DEFAULT_ALIGNMENT, num * size); 231 232 if (x) 233 VPX_MEMSET_L(x, 0, num * size); 234 235 return x; 236 } 237 238 void *vpx_realloc(void *memblk, size_t size) 239 { 240 void *addr, 241 * new_addr = NULL; 242 int align = DEFAULT_ALIGNMENT; 243 244 /* 245 The realloc() function changes the size of the object pointed to by 246 ptr to the size specified by size, and returns a pointer to the 247 possibly moved block. The contents are unchanged up to the lesser 248 of the new and old sizes. If ptr is null, realloc() behaves like 249 malloc() for the specified size. If size is zero (0) and ptr is 250 not a null pointer, the object pointed to is freed. 251 */ 252 if (!memblk) 253 new_addr = vpx_malloc(size); 254 else if (!size) 255 vpx_free(memblk); 256 else 257 { 258 addr = (void *)(((size_t *)memblk)[-1]); 259 memblk = NULL; 260 261 #if CONFIG_MEM_MANAGER 262 new_addr = vpx_mm_realloc(addr, size + align + ADDRESS_STORAGE_SIZE); 263 #else 264 new_addr = VPX_REALLOC_L(addr, size + align + ADDRESS_STORAGE_SIZE); 265 #endif 266 267 if (new_addr) 268 { 269 addr = new_addr; 270 new_addr = (void *)(((size_t) 271 ((unsigned char *)new_addr + ADDRESS_STORAGE_SIZE) + (align - 1)) & 272 (size_t) - align); 273 /* save the actual malloc address */ 274 ((size_t *)new_addr)[-1] = (size_t)addr; 275 } 276 } 277 278 return new_addr; 279 } 280 281 void vpx_free(void *memblk) 282 { 283 if (memblk) 284 { 285 void *addr = (void *)(((size_t *)memblk)[-1]); 286 #if CONFIG_MEM_MANAGER 287 hmm_free(&hmm_d, addr); 288 #else 289 VPX_FREE_L(addr); 290 #endif 291 } 292 } 293 294 void *vpx_mem_alloc(int id, size_t size, size_t align) 295 { 296 #if defined CHIP_DM642 || defined __uClinux__ 297 void *mem = (void *)mem_alloc(id, size, align); 298 299 if (!mem) 300 { 301 _P(fprintf(stderr, 302 "\n" 303 "*********************************************************\n" 304 "WARNING: mem_alloc returned 0 for id=%p size=%u align=%u.\n" 305 "*********************************************************\n", 306 mem, size, align)); 307 // should no longer need this. Softier says it's fixed. 2005-01-21 tjf 308 //#if defined __uClinux__ 309 //while(1)usleep(1000000); 310 //#endif 311 } 312 313 #if defined __uClinux__ 314 else if (mem == (void *)0xFFFFFFFF) 315 { 316 // out of memory/error 317 mem = (void *)0; 318 319 _P(fprintf(stderr, 320 "\n" 321 "******************************************************\n" 322 "ERROR: mem_alloc id=%p size=%u align=%u OUT OF MEMORY.\n" 323 "******************************************************\n", 324 mem, size, align)); 325 } 326 327 #endif // __uClinux__ 328 329 return mem; 330 #else 331 (void)id; 332 (void)size; 333 (void)align; 334 return (void *)0; 335 #endif 336 } 337 338 void vpx_mem_free(int id, void *mem, size_t size) 339 { 340 #if defined CHIP_DM642 || defined __uClinux__ 341 342 if (!mem) 343 { 344 _P(fprintf(stderr, 345 "\n" 346 "**************************************\n" 347 "WARNING: 0 being free'd id=%p size=%u.\n" 348 "**************************************\n", 349 id, size)); 350 351 // should no longer need this. Softier says it's fixed. 2005-01-21 tjf 352 //#if defined __uClinux__ 353 //while(1)usleep(1000000); 354 //#endif 355 } 356 357 mem_free(id, mem, size); 358 #else 359 (void)id; 360 (void)mem; 361 (void)size; 362 #endif 363 } 364 365 366 #if CONFIG_MEM_TRACKER 367 368 void *xvpx_mem_alloc(int id, size_t size, size_t align, char *file, int line) 369 { 370 void *mem = vpx_mem_alloc(id, size, align); 371 372 vpx_memory_tracker_add((size_t)mem, size, file, line, 0); 373 374 return mem; 375 } 376 377 void xvpx_mem_free(int id, void *mem, size_t size, char *file, int line) 378 { 379 if (vpx_memory_tracker_remove((size_t)mem) == -2) 380 { 381 #if REMOVE_PRINTFS 382 (void)file; 383 (void)line; 384 #endif 385 _P(fprintf(stderr, "[vpx_mem][xvpx_mem_free] addr: %p (id=%p size=%u) " 386 "not found in list; freed from file:%s" 387 " line:%d\n", mem, id, size, file, line)); 388 } 389 390 vpx_mem_free(id, mem, size); 391 } 392 393 void *xvpx_memalign(size_t align, size_t size, char *file, int line) 394 { 395 #if TRY_BOUNDS_CHECK 396 unsigned char *x_bounds; 397 #endif 398 399 void *x; 400 401 if (g_alloc_count == 0) 402 { 403 #if TRY_BOUNDS_CHECK 404 int i_rv = vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE); 405 #else 406 int i_rv = vpx_memory_tracker_init(0, 0); 407 #endif 408 409 if (i_rv < 0) 410 { 411 _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");) 412 } 413 } 414 415 #if TRY_BOUNDS_CHECK 416 { 417 int i; 418 unsigned int tempme = BOUNDS_CHECK_VALUE; 419 420 x_bounds = vpx_memalign(align, size + (BOUNDS_CHECK_PAD_SIZE * 2)); 421 422 if (x_bounds) 423 { 424 /*we're aligning the address twice here but to keep things 425 consistent we want to have the padding come before the stored 426 address so no matter what free function gets called we will 427 attempt to free the correct address*/ 428 x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]); 429 x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE, 430 (int)align); 431 /* save the actual malloc address */ 432 ((size_t *)x)[-1] = (size_t)x_bounds; 433 434 for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int)) 435 { 436 VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int)); 437 VPX_MEMCPY_L((unsigned char *)x + size + i, 438 &tempme, sizeof(unsigned int)); 439 } 440 } 441 else 442 x = NULL; 443 } 444 #else 445 x = vpx_memalign(align, size); 446 #endif //TRY_BOUNDS_CHECK 447 448 g_alloc_count++; 449 450 vpx_memory_tracker_add((size_t)x, size, file, line, 1); 451 452 return x; 453 } 454 455 void *xvpx_malloc(size_t size, char *file, int line) 456 { 457 return xvpx_memalign(DEFAULT_ALIGNMENT, size, file, line); 458 } 459 460 void *xvpx_calloc(size_t num, size_t size, char *file, int line) 461 { 462 void *x = xvpx_memalign(DEFAULT_ALIGNMENT, num * size, file, line); 463 464 if (x) 465 VPX_MEMSET_L(x, 0, num * size); 466 467 return x; 468 } 469 470 void *xvpx_realloc(void *memblk, size_t size, char *file, int line) 471 { 472 struct mem_block *p = NULL; 473 int orig_size = 0, 474 orig_line = 0; 475 char *orig_file = NULL; 476 477 #if TRY_BOUNDS_CHECK 478 unsigned char *x_bounds = memblk ? 479 (unsigned char *)(((size_t *)memblk)[-1]) : 480 NULL; 481 #endif 482 483 void *x; 484 485 if (g_alloc_count == 0) 486 { 487 #if TRY_BOUNDS_CHECK 488 489 if (!vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE)) 490 #else 491 if (!vpx_memory_tracker_init(0, 0)) 492 #endif 493 { 494 _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");) 495 } 496 } 497 498 if (p = vpx_memory_tracker_find((size_t)memblk)) 499 { 500 orig_size = p->size; 501 orig_file = p->file; 502 orig_line = p->line; 503 } 504 505 #if TRY_BOUNDS_CHECK_ON_FREE 506 vpx_memory_tracker_check_integrity(file, line); 507 #endif 508 509 //have to do this regardless of success, because 510 //the memory that does get realloc'd may change 511 //the bounds values of this block 512 vpx_memory_tracker_remove((size_t)memblk); 513 514 #if TRY_BOUNDS_CHECK 515 { 516 int i; 517 unsigned int tempme = BOUNDS_CHECK_VALUE; 518 519 x_bounds = vpx_realloc(memblk, size + (BOUNDS_CHECK_PAD_SIZE * 2)); 520 521 if (x_bounds) 522 { 523 x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]); 524 x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE, 525 (int)DEFAULT_ALIGNMENT); 526 /* save the actual malloc address */ 527 ((size_t *)x)[-1] = (size_t)x_bounds; 528 529 for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int)) 530 { 531 VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int)); 532 VPX_MEMCPY_L((unsigned char *)x + size + i, 533 &tempme, sizeof(unsigned int)); 534 } 535 } 536 else 537 x = NULL; 538 } 539 #else 540 x = vpx_realloc(memblk, size); 541 #endif //TRY_BOUNDS_CHECK 542 543 if (x) 544 vpx_memory_tracker_add((size_t)x, size, file, line, 1); 545 else 546 vpx_memory_tracker_add((size_t)memblk, orig_size, orig_file, orig_line, 1); 547 548 return x; 549 } 550 551 void xvpx_free(void *p_address, char *file, int line) 552 { 553 #if TRY_BOUNDS_CHECK 554 unsigned char *p_bounds_address = (unsigned char *)p_address; 555 //p_bounds_address -= BOUNDS_CHECK_PAD_SIZE; 556 #endif 557 558 #if !TRY_BOUNDS_CHECK_ON_FREE 559 (void)file; 560 (void)line; 561 #endif 562 563 if (p_address) 564 { 565 #if TRY_BOUNDS_CHECK_ON_FREE 566 vpx_memory_tracker_check_integrity(file, line); 567 #endif 568 569 //if the addr isn't found in the list, assume it was allocated via 570 //vpx_ calls not xvpx_, therefore it does not contain any padding 571 if (vpx_memory_tracker_remove((size_t)p_address) == -2) 572 { 573 p_bounds_address = p_address; 574 _P(fprintf(stderr, "[vpx_mem][xvpx_free] addr: %p not found in" 575 " list; freed from file:%s" 576 " line:%d\n", p_address, file, line)); 577 } 578 else 579 --g_alloc_count; 580 581 #if TRY_BOUNDS_CHECK 582 vpx_free(p_bounds_address); 583 #else 584 vpx_free(p_address); 585 #endif 586 587 if (!g_alloc_count) 588 vpx_memory_tracker_destroy(); 589 } 590 } 591 592 #endif /*CONFIG_MEM_TRACKER*/ 593 594 #if CONFIG_MEM_CHECKS 595 #if defined(VXWORKS) 596 #include <task_lib.h> //for task_delay() 597 /* This function is only used to get a stack trace of the player 598 object so we can se where we are having a problem. */ 599 static int get_my_tt(int task) 600 { 601 tt(task); 602 603 return 0; 604 } 605 606 static void vx_sleep(int msec) 607 { 608 int ticks_to_sleep = 0; 609 610 if (msec) 611 { 612 int msec_per_tick = 1000 / sys_clk_rate_get(); 613 614 if (msec < msec_per_tick) 615 ticks_to_sleep++; 616 else 617 ticks_to_sleep = msec / msec_per_tick; 618 } 619 620 task_delay(ticks_to_sleep); 621 } 622 #endif 623 #endif 624 625 void *vpx_memcpy(void *dest, const void *source, size_t length) 626 { 627 #if CONFIG_MEM_CHECKS 628 629 if (((int)dest < 0x4000) || ((int)source < 0x4000)) 630 { 631 _P(printf("WARNING: vpx_memcpy dest:0x%x source:0x%x len:%d\n", (int)dest, (int)source, length);) 632 633 #if defined(VXWORKS) 634 sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0); 635 636 vx_sleep(10000); 637 #endif 638 } 639 640 #endif 641 642 return VPX_MEMCPY_L(dest, source, length); 643 } 644 645 void *vpx_memset(void *dest, int val, size_t length) 646 { 647 #if CONFIG_MEM_CHECKS 648 649 if ((int)dest < 0x4000) 650 { 651 _P(printf("WARNING: vpx_memset dest:0x%x val:%d len:%d\n", (int)dest, val, length);) 652 653 #if defined(VXWORKS) 654 sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0); 655 656 vx_sleep(10000); 657 #endif 658 } 659 660 #endif 661 662 return VPX_MEMSET_L(dest, val, length); 663 } 664 665 void *vpx_memmove(void *dest, const void *src, size_t count) 666 { 667 #if CONFIG_MEM_CHECKS 668 669 if (((int)dest < 0x4000) || ((int)src < 0x4000)) 670 { 671 _P(printf("WARNING: vpx_memmove dest:0x%x src:0x%x count:%d\n", (int)dest, (int)src, count);) 672 673 #if defined(VXWORKS) 674 sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0); 675 676 vx_sleep(10000); 677 #endif 678 } 679 680 #endif 681 682 return VPX_MEMMOVE_L(dest, src, count); 683 } 684 685 #if CONFIG_MEM_MANAGER 686 687 static int vpx_mm_create_heap_memory() 688 { 689 int i_rv = 0; 690 691 if (!g_mng_memory_allocated) 692 { 693 #if MM_DYNAMIC_MEMORY 694 g_p_mng_memory_raw = 695 (unsigned char *)malloc(g_mm_memory_size + HMM_ADDR_ALIGN_UNIT); 696 697 if (g_p_mng_memory_raw) 698 { 699 g_p_mng_memory = (unsigned char *)((((unsigned int)g_p_mng_memory_raw) + 700 HMM_ADDR_ALIGN_UNIT - 1) & 701 -(int)HMM_ADDR_ALIGN_UNIT); 702 703 _P(printf("[vpx][mm] total memory size:%d g_p_mng_memory_raw:0x%x g_p_mng_memory:0x%x\n" 704 , g_mm_memory_size + HMM_ADDR_ALIGN_UNIT 705 , (unsigned int)g_p_mng_memory_raw 706 , (unsigned int)g_p_mng_memory);) 707 } 708 else 709 { 710 _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n" 711 , g_mm_memory_size);) 712 713 i_rv = -1; 714 } 715 716 if (g_p_mng_memory) 717 #endif 718 { 719 int chunk_size = 0; 720 721 g_mng_memory_allocated = 1; 722 723 hmm_init(&hmm_d); 724 725 chunk_size = g_mm_memory_size >> SHIFT_HMM_ADDR_ALIGN_UNIT; 726 727 chunk_size -= DUMMY_END_BLOCK_BAUS; 728 729 _P(printf("[vpx][mm] memory size:%d for vpx memory manager. g_p_mng_memory:0x%x chunk_size:%d\n" 730 , g_mm_memory_size 731 , (unsigned int)g_p_mng_memory 732 , chunk_size);) 733 734 hmm_new_chunk(&hmm_d, (void *)g_p_mng_memory, chunk_size); 735 } 736 737 #if MM_DYNAMIC_MEMORY 738 else 739 { 740 _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n" 741 , g_mm_memory_size);) 742 743 i_rv = -1; 744 } 745 746 #endif 747 } 748 749 return i_rv; 750 } 751 752 static void *vpx_mm_realloc(void *memblk, size_t size) 753 { 754 void *p_ret = NULL; 755 756 if (vpx_mm_create_heap_memory() < 0) 757 { 758 _P(printf("[vpx][mm] ERROR vpx_mm_realloc() Couldn't create memory for Heap.\n");) 759 } 760 else 761 { 762 int i_rv = 0; 763 int old_num_aaus; 764 int new_num_aaus; 765 766 old_num_aaus = hmm_true_size(memblk); 767 new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1; 768 769 if (old_num_aaus == new_num_aaus) 770 { 771 p_ret = memblk; 772 } 773 else 774 { 775 i_rv = hmm_resize(&hmm_d, memblk, new_num_aaus); 776 777 if (i_rv == 0) 778 { 779 p_ret = memblk; 780 } 781 else 782 { 783 /* Error. Try to malloc and then copy data. */ 784 void *p_from_malloc; 785 786 new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1; 787 p_from_malloc = hmm_alloc(&hmm_d, new_num_aaus); 788 789 if (p_from_malloc) 790 { 791 vpx_memcpy(p_from_malloc, memblk, size); 792 hmm_free(&hmm_d, memblk); 793 794 p_ret = p_from_malloc; 795 } 796 } 797 } 798 } 799 800 return p_ret; 801 } 802 #endif //CONFIG_MEM_MANAGER 803 804 #if USE_GLOBAL_FUNCTION_POINTERS 805 # if CONFIG_MEM_TRACKER 806 extern int vpx_memory_tracker_set_functions(g_malloc_func g_malloc_l 807 , g_calloc_func g_calloc_l 808 , g_realloc_func g_realloc_l 809 , g_free_func g_free_l 810 , g_memcpy_func g_memcpy_l 811 , g_memset_func g_memset_l 812 , g_memmove_func g_memmove_l); 813 # endif 814 #endif 815 int vpx_mem_set_functions(g_malloc_func g_malloc_l 816 , g_calloc_func g_calloc_l 817 , g_realloc_func g_realloc_l 818 , g_free_func g_free_l 819 , g_memcpy_func g_memcpy_l 820 , g_memset_func g_memset_l 821 , g_memmove_func g_memmove_l) 822 { 823 #if USE_GLOBAL_FUNCTION_POINTERS 824 825 /* If use global functions is turned on then the 826 application must set the global functions before 827 it does anything else or vpx_mem will have 828 unpredictable results. */ 829 if (!g_func) 830 { 831 g_func = (struct GLOBAL_FUNC_POINTERS *)g_malloc_l(sizeof(struct GLOBAL_FUNC_POINTERS)); 832 833 if (!g_func) 834 { 835 return -1; 836 } 837 } 838 839 #if CONFIG_MEM_TRACKER 840 { 841 int rv = 0; 842 rv = vpx_memory_tracker_set_functions(g_malloc_l 843 , g_calloc_l 844 , g_realloc_l 845 , g_free_l 846 , g_memcpy_l 847 , g_memset_l 848 , g_memmove_l); 849 850 if (rv < 0) 851 { 852 return rv; 853 } 854 } 855 #endif 856 857 if (g_malloc_l) 858 g_func->g_malloc = g_malloc_l; 859 else 860 g_func->g_malloc = 0; 861 862 if (g_calloc_l) 863 g_func->g_calloc = g_calloc_l; 864 else 865 g_func->g_calloc = 0; 866 867 if (g_realloc_l) 868 g_func->g_realloc = g_realloc_l; 869 else 870 g_func->g_realloc = 0; 871 872 if (g_free_l) 873 g_func->g_free = g_free_l; 874 else 875 g_func->g_free = 0; 876 877 if (g_memcpy_l) 878 g_func->g_memcpy = g_memcpy_l; 879 else 880 g_func->g_memcpy = 0; 881 882 if (g_memset_l) 883 g_func->g_memset = g_memset_l; 884 else 885 g_func->g_memset = 0; 886 887 if (g_memmove_l) 888 g_func->g_memmove = g_memmove_l; 889 else 890 g_func->g_memmove = 0; 891 892 return 0; 893 #else 894 (void)g_malloc_l; 895 (void)g_calloc_l; 896 (void)g_realloc_l; 897 (void)g_free_l; 898 (void)g_memcpy_l; 899 (void)g_memset_l; 900 (void)g_memmove_l; 901 return -1; 902 #endif 903 } 904 905 int vpx_mem_unset_functions() 906 { 907 #if USE_GLOBAL_FUNCTION_POINTERS 908 909 if (g_func) 910 { 911 g_free_func temp_free; 912 913 temp_free = g_func->g_free; 914 915 temp_free(g_func); 916 g_func = 0; 917 } 918 919 #endif 920 return 0; 921 } 922 923 #ifdef _INTEL_LINUX 924 void *_intel_fast_memcpy(void *dest, const void *src, size_t count) 925 { 926 927 //memcpy(dest, src, count); 928 char *dst8 = (char *)dest; 929 char *src8 = (char *)src; 930 931 while (count--) 932 { 933 *dst8++ = *src8++; 934 } 935 936 return dest; 937 } 938 939 void *_intel_fast_memset(void *dest, int c, size_t count) 940 { 941 memset(dest, c, count); 942 return dest; 943 } 944 945 void *_VEC_memzero(void *dest, int c, size_t count) 946 { 947 memset(dest, 0, count); 948 return dest; 949 } 950 951 #endif //_ICC 952