mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-01-01 03:12:16 +08:00
MaskCpuFlags return cpuinfo so InitCpuFlags can call it
Reduce number of atomic references to cpu_info by making InitCpuFlags call MaskCpuFlags and return the same value. BUG=libyuv:641 TEST=libyuv_unittests pass Change-Id: I5dfff8f7a10671bc8ef3ec0ed6f302791e752faa Reviewed-on: https://chromium-review.googlesource.com/514145 Commit-Queue: Frank Barchard <fbarchard@google.com> Reviewed-by: Cheng Wang <wangcheng@google.com>
This commit is contained in:
parent
651ccc0c3a
commit
8edd2286fd
@ -46,17 +46,14 @@ static const int kCpuHasMIPS = 0x10000;
|
||||
static const int kCpuHasDSPR2 = 0x20000;
|
||||
static const int kCpuHasMSA = 0x40000;
|
||||
|
||||
// Internal function used to auto-init.
|
||||
// Optional init function. TestCpuFlag does an auto-init.
|
||||
// Returns cpu_info flags.
|
||||
LIBYUV_API
|
||||
int InitCpuFlags(void);
|
||||
|
||||
// Internal function for parsing /proc/cpuinfo.
|
||||
LIBYUV_API
|
||||
int ArmCpuCaps(const char* cpuinfo_name);
|
||||
|
||||
// Detect CPU has SSE2 etc.
|
||||
// Test_flag parameter should be one of kCpuHas constants above.
|
||||
// returns non-zero if instruction set is detected
|
||||
// Returns non-zero if instruction set is detected
|
||||
static __inline int TestCpuFlag(int test_flag) {
|
||||
LIBYUV_API extern int cpu_info_;
|
||||
#ifdef __ATOMIC_RELAXED
|
||||
@ -67,12 +64,18 @@ static __inline int TestCpuFlag(int test_flag) {
|
||||
return (!cpu_info ? InitCpuFlags() : cpu_info) & test_flag;
|
||||
}
|
||||
|
||||
// Internal function for parsing /proc/cpuinfo.
|
||||
LIBYUV_API
|
||||
int ArmCpuCaps(const char* cpuinfo_name);
|
||||
|
||||
// For testing, allow CPU flags to be disabled.
|
||||
// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
|
||||
// MaskCpuFlags(-1) to enable all cpu specific optimizations.
|
||||
// MaskCpuFlags(1) to disable all cpu specific optimizations.
|
||||
// MaskCpuFlags(0) to reset state so next call will auto init.
|
||||
// Returns cpu_info flags.
|
||||
LIBYUV_API
|
||||
void MaskCpuFlags(int enable_flags);
|
||||
int MaskCpuFlags(int enable_flags);
|
||||
|
||||
// Low level cpuid for X86. Returns zeros on other CPUs.
|
||||
// eax is the info type that you want.
|
||||
|
||||
@ -46,6 +46,7 @@ extern "C" {
|
||||
// cpu_info_ variable for SIMD instruction sets detected.
|
||||
LIBYUV_API int cpu_info_ = 0;
|
||||
|
||||
// TODO(fbarchard): Consider using int for cpuid so casting is not needed.
|
||||
// Low level cpuid for X86.
|
||||
#if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
|
||||
defined(__x86_64__)) && \
|
||||
@ -55,7 +56,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
|
||||
#if defined(_MSC_VER)
|
||||
// Visual C version uses intrinsic or inline x86 assembly.
|
||||
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219)
|
||||
__cpuidex((int*)(cpu_info), info_eax, info_ecx);
|
||||
__cpuidex((int*)(cpu_info), info_eax, info_ecx); // NOLINT
|
||||
#elif defined(_M_IX86)
|
||||
__asm {
|
||||
mov eax, info_eax
|
||||
@ -69,7 +70,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
|
||||
}
|
||||
#else // Visual C but not x86
|
||||
if (info_ecx == 0) {
|
||||
__cpuid((int*)(cpu_info), info_eax);
|
||||
__cpuid((int*)(cpu_info), info_eax); // NOLINT
|
||||
} else {
|
||||
cpu_info[3] = cpu_info[2] = cpu_info[1] = cpu_info[0] = 0u;
|
||||
}
|
||||
@ -122,8 +123,9 @@ void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info) {
|
||||
// X86 CPUs have xgetbv to detect OS saves high parts of ymm registers.
|
||||
int GetXCR0() {
|
||||
uint32 xcr0 = 0u;
|
||||
// VS2010 SP1 required
|
||||
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219)
|
||||
xcr0 = (uint32)(_xgetbv(0)); // VS2010 SP1 required.
|
||||
xcr0 = (uint32)(_xgetbv(0)); // NOLINT
|
||||
#elif defined(__i386__) || defined(__x86_64__)
|
||||
asm(".byte 0x0f, 0x01, 0xd0" : "=a"(xcr0) : "c"(0) : "%edx");
|
||||
#endif // defined(__i386__) || defined(__x86_64__)
|
||||
@ -170,7 +172,7 @@ LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) {
|
||||
LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name,
|
||||
const char ase[]) {
|
||||
char cpuinfo_line[512];
|
||||
int len = (int)strlen(ase);
|
||||
int len = (int)strlen(ase); // NOLINT
|
||||
FILE* f = fopen(cpuinfo_name, "r");
|
||||
if (!f) {
|
||||
// ase enabled if /proc/cpuinfo is unavailable.
|
||||
@ -325,22 +327,19 @@ static SAFEBUFFERS int GetCpuFlags(void) {
|
||||
|
||||
// Note that use of this function is not thread safe.
|
||||
LIBYUV_API
|
||||
void MaskCpuFlags(int enable_flags) {
|
||||
int MaskCpuFlags(int enable_flags) {
|
||||
int cpu_info = GetCpuFlags() & enable_flags;
|
||||
#ifdef __ATOMIC_RELAXED
|
||||
__atomic_store_n(&cpu_info_, GetCpuFlags() & enable_flags, __ATOMIC_RELAXED);
|
||||
__atomic_store_n(&cpu_info_, cpu_info, __ATOMIC_RELAXED);
|
||||
#else
|
||||
cpu_info_ = GetCpuFlags() & enable_flags;
|
||||
cpu_info_ = cpu_info;
|
||||
#endif
|
||||
return cpu_info;
|
||||
}
|
||||
|
||||
LIBYUV_API
|
||||
int InitCpuFlags(void) {
|
||||
MaskCpuFlags(-1);
|
||||
#ifdef __ATOMIC_RELAXED
|
||||
return __atomic_load_n(&cpu_info_, __ATOMIC_RELAXED);
|
||||
#else
|
||||
return cpu_info_;
|
||||
#endif
|
||||
return MaskCpuFlags(-1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -12,8 +12,11 @@
|
||||
|
||||
#include "libyuv/cpu_id.h"
|
||||
|
||||
// TODO(fbarchard): Port to other platforms
|
||||
#if defined(__linux__)
|
||||
#if defined(__clang__)
|
||||
#if __has_include(<pthread.h>)
|
||||
#define LIBYUV_HAVE_PTHREAD 1
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#define LIBYUV_HAVE_PTHREAD 1
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user