vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Fri Feb 3 18:36:04 2012 +0200| [5c35f9d1ff19be0ccd1229d2195e36bfa667454e] | committer: Rémi Denis-Courmont
Linux: parse /proc/cpuinfo instead of playing fork tricks > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5c35f9d1ff19be0ccd1229d2195e36bfa667454e --- src/Makefile.am | 1 + src/misc/cpu.c | 47 ++------------ src/posix/linux_cpu.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 42 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 6dc3384..492dcde 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -254,6 +254,7 @@ SOURCES_libvlc_linux = \ posix/filesystem.c \ posix/plugin.c \ posix/thread.c \ + posix/linux_cpu.c \ posix/linux_specific.c \ posix/rand.c \ $(NULL) diff --git a/src/misc/cpu.c b/src/misc/cpu.c index 7c28b25..d4e762c 100644 --- a/src/misc/cpu.c +++ b/src/misc/cpu.c @@ -32,7 +32,11 @@ #include <vlc_common.h> #include <vlc_cpu.h> +#include "libvlc.h" + +#include <assert.h> +#ifndef __linux__ #include <sys/types.h> #ifndef WIN32 #include <unistd.h> @@ -41,14 +45,11 @@ #else #include <errno.h> #endif -#include <assert.h> #ifdef __APPLE__ #include <sys/sysctl.h> #endif -#include "libvlc.h" - static uint32_t cpu_flags; #if defined (__i386__) || defined (__x86_64__) || defined (__powerpc__) \ @@ -284,45 +285,6 @@ void vlc_CPU_init (void) } out: -#elif defined (__arm__) - -# if defined (__ARM_NEON__) - i_capabilities |= CPU_CAPABILITY_NEON; -# elif defined (CAN_COMPILE_NEON) -# define NEED_RUNTIME_CPU_CHECK 1 -# endif - -# ifdef NEED_RUNTIME_CPU_CHECK -# if defined (__linux__) - FILE *info = fopen ("/proc/cpuinfo", "rt"); - if (info != NULL) - { - char *line = NULL; - size_t linelen = 0; - - while (getline (&line, &linelen, info) != -1) - { - const char *cap; - - if (strncmp (line, "Features\t:", 10)) - continue; - - /* TODO: detect other CPU features when we use them */ -# if defined (CAN_COMPILE_NEON) && !defined (__ARM_NEON__) - cap = strstr (line + 10, " neon"); - if (cap != NULL && (cap[5] == '\0' || cap[5] == ' ')) - i_capabilities |= CPU_CAPABILITY_NEON; -# endif - break; - } - fclose (info); - free (line); - } -# else -# warning Run-time CPU detection missing: optimizations disabled! -# endif -# endif - #elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __powerpc64__ ) \ || defined( __ppc64__ ) @@ -363,6 +325,7 @@ unsigned vlc_CPU (void) #endif return cpu_flags; } +#endif void vlc_CPU_dump (vlc_object_t *obj) { diff --git a/src/posix/linux_cpu.c b/src/posix/linux_cpu.c new file mode 100644 index 0000000..63f184e --- /dev/null +++ b/src/posix/linux_cpu.c @@ -0,0 +1,170 @@ +/***************************************************************************** + * linux_cpu.c: CPU detection code for Linux + ***************************************************************************** + * Copyright (C) 2012 Rémi Denis-Courmont + * + * This program 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.1 of the License, or + * (at your option) any later version. + * + * This program 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <vlc_common.h> +#include <vlc_cpu.h> + +#undef CPU_FLAGS +#if defined (__arm__) +# define CPU_FLAGS "Features\t:" + +#elif defined (__i386__) || defined (__x86_64__) +# define CPU_FLAGS "flags\t\t:" + +#elif defined (__powerpc__) || defined (__powerpc64__) +# define CPU_FLAGS "cpu\t\t:" + +#endif + +#ifdef CPU_FLAGS +static uint32_t cpu_flags = 0; + +static void vlc_CPU_init (void) +{ + FILE *info = fopen ("/proc/cpuinfo", "rt"); + if (info == NULL) + return; + + char *line = NULL; + size_t linelen = 0; + uint_fast32_t all_caps = 0xFFFFFFFF; + + while (getline (&line, &linelen, info) != -1) + { + if (strncmp (line, CPU_FLAGS, strlen (CPU_FLAGS))) + continue; + + char *p = line, *cap; + uint_fast32_t core_caps = 0; + + while ((cap = strsep (&p, " ")) != NULL) + { +#if defined (__arm__) +# ifndef __ARM_NEON__ + if (!strcmp (cap, "neon")) + core_caps |= CPU_CAPABILITY_NEON; +# endif + +#elif defined (__i386__) || defined (__x86_64__) +# ifndef __MMX__ + if (!strcmp (cap, "mmx")) + core_caps |= CPU_CAPABILITY_MMX; +# endif +# ifndef __SSE__ + if (!strcmp (cap, "sse")) + core_caps |= CPU_CAPABILITY_SSE | CPU_CAPABILITY_MMXEXT; + if (!strcmp (cap, "mmxext")) + core_caps |= CPU_CAPABILITY_MMXEXT; +# endif +# ifndef __SSE2__ + if (!strcmp (cap, "sse2")) + core_caps |= CPU_CAPABILITY_SSE2; +# endif +# ifndef __SSE3__ + if (!strcmp (cap, "pni")) + core_caps |= CPU_CAPABILITY_SSE3; +# endif +# ifndef __SSSE3__ + if (!strcmp (cap, "ssse3")) + core_caps |= CPU_CAPABILITY_SSSE3; +# endif +# ifndef __SSE4_1__ + if (!strcmp (cap, "sse4_1")) + core_caps |= CPU_CAPABILITY_SSE4_1; +# endif +# ifndef __SSE4_2__ + if (!strcmp (cap, "sse4_2")) + core_caps |= CPU_CAPABILITY_SSE4_1; +# endif +# ifndef __3dNOW__ + if (!strcmp (cap, "3dnow")) + core_caps |= CPU_CAPABILITY_3DNOW; +# endif + +#elif defined (__powerpc__) || defined (__powerpc64__) + if (!strcmp (cap, "altivec supported")) + core_caps |= CPU_CAPABILITY_ALTIVEC; +#endif + } + + /* Take the intersection of capabilities of each processor */ + all_caps &= core_caps; + } + fclose (info); + free (line); + + if (all_caps == 0xFFFFFFFF) /* Error parsing of cpuinfo? */ + all_caps = 0; /* Do not assume any capability! */ + + /* Always enable capabilities that were forced during compilation */ +#if defined (__arm__) +# ifdef __ARM_NEON__ + all_caps |= CPU_CAPABILITY_NEON; +# endif + +#elif defined (__i386__) || defined (__x86_64__) +# ifdef __MMX__ + all_caps |= CPU_CAPABILITY_MMX; +# endif +# ifdef __SSE__ + all_caps |= CPU_CAPABILITY_SSE | CPU_CAPABILITY_MMXEXT; +# endif +# ifdef __SSE2__ + all_caps |= CPU_CAPABILITY_SSE2; +# endif +# ifdef __SSE3__ + all_caps |= CPU_CAPABILITY_SSE3; +# endif +# ifdef __SSSE3__ + all_caps |= CPU_CAPABILITY_SSSE3; +# endif +# ifdef __SSE4_1__ + all_caps |= CPU_CAPABILITY_SSE4_1; +# endif +# ifdef __SSE4_2__ + all_caps |= CPU_CAPABILITY_SSE4_2; +# endif +# ifdef __3dNOW__ + all_caps |= CPU_CAPABILITY_3DNOW; +# endif + +#endif + cpu_flags = all_caps; +} + +unsigned vlc_CPU (void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + pthread_once (&once, vlc_CPU_init); + return cpu_flags; +} +#else /* CPU_FLAGS */ +unsigned vlc_CPU (void) +{ + return 0; +} +#endif _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
