X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fmem.c;h=8cad089a7db29d790ae707628602dde646eb48d0;hb=7918375f8873ba465fc08e2bc00769ab0360327a;hp=cdfefd605502c4c24e96c68b95fc97bdccf4bc66;hpb=732692d94cf3048799c848799ee601ffc2f768b0;p=ffmpeg diff --git a/libavutil/mem.c b/libavutil/mem.c index cdfefd60550..8cad089a7db 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -1,83 +1,105 @@ /* * default memory allocator for libavutil - * Copyright (c) 2002 Fabrice Bellard. + * Copyright (c) 2002 Fabrice Bellard * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg 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. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg 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 + * License along with FFmpeg; 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. + * @file + * default memory allocator for libavutil */ -#include "common.h" +#include "config.h" -/* here we can use OS dependant allocation functions */ -#undef malloc +#include +#include +#include +#if HAVE_MALLOC_H +#include +#endif + +#include "avutil.h" +#include "mem.h" + +/* here we can use OS-dependent allocation functions */ #undef free +#undef malloc #undef realloc -#ifdef HAVE_MALLOC_H -#include -#endif +#ifdef MALLOC_PREFIX -/* you can redefine av_malloc and av_free in your project to use your +#define malloc AV_JOIN(MALLOC_PREFIX, malloc) +#define memalign AV_JOIN(MALLOC_PREFIX, memalign) +#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign) +#define realloc AV_JOIN(MALLOC_PREFIX, realloc) +#define free AV_JOIN(MALLOC_PREFIX, free) + +void *malloc(size_t size); +void *memalign(size_t align, size_t size); +int posix_memalign(void **ptr, size_t align, size_t size); +void *realloc(void *ptr, size_t size); +void free(void *ptr); + +#endif /* MALLOC_PREFIX */ + +/* 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 */ + 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 + void *ptr = NULL; +#if CONFIG_MEMALIGN_HACK long diff; #endif /* let's disallow possible ambiguous cases */ - if(size > (INT_MAX-16) || !size) + if(size > (INT_MAX-16) ) return NULL; -#ifdef MEMALIGN_HACK +#if CONFIG_MEMALIGN_HACK ptr = malloc(size+16); if(!ptr) return ptr; diff= ((-(long)ptr - 1)&15) + 1; - ptr += diff; + ptr = (char*)ptr + diff; ((char*)ptr)[-1]= diff; -#elif defined (HAVE_MEMALIGN) +#elif HAVE_POSIX_MEMALIGN + if (posix_memalign(&ptr,16,size)) + ptr = NULL; +#elif 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 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 + 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 ... + exception handler or it will just segfault (SSE2 on P4). + Why not larger? Because I did not see a difference in benchmarks ... */ - /* benchmarks with p3 + /* benchmarks with P3 memalign(64)+1 3071,3051,3032 memalign(64)+2 3051,3032,3041 memalign(64)+4 2911,2896,2915 @@ -86,7 +108,7 @@ void *av_malloc(unsigned int size) memalign(64)+32 2546,2545,2571 memalign(64)+64 2570,2533,2558 - btw, malloc seems to do 8 byte alignment by default here + BTW, malloc seems to do 8-byte alignment by default here. */ #else ptr = malloc(size); @@ -94,48 +116,61 @@ void *av_malloc(unsigned int size) 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) { - void *ptr2; +#if CONFIG_MEMALIGN_HACK + int diff; +#endif /* let's disallow possible ambiguous cases */ if(size > (INT_MAX-16) ) return NULL; -#ifndef MEMALIGN_HACK - ptr= realloc(ptr, size); -assert(((int)((void*)0)&15) == 0); //for the null pointer pedants - if(!((int)ptr&15)) - return ptr; +#if CONFIG_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 (char*)realloc((char*)ptr - diff, size + diff) + diff; +#else + return realloc(ptr, size); #endif - - ptr2= av_malloc(size); - if(ptr && ptr2) - memcpy(ptr2, ptr, size); - if(ptr2 || !size) - av_free(ptr); - - return ptr2; } -/** - * 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]); +#if CONFIG_MEMALIGN_HACK + free((char*)ptr - ((char*)ptr)[-1]); #else free(ptr); #endif } +void av_freep(void *arg) +{ + void **ptr= (void**)arg; + av_free(*ptr); + *ptr = NULL; +} + +void *av_mallocz(unsigned int size) +{ + void *ptr = av_malloc(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +char *av_strdup(const char *s) +{ + char *ptr= NULL; + if(s){ + int len = strlen(s) + 1; + ptr = av_malloc(len); + if (ptr) + memcpy(ptr, s, len); + } + return ptr; +} +