1/* 2 * default memory allocator for libavutil 3 * Copyright (c) 2002 Fabrice Bellard 4 * 5 * This file is part of Libav. 6 * 7 * Libav is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * Libav is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with Libav; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * default memory allocator for libavutil 25 */ 26 27#include "config.h" 28 29#include <limits.h> 30#include <stdlib.h> 31#include <string.h> 32#if HAVE_MALLOC_H 33#include <malloc.h> 34#endif 35 36#include "avutil.h" 37#include "mem.h" 38 39/* here we can use OS-dependent allocation functions */ 40#undef free 41#undef malloc 42#undef realloc 43 44#ifdef MALLOC_PREFIX 45 46#define malloc AV_JOIN(MALLOC_PREFIX, malloc) 47#define memalign AV_JOIN(MALLOC_PREFIX, memalign) 48#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign) 49#define realloc AV_JOIN(MALLOC_PREFIX, realloc) 50#define free AV_JOIN(MALLOC_PREFIX, free) 51 52void *malloc(size_t size); 53void *memalign(size_t align, size_t size); 54int posix_memalign(void **ptr, size_t align, size_t size); 55void *realloc(void *ptr, size_t size); 56void free(void *ptr); 57 58#endif /* MALLOC_PREFIX */ 59 60/* You can redefine av_malloc and av_free in your project to use your 61 memory allocator. You do not need to suppress this file because the 62 linker will do it automatically. */ 63 64void *av_malloc(size_t size) 65{ 66 void *ptr = NULL; 67#if CONFIG_MEMALIGN_HACK 68 long diff; 69#endif 70 71 /* let's disallow possible ambiguous cases */ 72 if(size > (INT_MAX-32) ) 73 return NULL; 74 75#if CONFIG_MEMALIGN_HACK 76 ptr = malloc(size+32); 77 if(!ptr) 78 return ptr; 79 diff= ((-(long)ptr - 1)&31) + 1; 80 ptr = (char*)ptr + diff; 81 ((char*)ptr)[-1]= diff; 82#elif HAVE_POSIX_MEMALIGN 83 if (posix_memalign(&ptr,32,size)) 84 ptr = NULL; 85#elif HAVE_MEMALIGN 86 ptr = memalign(32,size); 87 /* Why 64? 88 Indeed, we should align it: 89 on 4 for 386 90 on 16 for 486 91 on 32 for 586, PPro - K6-III 92 on 64 for K7 (maybe for P3 too). 93 Because L1 and L2 caches are aligned on those values. 94 But I don't want to code such logic here! 95 */ 96 /* Why 32? 97 For AVX ASM. SSE / NEON needs only 16. 98 Why not larger? Because I did not see a difference in benchmarks ... 99 */ 100 /* benchmarks with P3 101 memalign(64)+1 3071,3051,3032 102 memalign(64)+2 3051,3032,3041 103 memalign(64)+4 2911,2896,2915 104 memalign(64)+8 2545,2554,2550 105 memalign(64)+16 2543,2572,2563 106 memalign(64)+32 2546,2545,2571 107 memalign(64)+64 2570,2533,2558 108 109 BTW, malloc seems to do 8-byte alignment by default here. 110 */ 111#else 112 ptr = malloc(size); 113#endif 114 return ptr; 115} 116 117void *av_realloc(void *ptr, size_t size) 118{ 119#if CONFIG_MEMALIGN_HACK 120 int diff; 121#endif 122 123 /* let's disallow possible ambiguous cases */ 124 if(size > (INT_MAX-16) ) 125 return NULL; 126 127#if CONFIG_MEMALIGN_HACK 128 //FIXME this isn't aligned correctly, though it probably isn't needed 129 if(!ptr) return av_malloc(size); 130 diff= ((char*)ptr)[-1]; 131 return (char*)realloc((char*)ptr - diff, size + diff) + diff; 132#else 133 return realloc(ptr, size); 134#endif 135} 136 137void av_free(void *ptr) 138{ 139#if CONFIG_MEMALIGN_HACK 140 if (ptr) 141 free((char*)ptr - ((char*)ptr)[-1]); 142#else 143 free(ptr); 144#endif 145} 146 147void av_freep(void *arg) 148{ 149 void **ptr= (void**)arg; 150 av_free(*ptr); 151 *ptr = NULL; 152} 153 154void *av_mallocz(size_t size) 155{ 156 void *ptr = av_malloc(size); 157 if (ptr) 158 memset(ptr, 0, size); 159 return ptr; 160} 161 162char *av_strdup(const char *s) 163{ 164 char *ptr= NULL; 165 if(s){ 166 int len = strlen(s) + 1; 167 ptr = av_malloc(len); 168 if (ptr) 169 memcpy(ptr, s, len); 170 } 171 return ptr; 172} 173 174