]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/mem.c
Add LABEL_MANGLE() to export label symbols from inside asm blocks.
[ffmpeg] / libavutil / mem.c
index f43fb542073c0036b8bd0ac7e77c12ec17a739df..741450b53faad14df4067cc3f232c98d6955f815 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * default memory allocator for libavutil
 /*
  * default memory allocator for libavutil
- * Copyright (c) 2002 Fabrice Bellard.
+ * Copyright (c) 2002 Fabrice Bellard
  *
  * This file is part of FFmpeg.
  *
  *
  * This file is part of FFmpeg.
  *
  */
 
 /**
  */
 
 /**
- * @file mem.c
- * default memory allocator for libavutil.
+ * @file libavutil/mem.c
+ * default memory allocator for libavutil
  */
 
  */
 
-#include "common.h"
-
-/* here we can use OS dependant allocation functions */
-#undef malloc
-#undef free
-#undef realloc
+#include "config.h"
 
 
-#ifdef HAVE_MALLOC_H
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_MALLOC_H
 #include <malloc.h>
 #endif
 
 #include <malloc.h>
 #endif
 
-/* you can redefine av_malloc and av_free in your project to use your
+#include "mem.h"
+
+/* here we can use OS-dependent allocation functions */
+#undef free
+#undef malloc
+#undef realloc
+
+/* 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
    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 *av_malloc(unsigned int size)
 {
-    void *ptr;
-#ifdef CONFIG_MEMALIGN_HACK
+    void *ptr = NULL;
+#if CONFIG_MEMALIGN_HACK
     long diff;
 #endif
 
     long diff;
 #endif
 
@@ -55,31 +55,34 @@ void *av_malloc(unsigned int size)
     if(size > (INT_MAX-16) )
         return NULL;
 
     if(size > (INT_MAX-16) )
         return NULL;
 
-#ifdef CONFIG_MEMALIGN_HACK
+#if CONFIG_MEMALIGN_HACK
     ptr = malloc(size+16);
     if(!ptr)
         return ptr;
     diff= ((-(long)ptr - 1)&15) + 1;
     ptr = malloc(size+16);
     if(!ptr)
         return ptr;
     diff= ((-(long)ptr - 1)&15) + 1;
-    ptr += diff;
+    ptr = (char*)ptr + diff;
     ((char*)ptr)[-1]= 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
     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?
          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
         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
         memalign(64)+1          3071,3051,3032
         memalign(64)+2          3051,3032,3041
         memalign(64)+4          2911,2896,2915
@@ -88,7 +91,7 @@ void *av_malloc(unsigned int size)
         memalign(64)+32         2546,2545,2571
         memalign(64)+64         2570,2533,2558
 
         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);
      */
 #else
     ptr = malloc(size);
@@ -96,14 +99,9 @@ void *av_malloc(unsigned int size)
     return ptr;
 }
 
     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 *av_realloc(void *ptr, unsigned int size)
 {
-#ifdef CONFIG_MEMALIGN_HACK
+#if CONFIG_MEMALIGN_HACK
     int diff;
 #endif
 
     int diff;
 #endif
 
@@ -111,36 +109,27 @@ void *av_realloc(void *ptr, unsigned int size)
     if(size > (INT_MAX-16) )
         return NULL;
 
     if(size > (INT_MAX-16) )
         return NULL;
 
-#ifdef CONFIG_MEMALIGN_HACK
+#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];
     //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;
+    return (char*)realloc((char*)ptr - diff, size + diff) + diff;
 #else
     return realloc(ptr, size);
 #endif
 }
 
 #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)
 void av_free(void *ptr)
 {
     /* XXX: this test should not be needed on most libcs */
     if (ptr)
-#ifdef CONFIG_MEMALIGN_HACK
-        free(ptr - ((char*)ptr)[-1]);
+#if CONFIG_MEMALIGN_HACK
+        free((char*)ptr - ((char*)ptr)[-1]);
 #else
         free(ptr);
 #endif
 }
 
 #else
         free(ptr);
 #endif
 }
 
-/**
- * Frees memory and sets the pointer to NULL.
- * @param arg pointer to the pointer which should be freed
- */
 void av_freep(void *arg)
 {
     void **ptr= (void**)arg;
 void av_freep(void *arg)
 {
     void **ptr= (void**)arg;
@@ -150,9 +139,7 @@ void av_freep(void *arg)
 
 void *av_mallocz(unsigned int size)
 {
 
 void *av_mallocz(unsigned int size)
 {
-    void *ptr;
-
-    ptr = av_malloc(size);
+    void *ptr = av_malloc(size);
     if (ptr)
         memset(ptr, 0, size);
     return ptr;
     if (ptr)
         memset(ptr, 0, size);
     return ptr;
@@ -160,12 +147,13 @@ void *av_mallocz(unsigned int size)
 
 char *av_strdup(const char *s)
 {
 
 char *av_strdup(const char *s)
 {
-    char *ptr;
-    int len;
-    len = strlen(s) + 1;
-    ptr = av_malloc(len);
-    if (ptr)
-        memcpy(ptr, s, len);
+    char *ptr= NULL;
+    if(s){
+        int len = strlen(s) + 1;
+        ptr = av_malloc(len);
+        if (ptr)
+            memcpy(ptr, s, len);
+    }
     return ptr;
 }
 
     return ptr;
 }