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