1
0
mirror of https://github.com/google/cpu_features.git synced 2025-07-01 05:11:15 +02:00

Adding code. Closes #0.

This commit is contained in:
Guillaume Chatelet
2018-02-01 10:03:09 +01:00
parent 44d56a0a28
commit 439d371594
47 changed files with 4559 additions and 6 deletions

View File

@ -0,0 +1,121 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
////////////////////////////////////////////////////////////////////////////////
// Architectures
////////////////////////////////////////////////////////////////////////////////
#if ((defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
defined(__x86_64__)) && \
!defined(__pnacl__) && !defined(__CLR_VER))
#define CPU_FEATURES_ARCH_X86
#endif
#if (defined(__arm__) || defined(_M_ARM))
#define CPU_FEATURES_ARCH_ARM
#endif
#if defined(__aarch64__)
#define CPU_FEATURES_ARCH_AARCH64
#endif
#if (defined(CPU_FEATURES_ARCH_AARCH64) || defined(CPU_FEATURES_ARCH_ARM))
#define CPU_FEATURES_ARCH_ANY_ARM
#endif
#if defined(__mips__)
#define CPU_FEATURES_ARCH_MIPS
#endif
////////////////////////////////////////////////////////////////////////////////
// Os
////////////////////////////////////////////////////////////////////////////////
#if defined(__linux__)
#define CPU_FEATURES_OS_LINUX_OR_ANDROID
#endif
#if defined(__ANDROID__)
#define CPU_FEATURES_OS_ANDROID
#endif
#if (defined(_WIN64) || defined(_WIN32))
#define CPU_FEATURES_OS_WINDOWS
#endif
////////////////////////////////////////////////////////////////////////////////
// Compilers
////////////////////////////////////////////////////////////////////////////////
#if defined(__clang__)
#define CPU_FEATURES_COMPILER_CLANG
#endif
#if defined(__GNUC__) && !defined(__clang__)
#define CPU_FEATURES_COMPILER_GCC
#endif
#if defined(_MSC_VER)
#define CPU_FEATURES_COMPILER_MSC
#endif
////////////////////////////////////////////////////////////////////////////////
// Cpp
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
#define START_CPP_NAMESPACE \
namespace cpu_features { \
extern "C" {
#define END_CPP_NAMESPACE \
} \
}
#else
#define START_CPP_NAMESPACE
#define END_CPP_NAMESPACE
#endif
////////////////////////////////////////////////////////////////////////////////
// Compiler flags
////////////////////////////////////////////////////////////////////////////////
// Use the following to check if a feature is known to be available at compile
// time. See README.md for an example.
#if defined(CPU_FEATURES_ARCH_X86)
#define CPU_FEATURES_COMPILED_X86_AES defined(__AES__)
#define CPU_FEATURES_COMPILED_X86_F16C defined(__F16C__)
#define CPU_FEATURES_COMPILED_X86_BMI defined(__BMI__)
#define CPU_FEATURES_COMPILED_X86_BMI2 defined(__BMI2__)
#define CPU_FEATURES_COMPILED_X86_SSE (defined(__SSE__) || (_M_IX86_FP >= 1))
#define CPU_FEATURES_COMPILED_X86_SSE2 (defined(__SSE2__) || (_M_IX86_FP >= 2))
#define CPU_FEATURES_COMPILED_X86_SSE3 defined(__SSE3__)
#define CPU_FEATURES_COMPILED_X86_SSSE3 defined(__SSSE3__)
#define CPU_FEATURES_COMPILED_X86_SSE4_1 defined(__SSE4_1__)
#define CPU_FEATURES_COMPILED_X86_SSE4_2 defined(__SSE4_2__)
#define CPU_FEATURES_COMPILED_X86_AVX defined(__AVX__)
#define CPU_FEATURES_COMPILED_x86_AVX2 defined(__AVX2__)
#endif
#if defined(CPU_FEATURES_ARCH_ANY_ARM)
#define CPU_FEATURES_COMPILED_ANY_ARM_NEON defined(__ARM_NEON__)
#endif
#if defined(CPU_FEATURES_ARCH_MIPS)
#define CPU_FEATURES_COMPILED_MIPS_MSA defined(__mips_msa)
#endif
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_

