Commit 8edd2286 authored by Frank Barchard's avatar Frank Barchard Committed by Commit Bot

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: 's avatarCheng Wang <wangcheng@google.com>
parent 651ccc0c
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment