# HG changeset patch # User lucabe # Date 1153294138 0 # Node ID 8fb151c4d4c74ce8c52d02029592af6dda12a49f # Parent 5cfa773a3bddf084d61bd534722df2b9c7f2df33 Move av_malloc(), av_realloc(), and av_free() from libavcodec to libavutil diff -r 5cfa773a3bdd -r 8fb151c4d4c7 Makefile --- a/Makefile Tue Jul 18 11:00:55 2006 +0000 +++ b/Makefile Wed Jul 19 07:28:58 2006 +0000 @@ -14,7 +14,8 @@ md5.o \ lls.o \ adler32.o \ - log.o + log.o \ + mem.o \ HEADERS = avutil.h common.h mathematics.h integer.h rational.h \ intfloat_readwrite.h md5.h adler32.h diff -r 5cfa773a3bdd -r 8fb151c4d4c7 common.h --- a/common.h Tue Jul 18 11:00:55 2006 +0000 +++ b/common.h Wed Jul 19 07:28:58 2006 +0000 @@ -355,4 +355,9 @@ #define STOP_TIMER(id) {} #endif +/* memory */ +void *av_malloc(unsigned int size); +void *av_realloc(void *ptr, unsigned int size); +void av_free(void *ptr); + #endif /* COMMON_H */ diff -r 5cfa773a3bdd -r 8fb151c4d4c7 mem.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mem.c Wed Jul 19 07:28:58 2006 +0000 @@ -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 +#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 +} +