• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavutil/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 
00027 #include "config.h"
00028 
00029 #include <limits.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #if HAVE_MALLOC_H
00033 #include <malloc.h>
00034 #endif
00035 
00036 #include "mem.h"
00037 
00038 /* here we can use OS-dependent allocation functions */
00039 #undef free
00040 #undef malloc
00041 #undef realloc
00042 
00043 /* You can redefine av_malloc and av_free in your project to use your
00044    memory allocator. You do not need to suppress this file because the
00045    linker will do it automatically. */
00046 
00047 void *av_malloc(unsigned int size)
00048 {
00049     void *ptr = NULL;
00050 #if CONFIG_MEMALIGN_HACK
00051     long diff;
00052 #endif
00053 
00054     /* let's disallow possible ambiguous cases */
00055     if(size > (INT_MAX-16) )
00056         return NULL;
00057 
00058 #if CONFIG_MEMALIGN_HACK
00059     ptr = malloc(size+16);
00060     if(!ptr)
00061         return ptr;
00062     diff= ((-(long)ptr - 1)&15) + 1;
00063     ptr = (char*)ptr + diff;
00064     ((char*)ptr)[-1]= diff;
00065 #elif HAVE_POSIX_MEMALIGN
00066     if (posix_memalign(&ptr,16,size))
00067         ptr = NULL;
00068 #elif HAVE_MEMALIGN
00069     ptr = memalign(16,size);
00070     /* Why 64?
00071        Indeed, we should align it:
00072          on 4 for 386
00073          on 16 for 486
00074          on 32 for 586, PPro - K6-III
00075          on 64 for K7 (maybe for P3 too).
00076        Because L1 and L2 caches are aligned on those values.
00077        But I don't want to code such logic here!
00078      */
00079      /* Why 16?
00080         Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
00081         it will just trigger an exception and the unaligned load will be done in the
00082         exception handler or it will just segfault (SSE2 on P4).
00083         Why not larger? Because I did not see a difference in benchmarks ...
00084      */
00085      /* benchmarks with P3
00086         memalign(64)+1          3071,3051,3032
00087         memalign(64)+2          3051,3032,3041
00088         memalign(64)+4          2911,2896,2915
00089         memalign(64)+8          2545,2554,2550
00090         memalign(64)+16         2543,2572,2563
00091         memalign(64)+32         2546,2545,2571
00092         memalign(64)+64         2570,2533,2558
00093 
00094         BTW, malloc seems to do 8-byte alignment by default here.
00095      */
00096 #else
00097     ptr = malloc(size);
00098 #endif
00099     return ptr;
00100 }
00101 
00102 void *av_realloc(void *ptr, unsigned int size)
00103 {
00104 #if CONFIG_MEMALIGN_HACK
00105     int diff;
00106 #endif
00107 
00108     /* let's disallow possible ambiguous cases */
00109     if(size > (INT_MAX-16) )
00110         return NULL;
00111 
00112 #if CONFIG_MEMALIGN_HACK
00113     //FIXME this isn't aligned correctly, though it probably isn't needed
00114     if(!ptr) return av_malloc(size);
00115     diff= ((char*)ptr)[-1];
00116     return (char*)realloc((char*)ptr - diff, size + diff) + diff;
00117 #else
00118     return realloc(ptr, size);
00119 #endif
00120 }
00121 
00122 void av_free(void *ptr)
00123 {
00124     /* XXX: this test should not be needed on most libcs */
00125     if (ptr)
00126 #if CONFIG_MEMALIGN_HACK
00127         free((char*)ptr - ((char*)ptr)[-1]);
00128 #else
00129         free(ptr);
00130 #endif
00131 }
00132 
00133 void av_freep(void *arg)
00134 {
00135     void **ptr= (void**)arg;
00136     av_free(*ptr);
00137     *ptr = NULL;
00138 }
00139 
00140 void *av_mallocz(unsigned int size)
00141 {
00142     void *ptr = av_malloc(size);
00143     if (ptr)
00144         memset(ptr, 0, size);
00145     return ptr;
00146 }
00147 
00148 char *av_strdup(const char *s)
00149 {
00150     char *ptr= NULL;
00151     if(s){
00152         int len = strlen(s) + 1;
00153         ptr = av_malloc(len);
00154         if (ptr)
00155             memcpy(ptr, s, len);
00156     }
00157     return ptr;
00158 }
00159 

Generated on Tue Nov 4 2014 12:59:24 for ffmpeg by  doxygen 1.7.1