65
include/cpuinfo_aarch64.h Normal file
View File

@ -0,0 +1,65 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
typedef struct {
int fp : 1; // Floating-point.
int asimd : 1; // Advanced SIMD.
int aes : 1; // Hardware-accelerated Advanced Encryption Standard.
int pmull : 1; // Polynomial multiply long.
int sha1 : 1; // Hardware-accelerated SHA1.
int sha2 : 1; // Hardware-accelerated SHA2-256.
int crc32 : 1; // Hardware-accelerated CRC-32.
// Make sure to update Aarch64FeaturesEnum below if you add a field here.
} Aarch64Features;
typedef struct {
Aarch64Features features;
int implementer;
int variant;
int part;
int revision;
} Aarch64Info;
Aarch64Info GetAarch64Info(void);
////////////////////////////////////////////////////////////////////////////////
// Introspection functions
typedef enum {
AARCH64_FP,
AARCH64_ASIMD,
AARCH64_AES,
AARCH64_PMULL,
AARCH64_SHA1,
AARCH64_SHA2,
AARCH64_CRC32,
AARCH64_LAST_,
} Aarch64FeaturesEnum;
int GetAarch64FeaturesEnumValue(const Aarch64Features* features,
Aarch64FeaturesEnum value);
const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_

80
include/cpuinfo_arm.h Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
typedef struct {
int vfp : 1; // Vector Floating Point.
int iwmmxt : 1; // Intel Wireless MMX Technology.
int neon : 1; // Advanced SIMD.
int vfpv3 : 1; // VFP version 3
int vfpv3d16 : 1; // VFP version 3 with 16 D-registers
int vfpv4 : 1; // VFP version 4 with fast context switching
int idiva : 1; // SDIV and UDIV hardware division in ARM mode.
int idivt : 1; // SDIV and UDIV hardware division in Thumb mode.
int aes : 1; // Hardware-accelerated Advanced Encryption Standard.
int pmull : 1; // Polynomial multiply long.
int sha1 : 1; // Hardware-accelerated SHA1.
int sha2 : 1; // Hardware-accelerated SHA2-256.
int crc32 : 1; // Hardware-accelerated CRC-32.
// Make sure to update ArmFeaturesEnum below if you add a field here.
} ArmFeatures;
typedef struct {
ArmFeatures features;
int implementer;
int architecture;
int variant;
int part;
int revision;
} ArmInfo;
// TODO(user): Add macros to know which features are present at compile
// time.
ArmInfo GetArmInfo(void);
////////////////////////////////////////////////////////////////////////////////
// Introspection functions
typedef enum {
ARM_VFP,
ARM_IWMMXT,
ARM_NEON,
ARM_VFPV3,
ARM_VFPV3D16,
ARM_VFPV4,
ARM_IDIVA,
ARM_IDIVT,
ARM_AES,
ARM_PMULL,
ARM_SHA1,
ARM_SHA2,
ARM_CRC32,
ARM_LAST_,
} ArmFeaturesEnum;
int GetArmFeaturesEnumValue(const ArmFeatures* features, ArmFeaturesEnum value);
const char* GetArmFeaturesEnumName(ArmFeaturesEnum);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_

53
include/cpuinfo_mips.h Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
typedef struct {
int msa : 1; // MIPS SIMD Architecture
// https://www.mips.com/products/architectures/ase/simd/
int eva : 1; // Enhanced Virtual Addressing
// https://www.mips.com/products/architectures/mips64/
// Make sure to update MipsFeaturesEnum below if you add a field here.
} MipsFeatures;
typedef struct {
MipsFeatures features;
} MipsInfo;
MipsInfo GetMipsInfo(void);
////////////////////////////////////////////////////////////////////////////////
// Introspection functions
typedef enum {
MIPS_MSA,
MIPS_EVA,
MIPS_LAST_,
} MipsFeaturesEnum;
int GetMipsFeaturesEnumValue(const MipsFeatures* features,
MipsFeaturesEnum value);
const char* GetMipsFeaturesEnumName(MipsFeaturesEnum);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_

147
include/cpuinfo_x86.h Normal file
View File

