[Ffmpeg-devel] [Patch] aligned av_realloc

Hervé W. H.O.W.aka.V+ffmpeg
Fri Jul 21 14:23:00 CEST 2006


Hi,

On 30/06/06, Herv? W. wrote:
> The changes:
> for the case memalign-hack:
> *changed the type of 'diff' from int to long. In this patch diff gets
> used in exactly the same way as in av_malloc and per r4911: "long is
> better than int for pointer differences"
>
> *ptr is reallocated. If the data isn't aligned, it gets moved in the
> allocated space, and diff is updated.
>
> with memalign:
> *memalign is called, the original data is copied and the old ptr is
> av_free'd.

[...]

> without hack or memalign:
> *as regular realloc. The memalign hack isn't needed (or wanted), nor
> is memalign, therefore malloc is aligned on 16 (or does not need to
> be?) and, presumably, the same applies to realloc.

The previous patch had some mistakes.

-V
-------------- next part --------------
Index: libavutil/mem.c
===================================================================
--- libavutil/mem.c	(revision 5808)
+++ libavutil/mem.c	(working copy)
@@ -101,8 +101,9 @@
  */
 void *av_realloc(void *ptr, unsigned int size)
 {
+    void *old_ptr;
 #ifdef MEMALIGN_HACK
-    int diff;
+    long  diff;
 #endif
 
     /* let's disallow possible ambiguous cases */
@@ -110,11 +111,54 @@
         return NULL;
 
 #ifdef MEMALIGN_HACK
-    //FIXME this isn't aligned correctly, though it probably isn't needed
+    /* this should now be aligned correctly to 16 */
     if(!ptr) return av_malloc(size);
     diff= ((char*)ptr)[-1];
-    return realloc(ptr - diff, size + diff) + diff;
-#else
+    old_ptr = ptr;
+    ptr -= diff;
+
+    ptr = realloc(ptr, size+16);
+    if(!ptr)
+    {
+        ptr = old_ptr;
+        return NULL;
+    }
+    if( ( ((-(long)ptr - 1)&15) + 1) == diff )
+        return (ptr += diff);
+
+    old_ptr = ptr + diff;   /* old_ptr points to the start of the (not aligned) data */
+    diff= ((-(long)ptr - 1)&15) + 1;
+    ptr += diff;            /* ptr points to where the start of the (aligned) data will be*/
+
+    memmove(ptr, old_ptr, size);
+    ((char*)ptr)[-1]= diff;
+    return ptr;
+#elif defined (HAVE_MEMALIGN)
+    old_ptr = ptr;
+
+    ptr = realloc(ptr, size);       //  realloc, so that ptr points to allocated
+    if(!ptr)                        //  memory of the desired size, if realloc
+    {                               //  is possible
+        ptr = old_ptr;
+        return NULL;
+    }
+    if( !(((long)ptr)&15) )         //  if lucky, it's already aligned
+        return (ptr);
+
+    old_ptr = ptr;                  //  if it isn't aligned
+    ptr = memalign(16,size);        //  allocate a new aligned block of memory
+    if(!ptr)                        //  if possible
+    {
+        ptr = old_ptr;
+        return NULL;
+    }
+    memcpy(ptr, old_ptr, size);     //  and move the memory there
+
+    av_free(old_ptr);
+    return ptr;
+#else   /*  the memalign hack isn't needed, nor is memalign, therefore malloc is
+            aligned on 16 (or does not need to be?) and, presumably,
+            the same applies to realloc */
     return realloc(ptr, size);
 #endif
 }



More information about the ffmpeg-devel mailing list