mirror of
https://github.com/google/cpu_features.git
synced 2025-05-02 17:23:36 +02:00
parent
24b8a1de17
commit
eb59787849
23
README.md
23
README.md
@ -8,6 +8,7 @@ instructions) at runtime.
|
|||||||
- [Design Rationale](#rationale)
|
- [Design Rationale](#rationale)
|
||||||
- [Code samples](#codesample)
|
- [Code samples](#codesample)
|
||||||
- [Running sample code](#usagesample)
|
- [Running sample code](#usagesample)
|
||||||
|
- [Mocking the library](#mock)
|
||||||
- [What's supported](#support)
|
- [What's supported](#support)
|
||||||
- [Android NDK's drop in replacement](#ndk)
|
- [Android NDK's drop in replacement](#ndk)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
@ -130,6 +131,28 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
|
|||||||
{"arch":"x86","brand":" Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz","family":6,"model":45,"stepping":7,"uarch":"INTEL_SNB","flags":["aes","avx","cx16","smx","sse4_1","sse4_2","ssse3"]}
|
{"arch":"x86","brand":" Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz","family":6,"model":45,"stepping":7,"uarch":"INTEL_SNB","flags":["aes","avx","cx16","smx","sse4_1","sse4_2","ssse3"]}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a name="mock"></a>
|
||||||
|
### Mocking the library
|
||||||
|
|
||||||
|
When testing code depending on `cpu_features` it may be interesting to disable
|
||||||
|
support for a particular extension (e.g. test `sse4` support on a `Skylake`
|
||||||
|
machine).
|
||||||
|
|
||||||
|
It is easily done by setting up an interceptor callback.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
TEST(X86Test, TestOnlySSE4) {
|
||||||
|
RegisterX86InfoInterceptor([](X86Info* info) {
|
||||||
|
info->features = X86Features{};
|
||||||
|
info->features.sse4 = true;
|
||||||
|
});
|
||||||
|
// 1. Call code that uses GetX86Info(),
|
||||||
|
// 2. Check the expected values,
|
||||||
|
// 3. Don't forget to cancel.
|
||||||
|
RegisterX86InfoInterceptor(NULL);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
<a name="support"></a>
|
<a name="support"></a>
|
||||||
## What's supported
|
## What's supported
|
||||||
|
|
||||||
|
@ -140,4 +140,22 @@
|
|||||||
#define CPU_FEATURES_COMPILED_MIPS_MSA defined(__mips_msa)
|
#define CPU_FEATURES_COMPILED_MIPS_MSA defined(__mips_msa)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Miscellaneous
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef thread_local
|
||||||
|
#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
|
||||||
|
#define thread_local _Thread_local
|
||||||
|
#elif defined _WIN32 && (defined _MSC_VER || defined __ICL || \
|
||||||
|
defined __DMC__ || defined __BORLANDC__)
|
||||||
|
#define thread_local __declspec(thread)
|
||||||
|
/* note that ICC (linux) and Clang are covered by __GNUC__ */
|
||||||
|
#elif defined __GNUC__ || defined __SUNPRO_C || defined __xlC__
|
||||||
|
#define thread_local __thread
|
||||||
|
#else
|
||||||
|
#error "Cannot define thread_local"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
|
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
|
||||||
|
@ -201,6 +201,8 @@ const char* GetX86FeaturesEnumName(X86FeaturesEnum);
|
|||||||
|
|
||||||
const char* GetX86MicroarchitectureName(X86Microarchitecture);
|
const char* GetX86MicroarchitectureName(X86Microarchitecture);
|
||||||
|
|
||||||
|
void RegisterX86InfoInterceptor(void (*)(X86Info*));
|
||||||
|
|
||||||
CPU_FEATURES_END_CPP_NAMESPACE
|
CPU_FEATURES_END_CPP_NAMESPACE
|
||||||
|
|
||||||
#if !defined(CPU_FEATURES_ARCH_X86)
|
#if !defined(CPU_FEATURES_ARCH_X86)
|
||||||
|
@ -23,6 +23,12 @@
|
|||||||
#error "Cannot compile cpuinfo_x86 on a non x86 platform."
|
#error "Cannot compile cpuinfo_x86 on a non x86 platform."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
thread_local void (*X86InfoInterceptor)(X86Info*) = NULL;
|
||||||
|
|
||||||
|
void RegisterX86InfoInterceptor(void (*ptr)(X86Info*)) {
|
||||||
|
X86InfoInterceptor = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Definitions for CpuId and GetXCR0Eax.
|
// Definitions for CpuId and GetXCR0Eax.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -615,6 +621,7 @@ X86Info GetX86Info(void) {
|
|||||||
if (IsVendor(leaf_0, "GenuineIntel") || IsVendor(leaf_0, "AuthenticAMD")) {
|
if (IsVendor(leaf_0, "GenuineIntel") || IsVendor(leaf_0, "AuthenticAMD")) {
|
||||||
ParseCpuId(max_cpuid_leaf, &info);
|
ParseCpuId(max_cpuid_leaf, &info);
|
||||||
}
|
}
|
||||||
|
if (X86InfoInterceptor) X86InfoInterceptor(&info);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +101,26 @@ TEST(CpuidX86Test, SandyBridge) {
|
|||||||
EXPECT_FALSE(features.rdrnd);
|
EXPECT_FALSE(features.rdrnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CpuidX86Test, ForgingCpuWithInterceptor) {
|
||||||
|
RegisterX86InfoInterceptor([](X86Info* info) {
|
||||||
|
memcpy(info->vendor, "TEST", sizeof("TEST"));
|
||||||
|
info->features = X86Features{};
|
||||||
|
info->features.erms = true;
|
||||||
|
});
|
||||||
|
const auto info = GetX86Info();
|
||||||
|
EXPECT_STREQ(info.vendor, "GenuineIntel");
|
||||||
|
|
||||||
|
const auto& features = info.features;
|
||||||
|
for (size_t i = 0; i < X86_LAST_; ++i)
|
||||||
|
if (i == X86_ERMS)
|
||||||
|
EXPECT_TRUE(GetX86FeaturesEnumValue(&features, (X86FeaturesEnum)i));
|
||||||
|
else
|
||||||
|
EXPECT_FALSE(GetX86FeaturesEnumValue(&features, (X86FeaturesEnum)i));
|
||||||
|
|
||||||
|
RegisterX86InfoInterceptor(NULL);
|
||||||
|
EXPECT_STREQ(GetX86Info().vendor, "GenuineIntel");
|
||||||
|
}
|
||||||
|
|
||||||
const int KiB = 1024;
|
const int KiB = 1024;
|
||||||
const int MiB = 1024 * KiB;
|
const int MiB = 1024 * KiB;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user