mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
cpu: Add CPU information to pa_core
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.
This commit is contained in:
parent
ffcf3c8a6c
commit
ab4223e9cf
8 changed files with 119 additions and 55 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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__) */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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__) */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
45
src/pulsecore/cpu.h
Normal file
45
src/pulsecore/cpu.h
Normal file
|
|
@ -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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue