mem.c

Go to the documentation of this file.
00001 /*
00002  * default memory allocator for libavutil
00003  * Copyright (c) 2002 Fabrice Bellard.
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 /**
00023  * @file mem.c
00024  * default memory allocator for libavutil.
00025  */
00026 
00027 #include "common.h"
00028 
00029 /* here we can use OS dependent allocation functions */
00030 #undef malloc
00031 #undef free
00032 #undef realloc
00033 
00034 #ifdef HAVE_MALLOC_H
00035 #include <malloc.h>
00036 #endif
00037 
00038 /* you can redefine av_malloc and av_free in your project to use your
00039    memory allocator. You do not need to suppress this file because the
00040    linker will do it automatically */
00041 
00042 void *av_malloc(unsigned int size)
00043 {
00044     void *ptr;
00045 #ifdef CONFIG_MEMALIGN_HACK
00046     long diff;
00047 #endif
00048 
00049     /* let's disallow possible ambiguous cases */
00050     if(size > (INT_MAX-16) )
00051         return NULL;
00052 
00053 #ifdef CONFIG_MEMALIGN_HACK
00054     ptr = malloc(size+16);
00055     if(!ptr)
00056         return ptr;
00057     diff= ((-(long)ptr - 1)&15) + 1;
00058     ptr = (char*)ptr + diff;
00059     ((char*)ptr)[-1]= diff;
00060 #elif defined (HAVE_MEMALIGN)
00061     ptr = memalign(16,size);
00062     /* Why 64?
00063        Indeed, we should align it:
00064          on 4 for 386
00065          on 16 for 486
00066          on 32 for 586, PPro - k6-III
00067          on 64 for K7 (maybe for P3 too).
00068        Because L1 and L2 caches are aligned on those values.
00069        But I don't want to code such logic here!
00070      */
00071      /* Why 16?
00072         Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
00073         it will just trigger an exception and the unaligned load will be done in the
00074         exception handler or it will just segfault (SSE2 on P4)
00075         Why not larger? Because I did not see a difference in benchmarks ...
00076      */
00077      /* benchmarks with p3
00078         memalign(64)+1          3071,3051,3032
00079         memalign(64)+2          3051,3032,3041
00080         memalign(64)+4          2911,2896,2915
00081         memalign(64)+8          2545,2554,2550
00082         memalign(64)+16         2543,2572,2563
00083         memalign(64)+32         2546,2545,2571
00084         memalign(64)+64         2570,2533,2558
00085 
00086         btw, malloc seems to do 8 byte alignment by default here
00087      */
00088 #else
00089     ptr = malloc(size);
00090 #endif
00091     return ptr;
00092 }
00093 
00094 void *av_realloc(void *ptr, unsigned int size)
00095 {
00096 #ifdef CONFIG_MEMALIGN_HACK
00097     int diff;
00098 #endif
00099 
00100     /* let's disallow possible ambiguous cases */
00101     if(size > (INT_MAX-16) )
00102         return NULL;
00103 
00104 #ifdef CONFIG_MEMALIGN_HACK
00105     //FIXME this isn't aligned correctly, though it probably isn't needed
00106     if(!ptr) return av_malloc(size);
00107     diff= ((char*)ptr)[-1];
00108     return (char*)realloc((char*)ptr - diff, size + diff) + diff;
00109 #else
00110     return realloc(ptr, size);
00111 #endif
00112 }
00113 
00114 void av_free(void *ptr)
00115 {
00116     /* XXX: this test should not be needed on most libcs */
00117     if (ptr)
00118 #ifdef CONFIG_MEMALIGN_HACK
00119         free((char*)ptr - ((char*)ptr)[-1]);
00120 #else
00121         free(ptr);
00122 #endif
00123 }
00124 
00125 void av_freep(void *arg)
00126 {
00127     void **ptr= (void**)arg;
00128     av_free(*ptr);
00129     *ptr = NULL;
00130 }
00131 
00132 void *av_mallocz(unsigned int size)
00133 {
00134     void *ptr = av_malloc(size);
00135     if (ptr)
00136         memset(ptr, 0, size);
00137     return ptr;
00138 }
00139 
00140 char *av_strdup(const char *s)
00141 {
00142     char *ptr= NULL;
00143     if(s){
00144         int len = strlen(s) + 1;
00145         ptr = av_malloc(len);
00146         if (ptr)
00147             memcpy(ptr, s, len);
00148     }
00149     return ptr;
00150 }
00151 

Generated on Thu Nov 20 11:44:44 2008 for libextractor by  doxygen 1.5.1