]> code.delx.au - pulseaudio/commitdiff
cpu: Add CPU information to pa_core
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Tue, 14 Sep 2010 09:51:49 +0000 (15:21 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Thu, 23 Sep 2010 11:47:03 +0000 (17:17 +0530)
This retains CPU information (processor type and supported features) in
pa_core, so that this information can be used by modules at init time to
figure out what optimisations may be used.

src/Makefile.am
src/daemon/main.c
src/pulsecore/core.h
src/pulsecore/cpu-arm.c
src/pulsecore/cpu-arm.h
src/pulsecore/cpu-x86.c
src/pulsecore/cpu-x86.h
src/pulsecore/cpu.h [new file with mode: 0644]

index ef6419bff53c89bb8ddff33af79fb7b95b1aa61e..66757986fa0fc073cea57d421b05401e4918838a 100644 (file)
@@ -852,6 +852,7 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/resampler.c pulsecore/resampler.h \
                pulsecore/rtpoll.c pulsecore/rtpoll.h \
                pulsecore/sample-util.c pulsecore/sample-util.h \
+               pulsecore/cpu.h \
                pulsecore/cpu-arm.c pulsecore/cpu-arm.h \
                pulsecore/cpu-x86.c pulsecore/cpu-x86.h \
                pulsecore/svolume_c.c pulsecore/svolume_arm.c \
index 9bea2aee50ea51c65a2b51492ff6f8c2e592cf5c..0e7b54a51615727811c3ddd6d65806af79e94fde 100644 (file)
@@ -934,11 +934,6 @@ int main(int argc, char *argv[]) {
 
     pa_memtrap_install();
 
-    if (!getenv("PULSE_NO_SIMD")) {
-        pa_cpu_init_x86();
-        pa_cpu_init_arm();
-    }
-
     pa_assert_se(mainloop = pa_mainloop_new());
 
     if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
@@ -964,6 +959,14 @@ int main(int argc, char *argv[]) {
     c->server_type = conf->local_server_type;
 #endif
 
+    c->cpu_info.cpu_type = PA_CPU_UNDEFINED;
+    if (!getenv("PULSE_NO_SIMD")) {
+        if (pa_cpu_init_x86(&(c->cpu_info.flags.x86)))
+            c->cpu_info.cpu_type = PA_CPU_X86;
+        if (pa_cpu_init_arm(&(c->cpu_info.flags.arm)))
+            c->cpu_info.cpu_type = PA_CPU_ARM;
+    }
+
     pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
     pa_signal_new(SIGINT, signal_callback, c);
     pa_signal_new(SIGTERM, signal_callback, c);
index bfcea4f636104c03a30a118785b36e4a9b1175eb..6088f9155f9c3e97face34996d6086ab2721ccec 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <pulse/mainloop-api.h>
 #include <pulse/sample.h>
+#include <pulsecore/cpu.h>
 
 typedef struct pa_core pa_core;
 
@@ -169,6 +170,7 @@ struct pa_core {
     int realtime_priority;
 
     pa_server_type_t server_type;
+    pa_cpu_info cpu_info;
 
     /* hooks */
     pa_hook hooks[PA_CORE_HOOK_MAX];
index bf632f7aa7e04fbc0017a1ce098f5070f69cc6a8..1d0d76516798ad565824c15c738ac9ab2bd3380a 100644 (file)
@@ -80,12 +80,11 @@ static char *get_cpuinfo(void) {
 }
 #endif /* defined (__arm__) && defined (__linux__) */
 
-void pa_cpu_init_arm (void) {
+pa_bool_t pa_cpu_init_arm (pa_cpu_arm_flag_t *flags) {
 #if defined (__arm__)
 #if defined (__linux__)
     char *cpuinfo, *line;
     int arch;
-    pa_cpu_arm_flag_t flags = 0;
 
     /* We need to read the CPU flags from /proc/cpuinfo because there is no user
      * space support to get the CPU features. This only works on linux AFAIK. */
@@ -94,13 +93,15 @@ void pa_cpu_init_arm (void) {
         return;
     }
 
+    *flags = 0;
+
     /* get the CPU architecture */
     if ((line = get_cpuinfo_line (cpuinfo, "CPU architecture"))) {
         arch = strtoul (line, NULL, 0);
         if (arch >= 6)
-            flags |= PA_CPU_ARM_V6;
+            *flags |= PA_CPU_ARM_V6;
         if (arch >= 7)
-            flags |= PA_CPU_ARM_V7;
+            *flags |= PA_CPU_ARM_V7;
 
         pa_xfree(line);
     }
@@ -111,13 +112,13 @@ void pa_cpu_init_arm (void) {
 
         while ((current = pa_split_spaces (line, &state))) {
             if (!strcmp (current, "vfp"))
-                flags |= PA_CPU_ARM_VFP;
+                *flags |= PA_CPU_ARM_VFP;
             else if (!strcmp (current, "edsp"))
-                flags |= PA_CPU_ARM_EDSP;
+                *flags |= PA_CPU_ARM_EDSP;
             else if (!strcmp (current, "neon"))
-                flags |= PA_CPU_ARM_NEON;
+                *flags |= PA_CPU_ARM_NEON;
             else if (!strcmp (current, "vfpv3"))
-                flags |= PA_CPU_ARM_VFPV3;
+                *flags |= PA_CPU_ARM_VFPV3;
 
             pa_xfree(current);
         }
@@ -125,17 +126,23 @@ void pa_cpu_init_arm (void) {
     pa_xfree(cpuinfo);
 
     pa_log_info ("CPU flags: %s%s%s%s%s%s",
-          (flags & PA_CPU_ARM_V6) ? "V6 " : "",
-          (flags & PA_CPU_ARM_V7) ? "V7 " : "",
-          (flags & PA_CPU_ARM_VFP) ? "VFP " : "",
-          (flags & PA_CPU_ARM_EDSP) ? "EDSP " : "",
-          (flags & PA_CPU_ARM_NEON) ? "NEON " : "",
-          (flags & PA_CPU_ARM_VFPV3) ? "VFPV3 " : "");
+          (*flags & PA_CPU_ARM_V6) ? "V6 " : "",
+          (*flags & PA_CPU_ARM_V7) ? "V7 " : "",
+          (*flags & PA_CPU_ARM_VFP) ? "VFP " : "",
+          (*flags & PA_CPU_ARM_EDSP) ? "EDSP " : "",
+          (*flags & PA_CPU_ARM_NEON) ? "NEON " : "",
+          (*flags & PA_CPU_ARM_VFPV3) ? "VFPV3 " : "");
+
+    if (*flags & PA_CPU_ARM_V6)
+        pa_volume_func_init_arm (*flags);
+
+    return TRUE;
+
 #else /* defined (__linux__) */
     pa_log ("ARM cpu features not yet supported on this OS");
 #endif /* defined (__linux__) */
 
-    if (flags & PA_CPU_ARM_V6)
-        pa_volume_func_init_arm (flags);
+#else /* defined (__arm__) */
+    return FALSE;
 #endif /* defined (__arm__) */
 }
index a87cb63b4c940020e3d7f6f584d5f3c4be74e632..0e0c3e423bbcb5cb3734bdd315c271a418d769b1 100644 (file)
@@ -24,6 +24,7 @@
 ***/
 
 #include <stdint.h>
+#include <pulsecore/macro.h>
 
 typedef enum pa_cpu_arm_flag {
     PA_CPU_ARM_V6       = (1 << 0),
@@ -34,7 +35,7 @@ typedef enum pa_cpu_arm_flag {
     PA_CPU_ARM_VFPV3    = (1 << 5)
 } pa_cpu_arm_flag_t;
 
-void pa_cpu_init_arm (void);
+pa_bool_t pa_cpu_init_arm (pa_cpu_arm_flag_t *flags);
 
 /* some optimized functions */
 void pa_volume_func_init_arm(pa_cpu_arm_flag_t flags);
index b17307223261211c358d5b4215b2998df7160942..062a4c1bb3ec8867940a205fcd429cec682d8680 100644 (file)
@@ -46,11 +46,12 @@ get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
 }
 #endif
 
-void pa_cpu_init_x86 (void) {
+pa_bool_t pa_cpu_init_x86 (pa_cpu_x86_flag_t *flags) {
 #if defined (__i386__) || defined (__amd64__)
     uint32_t eax, ebx, ecx, edx;
     uint32_t level;
-    pa_cpu_x86_flag_t flags = 0;
+
+    *flags = 0;
 
     /* get standard level */
     get_cpuid (0x00000000, &level, &ebx, &ecx, &edx);
@@ -58,28 +59,28 @@ void pa_cpu_init_x86 (void) {
         get_cpuid (0x00000001, &eax, &ebx, &ecx, &edx);
 
         if (edx & (1<<15))
-          flags |= PA_CPU_X86_CMOV;
+          *flags |= PA_CPU_X86_CMOV;
 
         if (edx & (1<<23))
-          flags |= PA_CPU_X86_MMX;
+          *flags |= PA_CPU_X86_MMX;
 
         if (edx & (1<<25))
-          flags |= PA_CPU_X86_SSE;
+          *flags |= PA_CPU_X86_SSE;
 
         if (edx & (1<<26))
-          flags |= PA_CPU_X86_SSE2;
+          *flags |= PA_CPU_X86_SSE2;
 
         if (ecx & (1<<0))
-          flags |= PA_CPU_X86_SSE3;
+          *flags |= PA_CPU_X86_SSE3;
 
         if (ecx & (1<<9))
-          flags |= PA_CPU_X86_SSSE3;
+          *flags |= PA_CPU_X86_SSSE3;
 
         if (ecx & (1<<19))
-          flags |= PA_CPU_X86_SSE4_1;
+          *flags |= PA_CPU_X86_SSE4_1;
 
         if (ecx & (1<<20))
-          flags |= PA_CPU_X86_SSE4_2;
+          *flags |= PA_CPU_X86_SSE4_2;
     }
 
     /* get extended level */
@@ -88,42 +89,45 @@ void pa_cpu_init_x86 (void) {
         get_cpuid (0x80000001, &eax, &ebx, &ecx, &edx);
 
         if (edx & (1<<22))
-          flags |= PA_CPU_X86_MMXEXT;
+          *flags |= PA_CPU_X86_MMXEXT;
 
         if (edx & (1<<23))
-          flags |= PA_CPU_X86_MMX;
+          *flags |= PA_CPU_X86_MMX;
 
         if (edx & (1<<30))
-          flags |= PA_CPU_X86_3DNOWEXT;
+          *flags |= PA_CPU_X86_3DNOWEXT;
 
         if (edx & (1<<31))
-          flags |= PA_CPU_X86_3DNOW;
+          *flags |= PA_CPU_X86_3DNOW;
     }
 
     pa_log_info ("CPU flags: %s%s%s%s%s%s%s%s%s%s%s",
-    (flags & PA_CPU_X86_CMOV) ? "CMOV " : "",
-    (flags & PA_CPU_X86_MMX) ? "MMX " : "",
-    (flags & PA_CPU_X86_SSE) ? "SSE " : "",
-    (flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
-    (flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
-    (flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
-    (flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
-    (flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
-    (flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
-    (flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
-    (flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
+    (*flags & PA_CPU_X86_CMOV) ? "CMOV " : "",
+    (*flags & PA_CPU_X86_MMX) ? "MMX " : "",
+    (*flags & PA_CPU_X86_SSE) ? "SSE " : "",
+    (*flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
+    (*flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
+    (*flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
+    (*flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
+    (*flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
+    (*flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
+    (*flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
+    (*flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
 
     /* activate various optimisations */
-    if (flags & PA_CPU_X86_MMX) {
-        pa_volume_func_init_mmx (flags);
-        pa_remap_func_init_mmx (flags);
+    if (*flags & PA_CPU_X86_MMX) {
+        pa_volume_func_init_mmx (*flags);
+        pa_remap_func_init_mmx (*flags);
     }
 
-    if (flags & (PA_CPU_X86_SSE | PA_CPU_X86_SSE2)) {
-        pa_volume_func_init_sse (flags);
-        pa_remap_func_init_sse (flags);
-        pa_convert_func_init_sse (flags);
+    if (*flags & (PA_CPU_X86_SSE | PA_CPU_X86_SSE2)) {
+        pa_volume_func_init_sse (*flags);
+        pa_remap_func_init_sse (*flags);
+        pa_convert_func_init_sse (*flags);
     }
 
+    return TRUE;
+#else /* defined (__i386__) || defined (__amd64__) */
+    return FALSE;
 #endif /* defined (__i386__) || defined (__amd64__) */
 }
index 285c203186d75ef16a4f24a5d225d37431853881..0045ef6d963a22595d18e320c6947bc1c9ac38b5 100644 (file)
@@ -24,6 +24,7 @@
 ***/
 
 #include <stdint.h>
+#include <pulsecore/macro.h>
 
 typedef enum pa_cpu_x86_flag {
     PA_CPU_X86_MMX       = (1 << 0),
@@ -39,7 +40,7 @@ typedef enum pa_cpu_x86_flag {
     PA_CPU_X86_CMOV      = (1 << 10)
 } pa_cpu_x86_flag_t;
 
-void pa_cpu_init_x86 (void);
+pa_bool_t pa_cpu_init_x86 (pa_cpu_x86_flag_t *flags);
 
 #if defined (__i386__)
 typedef int32_t pa_reg_x86;
diff --git a/src/pulsecore/cpu.h b/src/pulsecore/cpu.h
new file mode 100644 (file)
index 0000000..7fe6f0b
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foocpuhfoo
+#define foocpuhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2010 Arun Raghavan
+
+  PulseAudio 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.
+
+  PulseAudio 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
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulsecore/cpu-x86.h>
+#include <pulsecore/cpu-arm.h>
+
+typedef enum {
+    PA_CPU_UNDEFINED = 0,
+    PA_CPU_X86,
+    PA_CPU_ARM,
+} pa_cpu_type_t;
+
+typedef struct pa_cpu_info pa_cpu_info;
+
+struct pa_cpu_info {
+    pa_cpu_type_t cpu_type;
+
+    union {
+        pa_cpu_x86_flag_t x86;
+        pa_cpu_arm_flag_t arm;
+    } flags;
+};
+
+#endif /* foocpuhfoo */