Home | History | Annotate | Download | only in vpx_mem
      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 }
    658