@ -0,0 +1,147 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features.
typedef struct {
int aes : 1;
int erms : 1;
int f16c : 1;
int fma3 : 1;
int vpclmulqdq : 1;
int bmi1 : 1;
int bmi2 : 1;
int ssse3 : 1;
int sse4_1 : 1;
int sse4_2 : 1;
int avx : 1;
int avx2 : 1;
int avx512f : 1;
int avx512cd : 1;
int avx512er : 1;
int avx512pf : 1;
int avx512bw : 1;
int avx512dq : 1;
int avx512vl : 1;
int avx512ifma : 1;
int avx512vbmi : 1;
int avx512vbmi2 : 1;
int avx512vnni : 1;
int avx512bitalg : 1;
int avx512vpopcntdq : 1;
int avx512_4vnniw : 1;
int avx512_4vbmi2 : 1;
// Make sure to update X86FeaturesEnum below if you add a field here.
} X86Features;
typedef struct {
X86Features features;
int family;
int model;
int stepping;
char vendor[13]; // 0 terminated string
} X86Info;
// Calls cpuid and returns an initialized X86info.
// This function is guaranteed to be malloc, memset and memcpy free.
X86Info GetX86Info(void);
typedef enum {
X86_UNKNOWN,
INTEL_CORE, // CORE
INTEL_PNR, // PENRYN
INTEL_NHM, // NEHALEM
INTEL_ATOM_BNL, // BONNELL
INTEL_WSM, // WESTMERE
INTEL_SNB, // SANDYBRIDGE
INTEL_IVB, // IVYBRIDGE
INTEL_ATOM_SMT, // SILVERMONT
INTEL_HSW, // HASWELL
INTEL_BDW, // BROADWELL
INTEL_SKL, // SKYLAKE
INTEL_ATOM_GMT, // GOLDMONT
INTEL_KBL, // KABY LAKE
INTEL_CFL, // COFFEE LAKE
INTEL_CNL, // CANON LAKE
AMD_HAMMER, // K8
AMD_K10, // K10
AMD_BOBCAT, // K14
AMD_BULLDOZER, // K15
AMD_JAGUAR, // K16
AMD_ZEN, // K17
} X86Microarchitecture;
// Returns the underlying microarchitecture by looking at X86Info's vendor,
// family and model.
X86Microarchitecture GetX86Microarchitecture(const X86Info* info);
// Calls cpuid and fills the brand_string.
// - brand_string *must* be of size 49 (beware of array decaying).
// - brand_string will be zero terminated.
// - This function calls memcpy.
void FillX86BrandString(char brand_string[49]);
////////////////////////////////////////////////////////////////////////////////
// Introspection functions
typedef enum {
X86_AES,
X86_ERMS,
X86_F16C,
X86_FMA3,
X86_VPCLMULQDQ,
X86_BMI1,
X86_BMI2,
X86_SSSE3,
X86_SSE4_1,
X86_SSE4_2,
X86_AVX,
X86_AVX2,
X86_AVX512F,
X86_AVX512CD,
X86_AVX512ER,
X86_AVX512PF,
X86_AVX512BW,
X86_AVX512DQ,
X86_AVX512VL,
X86_AVX512IFMA,
X86_AVX512VBMI,
X86_AVX512VBMI2,
X86_AVX512VNNI,
X86_AVX512BITALG,
X86_AVX512VPOPCNTDQ,
X86_AVX512_4VNNIW,
X86_AVX512_4VBMI2,
X86_LAST_,
} X86FeaturesEnum;
int GetX86FeaturesEnumValue(const X86Features* features, X86FeaturesEnum value);
const char* GetX86FeaturesEnumName(X86FeaturesEnum);
const char* GetX86MicroarchitectureName(X86Microarchitecture);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_X86_H_

View File

@ -0,0 +1,39 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
inline static bool IsBitSet(uint32_t reg, uint32_t bit) {
return (reg >> bit) & 0x1;
}
inline static uint32_t ExtractBitRange(uint32_t reg, uint32_t msb,
uint32_t lsb) {
const uint64_t bits = msb - lsb + 1;
const uint64_t mask = (1ULL << bits) - 1ULL;
assert(msb >= lsb);
return (reg >> lsb) & mask;
}
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_

View File

