diff options
author | Luca Abeni <lucabe72@email.it> | 2006-07-19 07:28:58 +0000 |
---|---|---|
committer | Luca Abeni <lucabe72@email.it> | 2006-07-19 07:28:58 +0000 |
commit | cea8f6f323d661b5412d9cc3d1be6d3026f1b213 (patch) | |
tree | c43e068722f937ff7b4fd01baa621b7bce06e73b /libavutil/mem.c | |
parent | b8889ea51f763c71a7cfadb5ec11e6e200ce8de5 (diff) | |
download | ffmpeg-cea8f6f323d661b5412d9cc3d1be6d3026f1b213.tar.gz |
Move av_malloc(), av_realloc(), and av_free() from libavcodec to libavutil
Originally committed as revision 5784 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavutil/mem.c')
-rw-r--r-- | libavutil/mem.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/libavutil/mem.c b/libavutil/mem.c new file mode 100644 index 0000000000..440328b7f1 --- /dev/null +++ b/libavutil/mem.c @@ -0,0 +1,137 @@ +/* + * default memory allocator for libavutil + * Copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file mem.c + * default memory allocator for libavutil. + */ + +#include "common.h" + +/* here we can use OS dependant allocation functions */ +#undef malloc +#undef free +#undef realloc + +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +/* you can redefine av_malloc and av_free in your project to use your + memory allocator. You do not need to suppress this file because the + linker will do it automatically */ + +/** + * Memory allocation of size byte with alignment suitable for all + * memory accesses (including vectors if available on the + * CPU). av_malloc(0) must return a non NULL pointer. + */ +void *av_malloc(unsigned int size) +{ + void *ptr; +#ifdef MEMALIGN_HACK + long diff; +#endif + + /* let's disallow possible ambiguous cases */ + if(size > (INT_MAX-16) ) + return NULL; + +#ifdef MEMALIGN_HACK + ptr = malloc(size+16); + if(!ptr) + return ptr; + diff= ((-(long)ptr - 1)&15) + 1; + ptr += diff; + ((char*)ptr)[-1]= diff; +#elif defined (HAVE_MEMALIGN) + ptr = memalign(16,size); + /* Why 64? + Indeed, we should align it: + on 4 for 386 + on 16 for 486 + on 32 for 586, PPro - k6-III + on 64 for K7 (maybe for P3 too). + Because L1 and L2 caches are aligned on those values. + But I don't want to code such logic here! + */ + /* Why 16? + because some cpus need alignment, for example SSE2 on P4, & most RISC cpus + it will just trigger an exception and the unaligned load will be done in the + exception handler or it will just segfault (SSE2 on P4) + Why not larger? because i didnt see a difference in benchmarks ... + */ + /* benchmarks with p3 + memalign(64)+1 3071,3051,3032 + memalign(64)+2 3051,3032,3041 + memalign(64)+4 2911,2896,2915 + memalign(64)+8 2545,2554,2550 + memalign(64)+16 2543,2572,2563 + memalign(64)+32 2546,2545,2571 + memalign(64)+64 2570,2533,2558 + + btw, malloc seems to do 8 byte alignment by default here + */ +#else + ptr = malloc(size); +#endif + return ptr; +} + +/** + * av_realloc semantics (same as glibc): if ptr is NULL and size > 0, + * identical to malloc(size). If size is zero, it is identical to + * free(ptr) and NULL is returned. + */ +void *av_realloc(void *ptr, unsigned int size) +{ +#ifdef MEMALIGN_HACK + int diff; +#endif + + /* let's disallow possible ambiguous cases */ + if(size > (INT_MAX-16) ) + return NULL; + +#ifdef MEMALIGN_HACK + //FIXME this isn't aligned correctly, though it probably isn't needed + if(!ptr) return av_malloc(size); + diff= ((char*)ptr)[-1]; + return realloc(ptr - diff, size + diff) + diff; +#else + return realloc(ptr, size); +#endif +} + +/** + * Free memory which has been allocated with av_malloc(z)() or av_realloc(). + * NOTE: ptr = NULL is explicetly allowed + * Note2: it is recommended that you use av_freep() instead + */ +void av_free(void *ptr) +{ + /* XXX: this test should not be needed on most libcs */ + if (ptr) +#ifdef MEMALIGN_HACK + free(ptr - ((char*)ptr)[-1]); +#else + free(ptr); +#endif +} + |