X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fcpu.c;h=5aef6af217c984484dcf8186236addf7446b458c;hb=820a4483af13cf6fd51f13638e57bcd1c3f629d4;hp=8c2cfb87cc43eda1b5d15e56bd7f424dffc3b7d4;hpb=b7b17ed66e199afc7246e642bf3b35c3f8eca217;p=ffmpeg diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 8c2cfb87cc4..5aef6af217c 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -16,7 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include +#include #include "cpu.h" #include "cpu_internal.h" @@ -42,34 +44,35 @@ #include #endif -static int cpuflags_mask = -1, checked; +static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1); -int av_get_cpu_flags(void) +static int get_cpu_flags(void) { - static int flags; - - if (checked) - return flags; - if (ARCH_AARCH64) - flags = ff_get_cpu_flags_aarch64(); + return ff_get_cpu_flags_aarch64(); if (ARCH_ARM) - flags = ff_get_cpu_flags_arm(); + return ff_get_cpu_flags_arm(); if (ARCH_PPC) - flags = ff_get_cpu_flags_ppc(); + return ff_get_cpu_flags_ppc(); if (ARCH_X86) - flags = ff_get_cpu_flags_x86(); - - flags &= cpuflags_mask; - checked = 1; + return ff_get_cpu_flags_x86(); + return 0; +} +int av_get_cpu_flags(void) +{ + int flags = atomic_load_explicit(&cpu_flags, memory_order_relaxed); + if (flags == -1) { + flags = get_cpu_flags(); + atomic_store_explicit(&cpu_flags, flags, memory_order_relaxed); + } return flags; } void av_set_cpu_flags_mask(int mask) { - cpuflags_mask = mask; - checked = 0; + atomic_store_explicit(&cpu_flags, get_cpu_flags() & mask, + memory_order_relaxed); } int av_parse_cpu_flags(const char *s) @@ -86,9 +89,12 @@ int av_parse_cpu_flags(const char *s) #define CPUFLAG_SSE4 (AV_CPU_FLAG_SSE4 | CPUFLAG_SSSE3) #define CPUFLAG_SSE42 (AV_CPU_FLAG_SSE42 | CPUFLAG_SSE4) #define CPUFLAG_AVX (AV_CPU_FLAG_AVX | CPUFLAG_SSE42) +#define CPUFLAG_AVXSLOW (AV_CPU_FLAG_AVXSLOW | CPUFLAG_AVX) #define CPUFLAG_XOP (AV_CPU_FLAG_XOP | CPUFLAG_AVX) +#define CPUFLAG_FMA3 (AV_CPU_FLAG_FMA3 | CPUFLAG_AVX) #define CPUFLAG_FMA4 (AV_CPU_FLAG_FMA4 | CPUFLAG_AVX) #define CPUFLAG_AVX2 (AV_CPU_FLAG_AVX2 | CPUFLAG_AVX) +#define CPUFLAG_BMI2 (AV_CPU_FLAG_BMI2 | AV_CPU_FLAG_BMI1) static const AVOption cpuflags_opts[] = { { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, #if ARCH_PPC @@ -106,9 +112,13 @@ int av_parse_cpu_flags(const char *s) { "sse4.1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE4 }, .unit = "flags" }, { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE42 }, .unit = "flags" }, { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX }, .unit = "flags" }, + { "avxslow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVXSLOW }, .unit = "flags" }, { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_XOP }, .unit = "flags" }, + { "fma3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA3 }, .unit = "flags" }, { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA4 }, .unit = "flags" }, { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX2 }, .unit = "flags" }, + { "bmi1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI1 }, .unit = "flags" }, + { "bmi2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_BMI2 }, .unit = "flags" }, { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOW }, .unit = "flags" }, { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT }, .unit = "flags" }, { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, @@ -117,9 +127,11 @@ int av_parse_cpu_flags(const char *s) { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" }, { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, + { "vfp_vm", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP_VM }, .unit = "flags" }, { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, #elif ARCH_AARCH64 + { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, #endif @@ -170,62 +182,14 @@ int av_cpu_count(void) return nb_cpus; } -#ifdef TEST - -#include - -static const struct { - int flag; - const char *name; -} cpu_flag_tab[] = { -#if ARCH_AARCH64 - { AV_CPU_FLAG_NEON, "neon" }, - { AV_CPU_FLAG_VFP, "vfp" }, -#elif ARCH_ARM - { AV_CPU_FLAG_ARMV5TE, "armv5te" }, - { AV_CPU_FLAG_ARMV6, "armv6" }, - { AV_CPU_FLAG_ARMV6T2, "armv6t2" }, - { AV_CPU_FLAG_VFP, "vfp" }, - { AV_CPU_FLAG_VFPV3, "vfpv3" }, - { AV_CPU_FLAG_NEON, "neon" }, -#elif ARCH_PPC - { AV_CPU_FLAG_ALTIVEC, "altivec" }, -#elif ARCH_X86 - { AV_CPU_FLAG_MMX, "mmx" }, - { AV_CPU_FLAG_MMXEXT, "mmxext" }, - { AV_CPU_FLAG_SSE, "sse" }, - { AV_CPU_FLAG_SSE2, "sse2" }, - { AV_CPU_FLAG_SSE2SLOW, "sse2(slow)" }, - { AV_CPU_FLAG_SSE3, "sse3" }, - { AV_CPU_FLAG_SSE3SLOW, "sse3(slow)" }, - { AV_CPU_FLAG_SSSE3, "ssse3" }, - { AV_CPU_FLAG_ATOM, "atom" }, - { AV_CPU_FLAG_SSE4, "sse4.1" }, - { AV_CPU_FLAG_SSE42, "sse4.2" }, - { AV_CPU_FLAG_AVX, "avx" }, - { AV_CPU_FLAG_XOP, "xop" }, - { AV_CPU_FLAG_FMA4, "fma4" }, - { AV_CPU_FLAG_3DNOW, "3dnow" }, - { AV_CPU_FLAG_3DNOWEXT, "3dnowext" }, - { AV_CPU_FLAG_CMOV, "cmov" }, - { AV_CPU_FLAG_AVX2, "avx2" }, -#endif - { 0 } -}; - -int main(void) +size_t av_cpu_max_align(void) { - int cpu_flags = av_get_cpu_flags(); - int i; + int flags = av_get_cpu_flags(); - printf("cpu_flags = 0x%08X\n", cpu_flags); - printf("cpu_flags ="); - for (i = 0; cpu_flag_tab[i].flag; i++) - if (cpu_flags & cpu_flag_tab[i].flag) - printf(" %s", cpu_flag_tab[i].name); - printf("\n"); + if (flags & AV_CPU_FLAG_AVX) + return 32; + if (flags & (AV_CPU_FLAG_ALTIVEC | AV_CPU_FLAG_SSE | AV_CPU_FLAG_NEON)) + return 16; - return 0; + return 8; } - -#endif