@ -0,0 +1,37 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// A struct to hold the result of a call to cpuid.
typedef struct {
uint32_t eax, ebx, ecx, edx;
} Leaf;
// Retrieves the leaf for a particular cpuid.
Leaf CpuId(uint32_t leaf_id);
// Returns the eax value of the XCR0 register.
uint32_t GetXCR0Eax(void);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_

View File

@ -0,0 +1,38 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// An interface for the filesystem that allows mocking the filesystem in
// unittests.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
#include <stddef.h>
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// Same as linux "open(filename, O_RDONLY)", retries automatically on EINTR.
int OpenFile(const char* filename);
// Same as linux "read(file_descriptor, buffer, buffer_size)", retries
// automatically on EINTR.
int ReadFile(int file_descriptor, void* buffer, size_t buffer_size);
// Same as linux "close(file_descriptor)".
void CloseFile(int file_descriptor);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_

73
include/internal/hwcaps.h Normal file
View File

@ -0,0 +1,73 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Interface to retrieve hardware capabilities. It relies on Linux's getauxval
// or `/proc/self/auxval` under the hood.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
#include <stdint.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
// To avoid depending on the linux kernel we reproduce the architecture specific
// constants here.
// http://elixir.free-electrons.com/linux/latest/source/arch/arm64/include/uapi/asm/hwcap.h
#define AARCH64_HWCAP_FP (1UL << 0)
#define AARCH64_HWCAP_ASIMD (1UL << 1)
#define AARCH64_HWCAP_AES (1UL << 3)
#define AARCH64_HWCAP_PMULL (1UL << 4)
#define AARCH64_HWCAP_SHA1 (1UL << 5)
#define AARCH64_HWCAP_SHA2 (1UL << 6)
#define AARCH64_HWCAP_CRC32 (1UL << 7)
// http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
#define ARM_HWCAP_VFP (1UL << 6)
#define ARM_HWCAP_IWMMXT (1UL << 9)
#define ARM_HWCAP_NEON (1UL << 12)
#define ARM_HWCAP_VFPV3 (1UL << 13)
#define ARM_HWCAP_VFPV3D16 (1UL << 14)
#define ARM_HWCAP_VFPV4 (1UL << 16)
#define ARM_HWCAP_IDIVA (1UL << 17)
#define ARM_HWCAP_IDIVT (1UL << 18)
#define ARM_HWCAP2_AES (1UL << 0)
#define ARM_HWCAP2_PMULL (1UL << 1)
#define ARM_HWCAP2_SHA1 (1UL << 2)
#define ARM_HWCAP2_SHA2 (1UL << 3)
#define ARM_HWCAP2_CRC32 (1UL << 4)
// http://elixir.free-electrons.com/linux/latest/source/arch/mips/include/uapi/asm/hwcap.h
#define MIPS_HWCAP_VZ (1UL << 0)
#define MIPS_HWCAP_EVA (1UL << 1)
#define MIPS_HWCAP_HTW (1UL << 2)
#define MIPS_HWCAP_FPU (1UL << 3)
#define MIPS_HWCAP_MIPS32R2 (1UL << 4)
#define MIPS_HWCAP_MIPS32R5 (1UL << 5)
#define MIPS_HWCAP_MIPS64R6 (1UL << 6)
#define MIPS_HWCAP_DSPR1 (1UL << 7)
#define MIPS_HWCAP_DSPR2 (1UL << 8)
#define MIPS_HWCAP_MSA (1UL << 9)
typedef struct {
uint32_t hwcaps;
uint32_t hwcaps2;
} HardwareCapabilities;
HardwareCapabilities GetHardwareCapabilities(void);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_

View File

