Home | History | Annotate | Download | only in intel_linux
      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