Commit 9be6d21a authored by Frank Barchard's avatar Frank Barchard

write to cpu_flags once

To make init cpu flags thread safe, there can only be one write to the variable.

R=richard.winterton@intel.com, harryjin@google.com
BUG=libyuv:508

Review URL: https://codereview.chromium.org/1412793006 .
parent d99324dd
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1515 Version: 1516
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1515 #define LIBYUV_VERSION 1516
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
...@@ -198,7 +198,7 @@ static LIBYUV_BOOL TestEnv(const char*) { ...@@ -198,7 +198,7 @@ static LIBYUV_BOOL TestEnv(const char*) {
LIBYUV_API SAFEBUFFERS LIBYUV_API SAFEBUFFERS
int InitCpuFlags(void) { int InitCpuFlags(void) {
#if !defined(__pnacl__) && !defined(__CLR_VER) && defined(CPU_X86) #if !defined(__pnacl__) && !defined(__CLR_VER) && defined(CPU_X86)
int cpu_info;
uint32 cpu_info0[4] = { 0, 0, 0, 0 }; uint32 cpu_info0[4] = { 0, 0, 0, 0 };
uint32 cpu_info1[4] = { 0, 0, 0, 0 }; uint32 cpu_info1[4] = { 0, 0, 0, 0 };
uint32 cpu_info7[4] = { 0, 0, 0, 0 }; uint32 cpu_info7[4] = { 0, 0, 0, 0 };
...@@ -207,7 +207,7 @@ int InitCpuFlags(void) { ...@@ -207,7 +207,7 @@ int InitCpuFlags(void) {
if (cpu_info0[0] >= 7) { if (cpu_info0[0] >= 7) {
CpuId(7, 0, cpu_info7); CpuId(7, 0, cpu_info7);
} }
cpu_info_ = ((cpu_info1[3] & 0x04000000) ? kCpuHasSSE2 : 0) | cpu_info = ((cpu_info1[3] & 0x04000000) ? kCpuHasSSE2 : 0) |
((cpu_info1[2] & 0x00000200) ? kCpuHasSSSE3 : 0) | ((cpu_info1[2] & 0x00000200) ? kCpuHasSSSE3 : 0) |
((cpu_info1[2] & 0x00080000) ? kCpuHasSSE41 : 0) | ((cpu_info1[2] & 0x00080000) ? kCpuHasSSE41 : 0) |
((cpu_info1[2] & 0x00100000) ? kCpuHasSSE42 : 0) | ((cpu_info1[2] & 0x00100000) ? kCpuHasSSE42 : 0) |
...@@ -219,52 +219,51 @@ int InitCpuFlags(void) { ...@@ -219,52 +219,51 @@ int InitCpuFlags(void) {
// AVX requires CPU has AVX, XSAVE and OSXSave for xgetbv // AVX requires CPU has AVX, XSAVE and OSXSave for xgetbv
if ((cpu_info1[2] & 0x1c000000) == 0x1c000000 && // AVX and OSXSave if ((cpu_info1[2] & 0x1c000000) == 0x1c000000 && // AVX and OSXSave
!TestEnv("LIBYUV_DISABLE_AVX") && TestOsSaveYmm()) { // Saves YMM. !TestEnv("LIBYUV_DISABLE_AVX") && TestOsSaveYmm()) { // Saves YMM.
cpu_info_ |= ((cpu_info7[1] & 0x00000020) ? kCpuHasAVX2 : 0) | cpu_info |= ((cpu_info7[1] & 0x00000020) ? kCpuHasAVX2 : 0) | kCpuHasAVX;
kCpuHasAVX;
} }
#endif #endif
// Environment variable overrides for testing. // Environment variable overrides for testing.
if (TestEnv("LIBYUV_DISABLE_X86")) { if (TestEnv("LIBYUV_DISABLE_X86")) {
cpu_info_ &= ~kCpuHasX86; cpu_info &= ~kCpuHasX86;
} }
if (TestEnv("LIBYUV_DISABLE_SSE2")) { if (TestEnv("LIBYUV_DISABLE_SSE2")) {
cpu_info_ &= ~kCpuHasSSE2; cpu_info &= ~kCpuHasSSE2;
} }
if (TestEnv("LIBYUV_DISABLE_SSSE3")) { if (TestEnv("LIBYUV_DISABLE_SSSE3")) {
cpu_info_ &= ~kCpuHasSSSE3; cpu_info &= ~kCpuHasSSSE3;
} }
if (TestEnv("LIBYUV_DISABLE_SSE41")) { if (TestEnv("LIBYUV_DISABLE_SSE41")) {
cpu_info_ &= ~kCpuHasSSE41; cpu_info &= ~kCpuHasSSE41;
} }
if (TestEnv("LIBYUV_DISABLE_SSE42")) { if (TestEnv("LIBYUV_DISABLE_SSE42")) {
cpu_info_ &= ~kCpuHasSSE42; cpu_info &= ~kCpuHasSSE42;
} }
if (TestEnv("LIBYUV_DISABLE_AVX2")) { if (TestEnv("LIBYUV_DISABLE_AVX2")) {
cpu_info_ &= ~kCpuHasAVX2; cpu_info &= ~kCpuHasAVX2;
} }
if (TestEnv("LIBYUV_DISABLE_ERMS")) { if (TestEnv("LIBYUV_DISABLE_ERMS")) {
cpu_info_ &= ~kCpuHasERMS; cpu_info &= ~kCpuHasERMS;
} }
if (TestEnv("LIBYUV_DISABLE_FMA3")) { if (TestEnv("LIBYUV_DISABLE_FMA3")) {
cpu_info_ &= ~kCpuHasFMA3; cpu_info &= ~kCpuHasFMA3;
} }
#endif #endif
#if defined(__mips__) && defined(__linux__) #if defined(__mips__) && defined(__linux__)
// Linux mips parse text file for dsp detect. // Linux mips parse text file for dsp detect.
cpu_info_ = MipsCpuCaps("dsp"); // set kCpuHasMIPS_DSP. cpu_info = MipsCpuCaps("dsp"); // set kCpuHasMIPS_DSP.
#if defined(__mips_dspr2) #if defined(__mips_dspr2)
cpu_info_ |= kCpuHasMIPS_DSPR2; cpu_info |= kCpuHasMIPS_DSPR2;
#endif #endif
cpu_info_ |= kCpuHasMIPS; cpu_info |= kCpuHasMIPS;
if (getenv("LIBYUV_DISABLE_MIPS")) { if (getenv("LIBYUV_DISABLE_MIPS")) {
cpu_info_ &= ~kCpuHasMIPS; cpu_info &= ~kCpuHasMIPS;
} }
if (getenv("LIBYUV_DISABLE_MIPS_DSP")) { if (getenv("LIBYUV_DISABLE_MIPS_DSP")) {
cpu_info_ &= ~kCpuHasMIPS_DSP; cpu_info &= ~kCpuHasMIPS_DSP;
} }
if (getenv("LIBYUV_DISABLE_MIPS_DSPR2")) { if (getenv("LIBYUV_DISABLE_MIPS_DSPR2")) {
cpu_info_ &= ~kCpuHasMIPS_DSPR2; cpu_info &= ~kCpuHasMIPS_DSPR2;
} }
#endif #endif
#if defined(__arm__) || defined(__aarch64__) #if defined(__arm__) || defined(__aarch64__)
...@@ -272,28 +271,30 @@ int InitCpuFlags(void) { ...@@ -272,28 +271,30 @@ int InitCpuFlags(void) {
// __ARM_NEON__ generates code that requires Neon. NaCL also requires Neon. // __ARM_NEON__ generates code that requires Neon. NaCL also requires Neon.
// For Linux, /proc/cpuinfo can be tested but without that assume Neon. // For Linux, /proc/cpuinfo can be tested but without that assume Neon.
#if defined(__ARM_NEON__) || defined(__native_client__) || !defined(__linux__) #if defined(__ARM_NEON__) || defined(__native_client__) || !defined(__linux__)
cpu_info_ = kCpuHasNEON; cpu_info = kCpuHasNEON;
// For aarch64(arm64), /proc/cpuinfo's feature is not complete, e.g. no neon // For aarch64(arm64), /proc/cpuinfo's feature is not complete, e.g. no neon
// flag in it. // flag in it.
// So for aarch64, neon enabling is hard coded here. // So for aarch64, neon enabling is hard coded here.
#endif #endif
#if defined(__aarch64__) #if defined(__aarch64__)
cpu_info_ = kCpuHasNEON; cpu_info = kCpuHasNEON;
#else #else
// Linux arm parse text file for neon detect. // Linux arm parse text file for neon detect.
cpu_info_ = ArmCpuCaps("/proc/cpuinfo"); cpu_info = ArmCpuCaps("/proc/cpuinfo");
#endif #endif
cpu_info_ |= kCpuHasARM; cpu_info |= kCpuHasARM;
if (TestEnv("LIBYUV_DISABLE_NEON")) { if (TestEnv("LIBYUV_DISABLE_NEON")) {
cpu_info_ &= ~kCpuHasNEON; cpu_info &= ~kCpuHasNEON;
} }
#endif // __arm__ #endif // __arm__
if (TestEnv("LIBYUV_DISABLE_ASM")) { if (TestEnv("LIBYUV_DISABLE_ASM")) {
cpu_info_ = 0; cpu_info = 0;
} }
cpu_info_ = cpu_info;
return cpu_info_; return cpu_info_;
} }
// Note that use of this function is not thread safe.
LIBYUV_API LIBYUV_API
void MaskCpuFlags(int enable_flags) { void MaskCpuFlags(int enable_flags) {
cpu_info_ = InitCpuFlags() & enable_flags; cpu_info_ = InitCpuFlags() & enable_flags;
......
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