Chromium Code Reviews| Index: base/cpu.cc |
| diff --git a/base/cpu.cc b/base/cpu.cc |
| index d6976bab33b316aed50e3a133edf1a7e8a060a97..6191d1fc829dc4f42a6ac6cf64c2da7cc9bf28d7 100644 |
| --- a/base/cpu.cc |
| +++ b/base/cpu.cc |
| @@ -11,6 +11,15 @@ |
| #include "build/build_config.h" |
| #if defined(ARCH_CPU_X86_FAMILY) |
| +#if defined(OS_LINUX) |
| +#include <stdio.h> |
| +#endif |
| + |
| +#if defined (OS_MACOSX) |
| +#include <sys/param.h> |
| +#include <sys/sysctl.h> |
| +#endif |
| + |
| #if defined(_MSC_VER) |
| #include <intrin.h> |
| #endif |
| @@ -32,6 +41,7 @@ CPU::CPU() |
| has_ssse3_(false), |
| has_sse41_(false), |
| has_sse42_(false), |
| + has_avx_(false), |
| cpu_vendor_("unknown") { |
| Initialize(); |
| } |
| @@ -81,6 +91,72 @@ void __cpuidex(int cpu_info[4], int info_type, int info_index) { |
| #endif |
| #endif // _MSC_VER |
| + |
| +#if defined(OS_WIN) |
| +bool OSHasAVXSupport() { |
| + OSVERSIONINFO version_info; |
| + |
| + if (GetVersionEx(&version_info)) |
|
apatrick_chromium
2013/03/06 02:02:28
Youu mean this?
if (!GetVersionEx(&version_info))
|
| + return false; |
| + |
| + // Windows 7 SP1 added support for AVX. |
| + return version_info.dwMajorVersion >= 6 && version_info.dwMinorVersion > 1; |
|
apatrick_chromium
2013/03/06 02:02:28
This won't work for 7.0 and 7.1 if the major versi
|
| +} |
| +#elif defined(OS_LINUX) |
| +bool OSHasAVXSupport() { |
| + FILE* f = fopen("/proc/cpuinfo", "r"); |
|
apatrick_chromium
2013/03/06 02:02:28
I think you can use file_util::ReadFileToString he
|
| + if (!f) |
| + return false; |
| + |
| + // Scan through /proc/cpuinfo to see if the kernel supports AVX. |
| + char buffer[4096]; |
| + while (fgets(buffer, (int)sizeof(buffer), f)) { |
|
brettw
2013/03/06 04:53:36
Use C++ casts.
|
| + if (strncmp(buffer, "flags", sizeof(buffer))) { |
| + if (strstr(buffer, "avx")) { |
|
apatrick_chromium
2013/03/06 02:02:28
Does /proc/cpuinfo reflect whether the OS has AVX
|
| + fclose(f); |
| + return true; |
| + } |
| + } |
| + } |
| + |
| + fclose(f); |
| + return false; |
| +} |
| +#elif defined(OS_MACOSX) |
| +bool OSHasAVXSupport() { |
| + size_t length; |
| + char* kernelVersion; |
|
apatrick_chromium
2013/03/06 02:02:28
nit: not chrome style
|
| + static int mib[2] = { CTL_KERN, KERN_OSRELEASE }; |
| + |
| + if (sysctl(mib, 2, NULL, &length, NULL, 0) < 0) |
| + return false; |
| + |
| + kernel_version = new char[length]; |
|
apatrick_chromium
2013/03/06 02:02:28
scoped_ptr<char[]>
|
| + if (!kernel_version) |
| + return false; |
| + |
| + if (sysctl(mib, 2, kernel_version, &length, NULL, 0) < 0) { |
| + delete [] kernel_version; |
|
apatrick_chromium
2013/03/06 02:02:28
not needed for scoped_ptr
|
| + return false; |
| + } |
| + |
| + int major, minor, patch_level; |
| + if (sscanf(kernel_version, "%d.%d.%d", &major, &minor, &patch_level) != 3) { |
|
apatrick_chromium
2013/03/06 02:02:28
check base/version.h. It can deal with version num
|
| + if (sscanf(kernel_version, "%d.%d", &major, &minor) != 2) { |
| + delete [] kernel_version; |
|
apatrick_chromium
2013/03/06 02:02:28
not needed for scoped_ptr
|
| + return false; |
| + } |
| + } |
| + free(kernelVersion); |
|
apatrick_chromium
2013/03/06 02:02:28
kernelVersion is uninitialized
|
| + |
| + // AVX support was added in 10.6.8, which has kernel 10.8. |
| + return major >= 10 && minor >= 8; |
|
apatrick_chromium
2013/03/06 02:02:28
This won't work for 11.0 through 11.7.
|
| +} |
| +#else |
| +bool OSHasAVXSupport() { |
| + return false; |
|
brettw
2013/03/06 04:53:36
indent.
|
| +} |
| +#endif |
| #endif // ARCH_CPU_X86_FAMILY |
| void CPU::Initialize() { |
| @@ -117,7 +193,7 @@ void CPU::Initialize() { |
| has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; |
| has_sse41_ = (cpu_info[2] & 0x00080000) != 0; |
| has_sse42_ = (cpu_info[2] & 0x00100000) != 0; |
| - has_avx_ = (cpu_info[2] & 0x10000000) != 0; |
| + has_avx_ = (cpu_info[2] & 0x10000000) != 0 && OSHasAVXSupport(); |
| } |
| // Get the brand string of the cpu. |