[FFmpeg-devel] Fix Altivec detection on Linux.

David Woodhouse dwmw2
Wed Mar 19 14:18:00 CET 2008


This patch should use /proc/$$/auxv to safely detect whether Altivec is
available.

I see we also build everything with -maltivec anyway, which with GCC now
doing autovectorisation means that we're likely to be using Altivec
anywhere, and this check is mostly pointless. 

We should stop doing that. If GCC is managing to autovectorise any C
code and it actually makes a significant difference, then we should
think about building those components twice -- once with -maltivec and
once without -- and putting the Altivec version in /lib/altivec where
the dynamic linker will find it on appropriate systems.

Index: libavcodec/ppc/check_altivec.c
===================================================================
--- libavcodec/ppc/check_altivec.c	(revision 12503)
+++ libavcodec/ppc/check_altivec.c	(working copy)
@@ -28,6 +28,14 @@
 #include <exec/exec.h>
 #include <interfaces/exec.h>
 #include <proto/exec.h>
+#elif __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <linux/auxvec.h>
+#include <asm/cputable.h>
 #endif /* __APPLE__ */
 
 /**
@@ -54,6 +62,45 @@
 
     if (err == 0) return (has_vu != 0);
     return 0;
+#elif __linux__
+    static int available = -1;
+    int new_avail = 0;
+    char fname[64];
+    unsigned long buf[64];
+    ssize_t count;
+    pid_t pid;
+    int fd, i;
+        
+    if (available != -1)
+	    return available;
+
+    pid = getpid();
+    snprintf(fname, sizeof(fname)-1, "/proc/%d/auxv", pid);
+
+    fd = open(fname, O_RDONLY);
+    if (fd < 0)
+	    goto out;
+ more:
+    count = read(fd, buf, sizeof(buf));
+    if (count < 0)
+	    goto out_close;
+
+    for (i=0; i < (count / sizeof(unsigned long)); i += 2) {
+	    if (buf[i] == AT_HWCAP) {
+		    new_avail = !!(buf[i+1] & PPC_FEATURE_HAS_ALTIVEC);
+		    goto out_close;
+	    } else if (buf[i] == AT_NULL) {
+		    goto out_close;
+	    }
+    }
+
+    if (count == sizeof(buf))
+	    goto more;
+ out_close:
+    close(fd);
+ out:
+    available = new_avail;
+    return available;
 #elif defined(RUNTIME_CPUDETECT)
     int proc_ver;
     // support of mfspr PVR emulation added in Linux 2.6.17

-- 
dwmw2





More information about the ffmpeg-devel mailing list