@ -0,0 +1,58 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// CapabilityConfig provides a way to map cpu features to hardware caps and
// /proc/cpuinfo flags. We then provide functions to update capabilities from
// either source.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
#include <ctype.h>
#include <stdint.h>
#include "cpu_features_macros.h"
#include "internal/hwcaps.h"
#include "internal/string_view.h"
START_CPP_NAMESPACE
// Use the following macro to declare setter functions to be used in
// CapabilityConfig.
#define DECLARE_SETTER(FeatureType, FeatureName) \
static void set_##FeatureName(void* const features, bool value) { \
((FeatureType*)features)->FeatureName = value; \
}
// Describes the relationship between hardware caps and /proc/cpuinfo flags.
typedef struct {
const HardwareCapabilities hwcaps_mask;
const char* const proc_cpuinfo_flag;
void (*set_bit)(void* const, bool); // setter for the corresponding bit.
} CapabilityConfig;
// For every config, looks into flags_line for the presence of the
// corresponding proc_cpuinfo_flag, calls `set_bit` accordingly.
// Note: features is a pointer to the underlying Feature struct.
void SetFromFlags(const size_t configs_size, const CapabilityConfig* configs,
const StringView flags_line, void* const features);
// For every config, looks into hwcaps for the presence of the feature. Calls
// `set_bit` with true if the hardware capability is found.
// Note: features is a pointer to the underlying Feature struct.
void OverrideFromHwCaps(const size_t configs_size,
const CapabilityConfig* configs,
const HardwareCapabilities hwcaps,
void* const features);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_

View File

@ -0,0 +1,49 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Reads a file line by line and stores the data on the stack. This allows
// parsing files in one go without allocating.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
#include <stdbool.h>
#include "cpu_features_macros.h"
#include "internal/string_view.h"
START_CPP_NAMESPACE
typedef struct {
char buffer[STACK_LINE_READER_BUFFER_SIZE];
StringView view;
int fd;
bool skip_mode;
} StackLineReader;
// Initializes a StackLineReader.
void StackLineReader_Initialize(StackLineReader* reader, int fd);
typedef struct {
StringView line; // A view of the line.
bool eof; // Nothing more to read, we reached EOF.
bool full_line; // If false the line was truncated to
// STACK_LINE_READER_BUFFER_SIZE.
} LineResult;
// Reads the file pointed to by fd and tries to read a full line.
LineResult StackLineReader_NextLine(StackLineReader* reader);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_

View File

@ -0,0 +1,101 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// A view over a piece of string. The view is not 0 terminated.
#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "cpu_features_macros.h"
START_CPP_NAMESPACE
typedef struct {
const char* ptr;
size_t size;
} StringView;
#ifdef __cplusplus
static const StringView kEmptyStringView = {NULL, 0};
#else
static const StringView kEmptyStringView;
#endif
// Returns a StringView from the provided string.
// Passing NULL is valid only if size is 0.
static inline StringView view(const char* str, const size_t size) {
StringView view;
view.ptr = str;
view.size = size;
return view;
}
static inline StringView str(const char* str) { return view(str, strlen(str)); }
// Returns the index of the first occurrence of c in view or -1 if not found.
int IndexOfChar(const StringView view, char c);
// Returns the index of the first occurrence of sub_view in view or -1 if not
// found.
int IndexOf(const StringView view, const StringView sub_view);
// Returns whether a is equal to b (same content).
bool IsEquals(const StringView a, const StringView b);
// Returns whether a starts with b.
bool StartsWith(const StringView a, const StringView b);
// Removes count characters from the beginning of view or kEmptyStringView if
// count if greater than view.size.
StringView PopFront(const StringView view, size_t count);
// Removes count characters from the end of view or kEmptyStringView if count if
// greater than view.size.
StringView PopBack(const StringView str_view, size_t count);
// Keeps the count first characters of view or view if count if greater than
// view.size.
StringView KeepFront(const StringView view, size_t count);
// Retrieves the first character of view. If view is empty the behavior is
// undefined.
char Front(const StringView view);
// Retrieves the last character of view. If view is empty the behavior is
// undefined.
char Back(const StringView view);
// Removes leading and tailing space characters.
StringView TrimWhitespace(StringView view);
// Convert StringView to positive integer. e.g. "42", "0x2a".
// Returns -1 on error.
int ParsePositiveNumber(const StringView view);
// Copies src StringView to dst buffer.
void CopyString(const StringView src, char* dst, size_t dst_size);
// Checks if line contains the specified whitespace separated word.
bool HasWord(const StringView line, const char* const word);
// Get key/value from line. key and value are separated by ": ".
// key and value are cleaned up from leading and trailing whitespaces.
bool GetAttributeKeyValue(const StringView line, StringView* key,
StringView* value);
END_CPP_NAMESPACE
#endif // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_