From ff00e489173e7d70821b58e69af7c09a30e408a5 Mon Sep 17 00:00:00 2001 From: Areg Melik-Adamyan Date: Thu, 25 Apr 2019 03:05:33 -0500 Subject: [PATCH 1/5] Adding cpu-features library to vendored folder --- .../arrow/vendored/cpu_features/.clang-format | 4 + .../arrow/vendored/cpu_features/.gitignore | 1 + .../arrow/vendored/cpu_features/.travis.yml | 117 ++++ .../vendored/cpu_features/CMakeLists.txt | 234 ++++++++ .../vendored/cpu_features/CONTRIBUTING.md | 23 + cpp/src/arrow/vendored/cpu_features/LICENSE | 202 +++++++ cpp/src/arrow/vendored/cpu_features/README.md | 174 ++++++ cpp/src/arrow/vendored/cpu_features/WORKSPACE | 7 + .../arrow/vendored/cpu_features/appveyor.yml | 24 + .../cmake/CpuFeaturesConfig.cmake.in | 3 + .../cmake/CpuFeaturesNdkCompatConfig.cmake.in | 3 + .../vendored/cpu_features/cmake/README.md | 28 + .../cmake/googletest.CMakeLists.txt.in | 15 + .../include/cpu_features_macros.h | 143 +++++ .../cpu_features/include/cpuinfo_aarch64.h | 69 +++ .../cpu_features/include/cpuinfo_arm.h | 88 +++ .../cpu_features/include/cpuinfo_mips.h | 59 ++ .../cpu_features/include/cpuinfo_ppc.h | 145 +++++ .../cpu_features/include/cpuinfo_x86.h | 167 ++++++ .../cpu_features/include/internal/bit_utils.h | 39 ++ .../cpu_features/include/internal/cpuid_x86.h | 37 ++ .../include/internal/filesystem.h | 38 ++ .../cpu_features/include/internal/hwcaps.h | 124 +++++ .../include/internal/stack_line_reader.h | 49 ++ .../include/internal/string_view.h | 108 ++++ .../internal/unix_features_aggregator.h | 60 ++ .../cpu_features/ndk_compat/CMakeLists.txt | 59 ++ .../cpu_features/ndk_compat/README.md | 4 + .../cpu_features/ndk_compat/cpu-features.c | 204 +++++++ .../cpu_features/ndk_compat/cpu-features.h | 320 +++++++++++ .../cpu_features/ndk_compat/ndk-compat-test.c | 11 + .../cpu_features/scripts/run_integration.sh | 209 +++++++ .../cpu_features/scripts/test_integration.sh | 106 ++++ .../cpu_features/src/cpuinfo_aarch64.c | 141 +++++ .../vendored/cpu_features/src/cpuinfo_arm.c | 259 +++++++++ .../vendored/cpu_features/src/cpuinfo_mips.c | 104 ++++ .../vendored/cpu_features/src/cpuinfo_ppc.c | 358 ++++++++++++ .../vendored/cpu_features/src/cpuinfo_x86.c | 518 ++++++++++++++++++ .../vendored/cpu_features/src/filesystem.c | 59 ++ .../arrow/vendored/cpu_features/src/hwcaps.c | 162 ++++++ .../cpu_features/src/stack_line_reader.c | 131 +++++ .../vendored/cpu_features/src/string_view.c | 182 ++++++ .../src/unix_features_aggregator.c | 52 ++ .../src/utils/list_cpu_features.c | 246 +++++++++ .../vendored/cpu_features/test/CMakeLists.txt | 92 ++++ .../cpu_features/test/bit_utils_test.cc | 53 ++ .../cpu_features/test/cpuinfo_aarch64_test.cc | 74 +++ .../cpu_features/test/cpuinfo_arm_test.cc | 186 +++++++ .../cpu_features/test/cpuinfo_mips_test.cc | 126 +++++ .../cpu_features/test/cpuinfo_ppc_test.cc | 119 ++++ .../cpu_features/test/cpuinfo_x86_test.cc | 176 ++++++ .../test/filesystem_for_testing.cc | 103 ++++ .../test/filesystem_for_testing.h | 61 +++ .../cpu_features/test/hwcaps_for_testing.cc | 45 ++ .../cpu_features/test/hwcaps_for_testing.h | 27 + .../test/stack_line_reader_test.cc | 132 +++++ .../cpu_features/test/string_view_test.cc | 144 +++++ .../test/unix_features_aggregator_test.cc | 95 ++++ 58 files changed, 6519 insertions(+) create mode 100644 cpp/src/arrow/vendored/cpu_features/.clang-format create mode 100644 cpp/src/arrow/vendored/cpu_features/.gitignore create mode 100644 cpp/src/arrow/vendored/cpu_features/.travis.yml create mode 100644 cpp/src/arrow/vendored/cpu_features/CMakeLists.txt create mode 100644 cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md create mode 100644 cpp/src/arrow/vendored/cpu_features/LICENSE create mode 100644 cpp/src/arrow/vendored/cpu_features/README.md create mode 100644 cpp/src/arrow/vendored/cpu_features/WORKSPACE create mode 100644 cpp/src/arrow/vendored/cpu_features/appveyor.yml create mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in create mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in create mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/README.md create mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in create mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h create mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h create mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt create mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md create mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c create mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h create mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c create mode 100644 cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh create mode 100644 cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh create mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/filesystem.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/hwcaps.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/string_view.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c create mode 100644 cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c create mode 100644 cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt create mode 100644 cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h create mode 100644 cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h create mode 100644 cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc create mode 100644 cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc diff --git a/cpp/src/arrow/vendored/cpu_features/.clang-format b/cpp/src/arrow/vendored/cpu_features/.clang-format new file mode 100644 index 000000000000..06ea346a1067 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/.clang-format @@ -0,0 +1,4 @@ +--- +Language: Cpp +BasedOnStyle: Google +... diff --git a/cpp/src/arrow/vendored/cpu_features/.gitignore b/cpp/src/arrow/vendored/cpu_features/.gitignore new file mode 100644 index 000000000000..0690aa44237d --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/.gitignore @@ -0,0 +1 @@ +cmake_build/ diff --git a/cpp/src/arrow/vendored/cpu_features/.travis.yml b/cpp/src/arrow/vendored/cpu_features/.travis.yml new file mode 100644 index 000000000000..e0b4f448d6f9 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/.travis.yml @@ -0,0 +1,117 @@ +language: c + +sudo: false + +cache: + timeout: 1000 + directories: + - $HOME/cpu_features_archives + +addons: + apt: + packages: + - ninja-build + +env: + global: + TOOLCHAIN=NATIVE + CMAKE_GENERATOR=Ninja + +matrix: + include: + - os: linux + compiler: gcc + env: + TARGET=x86_64-linux-gnu + - os: linux + compiler: clang + env: + TARGET=x86_64-linux-gnu + - os: osx + compiler: gcc + env: + TARGET=x86_64-osx + CMAKE_GENERATOR="Unix Makefiles" + - os: osx + compiler: clang + env: + TARGET=x86_64-osx + CMAKE_GENERATOR="Unix Makefiles" + - os: windows + env: + TARGET=x86_64-windows + CMAKE_GENERATOR="Visual Studio 15 2017 Win64" + - os: linux-ppc64le + compiler: gcc + env: + TARGET=ppc64le-linux-gnu + - os: linux-ppc64le + compiler: clang + env: + TARGET=ppc64le-linux-gnu + # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=aarch64-linux-gnu + QEMU_ARCH=aarch64 + # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm + # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armv8l-linux-gnueabihf + QEMU_ARCH=arm + # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabi + QEMU_ARCH=arm + # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=aarch64_be-linux-gnu + QEMU_ARCH=DISABLED + # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabihf + QEMU_ARCH=DISABLED + # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabi + QEMU_ARCH=DISABLED + - os: linux + env: + TOOLCHAIN=CODESCAPE + TARGET=mips32 + QEMU_ARCH=mips + - os: linux + env: + TOOLCHAIN=CODESCAPE + TARGET=mips32el + QEMU_ARCH=mipsel + - os: linux + env: + TOOLCHAIN=CODESCAPE + TARGET=mips64 + QEMU_ARCH=mips64 + - os: linux + env: + TOOLCHAIN=CODESCAPE + TARGET=mips64el + QEMU_ARCH=mips64el + +script: + - cmake --version + - bash -e -x ./scripts/run_integration.sh diff --git a/cpp/src/arrow/vendored/cpu_features/CMakeLists.txt b/cpp/src/arrow/vendored/cpu_features/CMakeLists.txt new file mode 100644 index 000000000000..6e0d33e3bf16 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/CMakeLists.txt @@ -0,0 +1,234 @@ +cmake_minimum_required(VERSION 3.0) + +project(CpuFeatures VERSION 0.1.0) + +# Default Build Type to be Release +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." + FORCE) +endif(NOT CMAKE_BUILD_TYPE) + +# BUILD_TESTING is a standard CMake variable, but we declare it here to make it +# prominent in the GUI. +option(BUILD_TESTING "Enable test (depends on googletest)." OFF) +# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make +# it prominent in the GUI. +# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field). +# As a consequence it is discouraged to use cpu_features as a shared library because different compilers may interpret the code in different ways. +# Prefer static linking from source whenever possible. +option(BUILD_SHARED_LIBS "Build library as shared." OFF) +# PIC +option(BUILD_PIC "Build with Position Independant Code." OFF) # Default is off at least for GCC + +include(CheckIncludeFile) +include(CheckSymbolExists) +include(GNUInstallDirs) + +macro(setup_include_and_definitions TARGET_NAME) + target_include_directories(${TARGET_NAME} + PUBLIC $ + PRIVATE $ + ) + target_compile_definitions(${TARGET_NAME} + PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024 + ) +endmacro() + +set(PROCESSOR_IS_MIPS FALSE) +set(PROCESSOR_IS_ARM FALSE) +set(PROCESSOR_IS_AARCH64 FALSE) +set(PROCESSOR_IS_X86 FALSE) +set(PROCESSOR_IS_POWER FALSE) + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") + set(PROCESSOR_IS_MIPS TRUE) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") + set(PROCESSOR_IS_ARM TRUE) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") + set(PROCESSOR_IS_AARCH64 TRUE) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64)|(^i.86$)") + set(PROCESSOR_IS_X86 TRUE) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") + set(PROCESSOR_IS_POWER TRUE) +endif() + +macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) + list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h) + if(PROCESSOR_IS_MIPS) + list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) + list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_mips.c) + elseif(PROCESSOR_IS_ARM) + list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) + list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_arm.c) + elseif(PROCESSOR_IS_AARCH64) + list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) + list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_aarch64.c) + elseif(PROCESSOR_IS_X86) + list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) + list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h) + list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c) + elseif(PROCESSOR_IS_POWER) + list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) + list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_ppc.c) + else() + message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") + endif() +endmacro() + +# +# library : utils +# + +add_library(utils OBJECT + ${PROJECT_SOURCE_DIR}/include/internal/bit_utils.h + ${PROJECT_SOURCE_DIR}/include/internal/filesystem.h + ${PROJECT_SOURCE_DIR}/include/internal/stack_line_reader.h + ${PROJECT_SOURCE_DIR}/include/internal/string_view.h + ${PROJECT_SOURCE_DIR}/src/filesystem.c + ${PROJECT_SOURCE_DIR}/src/stack_line_reader.c + ${PROJECT_SOURCE_DIR}/src/string_view.c +) +setup_include_and_definitions(utils) + +arrow_install_all_headers("arrow/vendored/cpu_features") +# +# library : unix_based_hardware_detection +# + +if(UNIX) + add_library(unix_based_hardware_detection OBJECT + ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h + ${PROJECT_SOURCE_DIR}/include/internal/unix_features_aggregator.h + ${PROJECT_SOURCE_DIR}/src/hwcaps.c + ${PROJECT_SOURCE_DIR}/src/unix_features_aggregator.c + ) + setup_include_and_definitions(unix_based_hardware_detection) + check_include_file(dlfcn.h HAVE_DLFCN_H) + if(HAVE_DLFCN_H) + target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H) + endif() + check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL) + if(HAVE_STRONG_GETAUXVAL) + target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL) + endif() + set_property(TARGET unix_based_hardware_detection PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) +endif() + +# +# library : cpu_features +# +set (CPU_FEATURES_HDRS) +set (CPU_FEATURES_SRCS) +add_cpu_features_headers_and_sources(CPU_FEATURES_HDRS CPU_FEATURES_SRCS) +list(APPEND CPU_FEATURES_SRCS $) +if(NOT PROCESSOR_IS_X86 AND UNIX) + list(APPEND CPU_FEATURES_SRCS $) +endif() +add_library(cpu_features ${CPU_FEATURES_HDRS} ${CPU_FEATURES_SRCS}) +set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${CPU_FEATURES_HDRS}") +setup_include_and_definitions(cpu_features) +target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS}) +set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) +target_include_directories(cpu_features + PUBLIC $ +) + +# +# program : list_cpu_features +# + +add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c) +target_link_libraries(list_cpu_features PRIVATE cpu_features) +add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features) + +# +# ndk_compat +# + +if(ANDROID) +add_subdirectory(ndk_compat) +endif() + +# +# tests +# + +include(CTest) +if(BUILD_TESTING) + # Automatically incorporate googletest into the CMake Project if target not + # found. + if(NOT TARGET gtest OR NOT TARGET gmock_main) + # Download and unpack googletest at configure time. + configure_file( + cmake/googletest.CMakeLists.txt.in + googletest-download/CMakeLists.txt + ) + + execute_process( + COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) + + if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") + endif() + + execute_process( + COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) + + if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") + endif() + + # Prevent overriding the parent project's compiler/linker settings on + # Windows. + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + + # Add googletest directly to our build. This defines the gtest and + # gtest_main targets. + add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src + ${CMAKE_BINARY_DIR}/googletest-build + EXCLUDE_FROM_ALL) + endif() + + add_subdirectory(test) +endif() + +# +# Install cpu_features and list_cpu_features +# + +include(GNUInstallDirs) +install(TARGETS cpu_features list_cpu_features + EXPORT CpuFeaturesTargets + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) +install(EXPORT CpuFeaturesTargets + NAMESPACE CpuFeatures:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures + COMPONENT Devel +) +include(CMakePackageConfigHelpers) +configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in + "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO +) +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) +install( + FILES + "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" + "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" + COMPONENT Devel +) diff --git a/cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md b/cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md new file mode 100644 index 000000000000..c980350f8fc3 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution; +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. diff --git a/cpp/src/arrow/vendored/cpu_features/LICENSE b/cpp/src/arrow/vendored/cpu_features/LICENSE new file mode 100644 index 000000000000..7a4a3ea2424c --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/cpp/src/arrow/vendored/cpu_features/README.md b/cpp/src/arrow/vendored/cpu_features/README.md new file mode 100644 index 000000000000..29d794661cf9 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/README.md @@ -0,0 +1,174 @@ +# cpu_features [![Build Status](https://travis-ci.org/google/cpu_features.svg?branch=master)](https://travis-ci.org/google/cpu_features) [![Build status](https://ci.appveyor.com/api/projects/status/46d1owsj7n8dsylq/branch/master?svg=true)](https://ci.appveyor.com/project/gchatelet/cpu-features/branch/master) + +A cross-platform C library to retrieve CPU features (such as available +instructions) at runtime. + +## Table of Contents + +- [Design Rationale](#rationale) +- [Code samples](#codesample) +- [Running sample code](#usagesample) +- [What's supported](#support) +- [Android NDK's drop in replacement](#ndk) +- [License](#license) +- [Build with cmake](#cmake) + + +## Design Rationale + +- **Simple to use.** See the snippets below for examples. +- **Extensible.** Easy to add missing features or architectures. +- **Compatible with old compilers** and available on many architectures so it + can be used widely. To ensure that cpu_features works on as many platforms + as possible, we implemented it in a highly portable version of C: C99. +- **Sandbox-compatible.** The library uses a variety of strategies to cope + with sandboxed environments or when `cpuid` is unavailable. This is useful + when running integration tests in hermetic environments. +- **Thread safe, no memory allocation, and raises no exceptions.** + cpu_features is suitable for implementing fundamental libc functions like + `malloc`, `memcpy`, and `memcmp`. +- **Unit tested.** + + +### Checking features at runtime + +Here's a simple example that executes a codepath if the CPU supports both the +AES and the SSE4.2 instruction sets: + +```c +#include "cpuinfo_x86.h" + +static const X86Features features = GetX86Info().features; + +void Compute(void) { + if (features.aes && features.sse4_2) { + // Run optimized code. + } else { + // Run standard code. + } +} +``` + +### Caching for faster evaluation of complex checks + +If you wish, you can read all the features at once into a global variable, and +then query for the specific features you care about. Below, we store all the ARM +features and then check whether AES and NEON are supported. + +```c +#include +#include "cpuinfo_arm.h" + +static const ArmFeatures features = GetArmInfo().features; +static const bool has_aes_and_neon = features.aes && features.neon; + +// use has_aes_and_neon. +``` + +This is a good approach to take if you're checking for combinations of features +when using a compiler that is slow to extract individual bits from bit-packed +structures. + +### Checking compile time flags + +The following code determines whether the compiler was told to use the AVX +instruction set (e.g., `g++ -mavx`) and sets `has_avx` accordingly. + +```c +#include +#include "cpuinfo_x86.h" + +static const X86Features features = GetX86Info().features; +static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx; + +// use has_avx. +``` + +`CPU_FEATURES_COMPILED_X86_AVX` is set to 1 if the compiler was instructed to +use AVX and 0 otherwise, combining compile time and runtime knowledge. + +### Rejecting poor hardware implementations based on microarchitecture + +On x86, the first incarnation of a feature in a microarchitecture might not be +the most efficient (e.g. AVX on Sandy Bridge). We provide a function to retrieve +the underlying microarchitecture so you can decide whether to use it. + +Below, `has_fast_avx` is set to 1 if the CPU supports the AVX instruction +set—but only if it's not Sandy Bridge. + +```c +#include +#include "cpuinfo_x86.h" + +static const X86Info info = GetX86Info(); +static const X86Microarchitecture uarch = GetX86Microarchitecture(&info); +static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB; + +// use has_fast_avx. +``` + +This feature is currently available only for x86 microarchitectures. + + +### Running sample code + +Building `cpu_features` brings a small executable to test the library. + +```shell + % ./build/list_cpu_features +arch : x86 +brand : Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz +family : 6 (0x06) +model : 45 (0x2D) +stepping : 7 (0x07) +uarch : INTEL_SNB +flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3 +``` + +```shell +% ./build/list_cpu_features --json +{"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"]} +``` + + +## What's supported + +| | x86³ | ARM | AArch64 | MIPS⁴ | POWER | +|---------|:----:|:-------:|:-------:|:------:|:-------:| +| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | +| iOS | N/A | not yet | not yet | N/A | N/A | +| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | +| MacOs | yes² | N/A | not yet | N/A | no | +| Windows | yes² | not yet | not yet | N/A | N/A | + +1. **Features revealed from Linux.** We gather data from several sources + depending on availability: + + from glibc's + [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html) + + by parsing `/proc/self/auxv` + + by parsing `/proc/cpuinfo` +2. **Features revealed from CPU.** features are retrieved by using the `cpuid` + instruction. +3. **Microarchitecture detection.** On x86 some features are not always + implemented efficiently in hardware (e.g. AVX on Sandybridge). Exposing the + microarchitecture allows the client to reject particular microarchitectures. +4. All flavors of Mips are supported, little and big endian as well as 32/64 + bits. + + +## Android NDK's drop in replacement + +[cpu_features](https://github.com/google/cpu_features) is now officially +supporting Android and offers a drop in replacement of for the NDK's [cpu-features.h](https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h) +, see [ndk_compat](ndk_compat) folder for details. + + +## License + +The cpu_features library is licensed under the terms of the Apache license. +See [LICENSE](LICENSE) for more information. + + +## Build with CMake + +Please check the [CMake build instructions](cmake/README.md). diff --git a/cpp/src/arrow/vendored/cpu_features/WORKSPACE b/cpp/src/arrow/vendored/cpu_features/WORKSPACE new file mode 100644 index 000000000000..8ea8a8b6c59b --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/WORKSPACE @@ -0,0 +1,7 @@ +# ===== googletest ===== + +git_repository( + name = "com_google_googletest", + remote = "https://github.com/google/googletest.git", + commit = "c3f65335b79f47b05629e79a54685d899bc53b93", +) diff --git a/cpp/src/arrow/vendored/cpu_features/appveyor.yml b/cpp/src/arrow/vendored/cpu_features/appveyor.yml new file mode 100644 index 000000000000..f18635a3d195 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/appveyor.yml @@ -0,0 +1,24 @@ +version: '{build}' +shallow_clone: true + +platform: x64 + +environment: + matrix: + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + CMAKE_GENERATOR: "Visual Studio 15 2017 Win64" + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + CMAKE_GENERATOR: "Visual Studio 14 2015 Win64" + +matrix: + fast_finish: true + +before_build: + - cmake --version + - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -H. -Bcmake_build -G "%CMAKE_GENERATOR%" + +build_script: + - cmake --build cmake_build --config Debug --target ALL_BUILD + +test_script: + - cmake --build cmake_build --config Debug --target RUN_TESTS diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in b/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in new file mode 100644 index 000000000000..e0bf10e42de1 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in @@ -0,0 +1,3 @@ +# CpuFeatures CMake configuration file + +include("${CMAKE_CURRENT_LIST_DIR}/CpuFeaturesTargets.cmake") diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in b/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in new file mode 100644 index 000000000000..5a53ffda9265 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in @@ -0,0 +1,3 @@ +# CpuFeaturesNdkCompat CMake configuration file + +include("${CMAKE_CURRENT_LIST_DIR}/CpuFeaturesNdkCompatTargets.cmake") diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/README.md b/cpp/src/arrow/vendored/cpu_features/cmake/README.md new file mode 100644 index 000000000000..b6baeaa21c8a --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/cmake/README.md @@ -0,0 +1,28 @@ +# CMake build instructions + +## Recommended usage : Incorporating cpu_features into a CMake project + + For API / ABI compatibility reasons, it is recommended to build and use + cpu_features in a subdirectory of your project or as an embedded dependency. + + This is similar to the recommended usage of the googletest framework + ( https://github.com/google/googletest/blob/master/googletest/README.md ) + + Build and use step-by-step + + + 1- Download cpu_features and copy it in a sub-directory in your project. + or add cpu_features as a git-submodule in your project + + 2- You can then use the cmake command `add_subdirectory()` to include + cpu_features directly and use the `cpu_features` target in your project. + + 3- Add the `cpu_features` target to the `target_link_libraries()` section of + your executable or of your library. + +## Enabling tests + + CMake default options for cpu_features is Release built type with tests + disabled. To enable testing set cmake `BUILD_TESTING` variable to `ON`, + [.travis.yml](../.travis.yml) and [appveyor.yml](../appveyor.yml) have up to + date examples. diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in b/cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in new file mode 100644 index 000000000000..d60a33e9ac6a --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.8.2) + +project(googletest-download NONE) + +include(ExternalProject) +ExternalProject_Add(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG master + SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" + BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" +) \ No newline at end of file diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h b/cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h new file mode 100644 index 000000000000..2227160367aa --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h @@ -0,0 +1,143 @@ +// 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 CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ +#define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ + +//////////////////////////////////////////////////////////////////////////////// +// Architectures +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__pnacl__) || defined(__CLR_VER) +#define CPU_FEATURES_ARCH_VM +#endif + +#if (defined(_M_IX86) || defined(__i386__)) && !defined(CPU_FEATURES_ARCH_VM) +#define CPU_FEATURES_ARCH_X86_32 +#endif + +#if (defined(_M_X64) || defined(__x86_64__)) && !defined(CPU_FEATURES_ARCH_VM) +#define CPU_FEATURES_ARCH_X86_64 +#endif + +#if defined(CPU_FEATURES_ARCH_X86_32) || defined(CPU_FEATURES_ARCH_X86_64) +#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(__mips64) +#define CPU_FEATURES_ARCH_MIPS64 +#endif + +#if defined(__mips__) && !defined(__mips64) // mips64 also declares __mips__ +#define CPU_FEATURES_ARCH_MIPS32 +#endif + +#if defined(CPU_FEATURES_ARCH_MIPS32) || defined(CPU_FEATURES_ARCH_MIPS64) +#define CPU_FEATURES_ARCH_MIPS +#endif + +#if defined(__powerpc__) +#define CPU_FEATURES_ARCH_PPC +#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 CPU_FEATURES_START_CPP_NAMESPACE \ + namespace cpu_features { \ + extern "C" { +#define CPU_FEATURES_END_CPP_NAMESPACE \ + } \ + } +#else +#define CPU_FEATURES_START_CPP_NAMESPACE +#define CPU_FEATURES_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 // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h new file mode 100644 index 000000000000..a7d22018c228 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h @@ -0,0 +1,69 @@ +// 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 CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ +#define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ + +#include "cpu_features_macros.h" + +CPU_FEATURES_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); + +CPU_FEATURES_END_CPP_NAMESPACE + +#if !defined(CPU_FEATURES_ARCH_AARCH64) +#error "Including cpuinfo_aarch64.h from a non-aarch64 target." +#endif + +#endif // CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h new file mode 100644 index 000000000000..76a49ef58a2f --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h @@ -0,0 +1,88 @@ +// 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 CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ +#define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ + +#include // uint32_t +#include "cpu_features_macros.h" + +CPU_FEATURES_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); + +// Compute CpuId from ArmInfo. +uint32_t GetArmCpuId(const ArmInfo* const info); + +//////////////////////////////////////////////////////////////////////////////// +// 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); + +CPU_FEATURES_END_CPP_NAMESPACE + +#if !defined(CPU_FEATURES_ARCH_ARM) +#error "Including cpuinfo_arm.h from a non-arm target." +#endif + +#endif // CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h new file mode 100644 index 000000000000..fd65a230d729 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h @@ -0,0 +1,59 @@ +// 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 CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ +#define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ + +#include "cpu_features_macros.h" + +CPU_FEATURES_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/ + int r6 : 1; // True if is release 6 of the processor. + + // 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_R6, + MIPS_LAST_, +} MipsFeaturesEnum; + +int GetMipsFeaturesEnumValue(const MipsFeatures* features, + MipsFeaturesEnum value); + +const char* GetMipsFeaturesEnumName(MipsFeaturesEnum); + +CPU_FEATURES_END_CPP_NAMESPACE + +#if !defined(CPU_FEATURES_ARCH_MIPS) +#error "Including cpuinfo_mips.h from a non-mips target." +#endif + +#endif // CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h new file mode 100644 index 000000000000..53d1cb6e42e4 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h @@ -0,0 +1,145 @@ +// Copyright 2018 IBM +// +// 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 CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ +#define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ + +#include "cpu_features_macros.h" +#include "internal/hwcaps.h" + +CPU_FEATURES_START_CPP_NAMESPACE + +typedef struct { + int ppc32 : 1; + int ppc64 : 1; + int ppc601 : 1; + int altivec : 1; + int fpu : 1; + int mmu : 1; + int mac_4xx : 1; + int unifiedcache : 1; + int spe : 1; + int efpsingle : 1; + int efpdouble : 1; + int no_tb : 1; + int power4 : 1; + int power5 : 1; + int power5plus : 1; + int cell : 1; + int booke : 1; + int smt : 1; + int icachesnoop : 1; + int arch205 : 1; + int pa6t : 1; + int dfp : 1; + int power6ext : 1; + int arch206 : 1; + int vsx : 1; + int pseries_perfmon_compat : 1; + int truele : 1; + int ppcle : 1; + int arch207 : 1; + int htm : 1; + int dscr : 1; + int ebb : 1; + int isel : 1; + int tar : 1; + int vcrypto : 1; + int htm_nosc : 1; + int arch300 : 1; + int ieee128 : 1; + int darn : 1; + int scv : 1; + int htm_no_suspend : 1; + + // Make sure to update PPCFeaturesEnum below if you add a field here. +} PPCFeatures; + +typedef struct { + PPCFeatures features; +} PPCInfo; + +// This function is guaranteed to be malloc, memset and memcpy free. +PPCInfo GetPPCInfo(void); + +typedef struct { + char platform[64]; // 0 terminated string + char model[64]; // 0 terminated string + char machine[64]; // 0 terminated string + char cpu[64]; // 0 terminated string + PlatformType type; +} PPCPlatformStrings; + +PPCPlatformStrings GetPPCPlatformStrings(void); + +//////////////////////////////////////////////////////////////////////////////// +// Introspection functions + +typedef enum { + PPC_32, /* 32 bit mode execution */ + PPC_64, /* 64 bit mode execution */ + PPC_601_INSTR, /* Old POWER ISA */ + PPC_HAS_ALTIVEC, /* SIMD Unit*/ + PPC_HAS_FPU, /* Floating Point Unit */ + PPC_HAS_MMU, /* Memory management unit */ + PPC_HAS_4xxMAC, + PPC_UNIFIED_CACHE, /* Unified instruction and data cache */ + PPC_HAS_SPE, /* Signal processing extention unit */ + PPC_HAS_EFP_SINGLE, /* SPE single precision fpu */ + PPC_HAS_EFP_DOUBLE, /* SPE double precision fpu */ + PPC_NO_TB, /* No timebase */ + PPC_POWER4, + PPC_POWER5, + PPC_POWER5_PLUS, + PPC_CELL, /* Cell broadband engine */ + PPC_BOOKE, /* Embedded ISA */ + PPC_SMT, /* Simultaneous multi-threading */ + PPC_ICACHE_SNOOP, + PPC_ARCH_2_05, /* ISA 2.05 - POWER6 */ + PPC_PA6T, /* PA Semi 6T core ISA */ + PPC_HAS_DFP, /* Decimal floating point unit */ + PPC_POWER6_EXT, + PPC_ARCH_2_06, /* ISA 2.06 - POWER7 */ + PPC_HAS_VSX, /* Vector-scalar extension */ + PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatibile performance + monitoring events */ + PPC_TRUE_LE, + PPC_PPC_LE, + PPC_ARCH_2_07, /* ISA 2.07 - POWER8 */ + PPC_HTM, /* Hardware Transactional Memory */ + PPC_DSCR, /* Data stream control register */ + PPC_EBB, /* Event base branching */ + PPC_ISEL, /* Integer select instructions */ + PPC_TAR, /* Target address register */ + PPC_VEC_CRYPTO, /* Vector cryptography instructions */ + PPC_HTM_NOSC, /* Transactions aborted when syscall made*/ + PPC_ARCH_3_00, /* ISA 3.00 - POWER9 */ + PPC_HAS_IEEE128, /* VSX IEEE Binary Float 128-bit */ + PPC_DARN, /* Deliver a random number instruction */ + PPC_SCV, /* scv syscall */ + PPC_HTM_NO_SUSPEND, /* TM w/out suspended state */ + PPC_LAST_, +} PPCFeaturesEnum; + +int GetPPCFeaturesEnumValue(const PPCFeatures* features, PPCFeaturesEnum value); + +const char* GetPPCFeaturesEnumName(PPCFeaturesEnum); + +CPU_FEATURES_END_CPP_NAMESPACE + +#if !defined(CPU_FEATURES_ARCH_PPC) +#error "Including cpuinfo_ppc.h from a non-ppc target." +#endif + +#endif // CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h new file mode 100644 index 000000000000..bb61293b3748 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h @@ -0,0 +1,167 @@ +// 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 CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ +#define CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ + +#include "cpu_features_macros.h" + +CPU_FEATURES_START_CPP_NAMESPACE + +// See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features. +// The field names are based on the short name provided in the wikipedia tables. +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; + + int smx : 1; + int sgx : 1; + int cx16 : 1; // aka. CMPXCHG16B + int sha : 1; + int popcnt : 1; + int movbe : 1; + int rdrnd : 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, // CANNON 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_SMX, + X86_SGX, + X86_CX16, + X86_SHA, + X86_POPCNT, + X86_MOVBE, + X86_RDRND, + X86_LAST_, +} X86FeaturesEnum; + +int GetX86FeaturesEnumValue(const X86Features* features, X86FeaturesEnum value); + +const char* GetX86FeaturesEnumName(X86FeaturesEnum); + +const char* GetX86MicroarchitectureName(X86Microarchitecture); + +CPU_FEATURES_END_CPP_NAMESPACE + +#if !defined(CPU_FEATURES_ARCH_X86) +#error "Including cpuinfo_x86.h from a non-x86 target." +#endif + +#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h b/cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h new file mode 100644 index 000000000000..bc965cb6e313 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h @@ -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 CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ + +#include +#include +#include +#include "cpu_features_macros.h" + +CPU_FEATURES_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 + 1ULL; + const uint64_t mask = (1ULL << bits) - 1ULL; + assert(msb >= lsb); + return (reg >> lsb) & mask; +} + +CPU_FEATURES_END_CPP_NAMESPACE + +#endif // CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h b/cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h new file mode 100644 index 000000000000..9dcee0de95b4 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h @@ -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 CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ + +#include + +#include "cpu_features_macros.h" + +CPU_FEATURES_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); + +CPU_FEATURES_END_CPP_NAMESPACE + +#endif // CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h b/cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h new file mode 100644 index 000000000000..3378881358eb --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h @@ -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 CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ + +#include +#include +#include "cpu_features_macros.h" + +CPU_FEATURES_START_CPP_NAMESPACE + +// Same as linux "open(filename, O_RDONLY)", retries automatically on EINTR. +int CpuFeatures_OpenFile(const char* filename); + +// Same as linux "read(file_descriptor, buffer, buffer_size)", retries +// automatically on EINTR. +int CpuFeatures_ReadFile(int file_descriptor, void* buffer, size_t buffer_size); + +// Same as linux "close(file_descriptor)". +void CpuFeatures_CloseFile(int file_descriptor); + +CPU_FEATURES_END_CPP_NAMESPACE + +#endif // CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h b/cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h new file mode 100644 index 000000000000..cb38e294aa4e --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h @@ -0,0 +1,124 @@ +// 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 CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ + +#include +#include "cpu_features_macros.h" + +CPU_FEATURES_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_R6 (1UL << 0) +#define MIPS_HWCAP_MSA (1UL << 1) +#define MIPS_HWCAP_CRC32 (1UL << 2) + +// http://elixir.free-electrons.com/linux/latest/source/arch/powerpc/include/uapi/asm/cputable.h +#ifndef _UAPI__ASM_POWERPC_CPUTABLE_H +/* in AT_HWCAP */ +#define PPC_FEATURE_32 0x80000000 +#define PPC_FEATURE_64 0x40000000 +#define PPC_FEATURE_601_INSTR 0x20000000 +#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 +#define PPC_FEATURE_HAS_FPU 0x08000000 +#define PPC_FEATURE_HAS_MMU 0x04000000 +#define PPC_FEATURE_HAS_4xxMAC 0x02000000 +#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 +#define PPC_FEATURE_HAS_SPE 0x00800000 +#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 +#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 +#define PPC_FEATURE_NO_TB 0x00100000 +#define PPC_FEATURE_POWER4 0x00080000 +#define PPC_FEATURE_POWER5 0x00040000 +#define PPC_FEATURE_POWER5_PLUS 0x00020000 +#define PPC_FEATURE_CELL 0x00010000 +#define PPC_FEATURE_BOOKE 0x00008000 +#define PPC_FEATURE_SMT 0x00004000 +#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 +#define PPC_FEATURE_ARCH_2_05 0x00001000 +#define PPC_FEATURE_PA6T 0x00000800 +#define PPC_FEATURE_HAS_DFP 0x00000400 +#define PPC_FEATURE_POWER6_EXT 0x00000200 +#define PPC_FEATURE_ARCH_2_06 0x00000100 +#define PPC_FEATURE_HAS_VSX 0x00000080 + +#define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040 + +/* Reserved - do not use 0x00000004 */ +#define PPC_FEATURE_TRUE_LE 0x00000002 +#define PPC_FEATURE_PPC_LE 0x00000001 + +/* in AT_HWCAP2 */ +#define PPC_FEATURE2_ARCH_2_07 0x80000000 +#define PPC_FEATURE2_HTM 0x40000000 +#define PPC_FEATURE2_DSCR 0x20000000 +#define PPC_FEATURE2_EBB 0x10000000 +#define PPC_FEATURE2_ISEL 0x08000000 +#define PPC_FEATURE2_TAR 0x04000000 +#define PPC_FEATURE2_VEC_CRYPTO 0x02000000 +#define PPC_FEATURE2_HTM_NOSC 0x01000000 +#define PPC_FEATURE2_ARCH_3_00 0x00800000 +#define PPC_FEATURE2_HAS_IEEE128 0x00400000 +#define PPC_FEATURE2_DARN 0x00200000 +#define PPC_FEATURE2_SCV 0x00100000 +#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 +#endif + +typedef struct { + unsigned long hwcaps; + unsigned long hwcaps2; +} HardwareCapabilities; + +HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void); + +typedef struct { + char platform[64]; // 0 terminated string + char base_platform[64]; // 0 terminated string +} PlatformType; + +PlatformType CpuFeatures_GetPlatformType(void); + +CPU_FEATURES_END_CPP_NAMESPACE + +#endif // CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h b/cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h new file mode 100644 index 000000000000..c540f6b23e1e --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h @@ -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 CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ + +#include + +#include "cpu_features_macros.h" +#include "internal/string_view.h" + +CPU_FEATURES_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); + +CPU_FEATURES_END_CPP_NAMESPACE + +#endif // CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h b/cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h new file mode 100644 index 000000000000..aa3779c44d01 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h @@ -0,0 +1,108 @@ +// 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 CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ + +#include +#include +#include +#include "cpu_features_macros.h" + +CPU_FEATURES_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 CpuFeatures_StringView_IndexOfChar(const StringView view, char c); + +// Returns the index of the first occurrence of sub_view in view or -1 if not +// found. +int CpuFeatures_StringView_IndexOf(const StringView view, + const StringView sub_view); + +// Returns whether a is equal to b (same content). +bool CpuFeatures_StringView_IsEquals(const StringView a, const StringView b); + +// Returns whether a starts with b. +bool CpuFeatures_StringView_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 CpuFeatures_StringView_PopFront(const StringView str_view, + size_t count); + +// Removes count characters from the end of view or kEmptyStringView if count if +// greater than view.size. +StringView CpuFeatures_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 CpuFeatures_StringView_KeepFront(const StringView str_view, + size_t count); + +// Retrieves the first character of view. If view is empty the behavior is +// undefined. +char CpuFeatures_StringView_Front(const StringView view); + +// Retrieves the last character of view. If view is empty the behavior is +// undefined. +char CpuFeatures_StringView_Back(const StringView view); + +// Removes leading and tailing space characters. +StringView CpuFeatures_StringView_TrimWhitespace(StringView view); + +// Convert StringView to positive integer. e.g. "42", "0x2a". +// Returns -1 on error. +int CpuFeatures_StringView_ParsePositiveNumber(const StringView view); + +// Copies src StringView to dst buffer. +void CpuFeatures_StringView_CopyString(const StringView src, char* dst, + size_t dst_size); + +// Checks if line contains the specified whitespace separated word. +bool CpuFeatures_StringView_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 CpuFeatures_StringView_GetAttributeKeyValue(const StringView line, + StringView* key, + StringView* value); + +CPU_FEATURES_END_CPP_NAMESPACE + +#endif // CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h b/cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h new file mode 100644 index 000000000000..77661d4cb399 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h @@ -0,0 +1,60 @@ +// 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 CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_ +#define CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_ + +#include +#include +#include "cpu_features_macros.h" +#include "internal/hwcaps.h" +#include "internal/string_view.h" + +CPU_FEATURES_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 CpuFeatures_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 CpuFeatures_OverrideFromHwCaps(const size_t configs_size, + const CapabilityConfig* configs, + const HardwareCapabilities hwcaps, + void* const features); + +CPU_FEATURES_END_CPP_NAMESPACE +#endif // CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt b/cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt new file mode 100644 index 000000000000..d95e523742b3 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt @@ -0,0 +1,59 @@ + +# +# library : NDK compat +# +find_package(Threads REQUIRED) +set (NDK_COMPAT_HDRS cpu-features.h) +set (NDK_COMPAT_SRCS + cpu-features.c + $ + $ +) +# Note that following `add_cpu_features_headers_and_sources` will use +# NDK_COMPAT_SRCS in lieu of NDK_COMPAT_HDRS because we don't want cpu_features +# headers to be installed alongside ndk_compat. +add_cpu_features_headers_and_sources(NDK_COMPAT_SRCS NDK_COMPAT_SRCS) +add_library(ndk_compat ${NDK_COMPAT_HDRS} ${NDK_COMPAT_SRCS}) +setup_include_and_definitions(ndk_compat) +target_link_libraries(ndk_compat PUBLIC ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +set_target_properties(ndk_compat PROPERTIES PUBLIC_HEADER "${NDK_COMPAT_HDRS}") + +include(GNUInstallDirs) +install(TARGETS ndk_compat + EXPORT CpuFeaturesNdkCompatTargets + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ndk_compat + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) +install(EXPORT CpuFeaturesNdkCompatTargets + NAMESPACE CpuFeatures:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeaturesNdkCompat + COMPONENT Devel +) +include(CMakePackageConfigHelpers) +configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/CpuFeaturesNdkCompatConfig.cmake.in + "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfig.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeaturesNdkCompat" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO +) +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) +install( + FILES + "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfig.cmake" + "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeaturesNdkCompat" + COMPONENT Devel +) + +# +# program : NDK compat test program +# +if(ENABLE_TESTING) + add_executable(ndk-compat-test ndk-compat-test.c) + target_link_libraries(ndk-compat-test PRIVATE ndk_compat) +endif() diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md b/cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md new file mode 100644 index 000000000000..38c83937f93d --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md @@ -0,0 +1,4 @@ +Provides a header compatible with [android's NDK cpu-features.h](https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h). + +It is intended to be a drop in replacement for this header and help users +transition from the NDK to [Google's cpu_features library](https://github.com/google/cpu_features). diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c b/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c new file mode 100644 index 000000000000..715dc4f7d659 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c @@ -0,0 +1,204 @@ +#include "cpu-features.h" +#include "cpu_features_macros.h" +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" + +#include + +#if defined(CPU_FEATURES_ARCH_ARM) +#include "cpuinfo_arm.h" +#elif defined(CPU_FEATURES_ARCH_X86) +#include "cpuinfo_x86.h" +#elif defined(CPU_FEATURES_ARCH_MIPS) +#include "cpuinfo_mips.h" +#elif defined(CPU_FEATURES_ARCH_AARCH64) +#include "cpuinfo_aarch64.h" +#endif + +static pthread_once_t g_once; +static int g_inited; +static uint64_t g_cpuFeatures; +static int g_cpuCount; + +#ifdef CPU_FEATURES_ARCH_ARM +static uint32_t g_cpuIdArm; +#endif + +static void set_cpu_mask_bit(uint32_t index, uint32_t* cpu_mask) { + *cpu_mask |= 1UL << index; +} + +// Examples of valid inputs: "31", "4-31" +static void parse_cpu_mask(const StringView text, uint32_t* cpu_mask) { + int separator_index = CpuFeatures_StringView_IndexOfChar(text, '-'); + if (separator_index < 0) { // A single cpu index + int cpu_index = CpuFeatures_StringView_ParsePositiveNumber(text); + if (cpu_index < 0) return; + set_cpu_mask_bit(cpu_index, cpu_mask); + } else { + int cpu_index_a = CpuFeatures_StringView_ParsePositiveNumber( + CpuFeatures_StringView_KeepFront(text, separator_index)); + int cpu_index_b = CpuFeatures_StringView_ParsePositiveNumber( + CpuFeatures_StringView_PopFront(text, separator_index + 1)); + int i; + if (cpu_index_a < 0 || cpu_index_b < 0) return; + for (i = cpu_index_a; i <= cpu_index_b; ++i) { + if (i < 32) { + set_cpu_mask_bit(i, cpu_mask); + } + } + } +} + +// Format specification from +// https://www.kernel.org/doc/Documentation/cputopology.txt +// Examples of valid inputs: "31", "2,4-31,32-63", "0-1,3" +static void parse_cpu_mask_line(const LineResult result, uint32_t* cpu_mask) { + if (!result.full_line || result.eof) return; + StringView line = result.line; + for (; line.size > 0;) { + int next_entry_index = CpuFeatures_StringView_IndexOfChar(line, ','); + if (next_entry_index < 0) { + parse_cpu_mask(line, cpu_mask); + break; + } + StringView entry = CpuFeatures_StringView_KeepFront(line, next_entry_index); + parse_cpu_mask(entry, cpu_mask); + line = CpuFeatures_StringView_PopFront(line, next_entry_index + 1); + } +} + +static void update_cpu_mask_from_file(const char* filename, + uint32_t* cpu_mask) { + const int fd = CpuFeatures_OpenFile(filename); + if (fd >= 0) { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + parse_cpu_mask_line(StackLineReader_NextLine(&reader), cpu_mask); + CpuFeatures_CloseFile(fd); + } +} + +static int get_cpu_count(void) { + uint32_t cpu_mask = 0; + update_cpu_mask_from_file("/sys/devices/system/cpu/present", &cpu_mask); + update_cpu_mask_from_file("/sys/devices/system/cpu/possible", &cpu_mask); + return __builtin_popcount(cpu_mask); +} + +static void android_cpuInit(void) { + g_cpuFeatures = 0; + g_cpuCount = 1; + g_inited = 1; + + g_cpuCount = get_cpu_count(); + if (g_cpuCount == 0) { + g_cpuCount = 1; + } +#if defined(CPU_FEATURES_ARCH_ARM) + ArmInfo info = GetArmInfo(); + if (info.architecture == 7) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7; + if (info.features.vfpv3) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3; + if (info.features.neon) { + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON; + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFP_D32; + } + if (info.features.vfpv3d16) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFP_FP16; + if (info.features.idiva) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM; + if (info.features.idivt) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2; + if (info.features.iwmmxt) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_iWMMXt; + if (info.features.aes) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_AES; + if (info.features.pmull) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_PMULL; + if (info.features.sha1) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA1; + if (info.features.sha2) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA2; + if (info.features.crc32) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_CRC32; + if (info.architecture >= 6) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX; + if (info.features.vfpv) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv2; + if (info.features.vfpv4) { + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFP_FMA; + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON_FMA; + } + g_cpuIdArm = GetArmCpuId(&info); +#elif defined(CPU_FEATURES_ARCH_X86) + X86Info info = GetX86Info(); + if (info.features.ssse3) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3; + if (info.features.popcnt) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT; + if (info.features.movbe) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE; + if (info.features.sse4_1) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_1; + if (info.features.sse4_2) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_2; + if (info.features.aes) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AES_NI; + if (info.features.avx) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX; + if (info.features.rdrnd) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_RDRAND; + if (info.features.avx2) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX2; + if (info.features.sha) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SHA_NI; +#elif defined(CPU_FEATURES_ARCH_MIPS) + MipsInfo info = GetMipsInfo(); + if (info.features.r6) g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_R6; + if (info.features.msa) g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_MSA; +#elif defined(CPU_FEATURES_ARCH_AARCH64) + Aarch64Info info = GetAarch64Info(); + if (info.features.fp) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_FP; + if (info.features.asimd) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_ASIMD; + if (info.features.aes) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_AES; + if (info.features.pmull) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_PMULL; + if (info.features.sha1) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA1; + if (info.features.sha2) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA2; + if (info.features.crc32) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_CRC32; +#endif +} + +AndroidCpuFamily android_getCpuFamily(void) { +#if defined(CPU_FEATURES_ARCH_ARM) + return ANDROID_CPU_FAMILY_ARM; +#elif defined(CPU_FEATURES_ARCH_X86_32) + return ANDROID_CPU_FAMILY_X86; +#elif defined(CPU_FEATURES_ARCH_MIPS64) + return ANDROID_CPU_FAMILY_MIPS64; +#elif defined(CPU_FEATURES_ARCH_MIPS32) + return ANDROID_CPU_FAMILY_MIPS; +#elif defined(CPU_FEATURES_ARCH_AARCH64) + return ANDROID_CPU_FAMILY_ARM64; +#elif defined(CPU_FEATURES_ARCH_X86_64) + return ANDROID_CPU_FAMILY_X86_64; +#else + return ANDROID_CPU_FAMILY_UNKNOWN; +#endif +} + +uint64_t android_getCpuFeatures(void) { + pthread_once(&g_once, android_cpuInit); + return g_cpuFeatures; +} + +int android_getCpuCount(void) { + pthread_once(&g_once, android_cpuInit); + return g_cpuCount; +} + +static void android_cpuInitDummy(void) { g_inited = 1; } + +int android_setCpu(int cpu_count, uint64_t cpu_features) { + /* Fail if the library was already initialized. */ + if (g_inited) return 0; + g_cpuCount = (cpu_count <= 0 ? 1 : cpu_count); + g_cpuFeatures = cpu_features; + pthread_once(&g_once, android_cpuInitDummy); + return 1; +} + +#ifdef CPU_FEATURES_ARCH_ARM + +uint32_t android_getCpuIdArm(void) { + pthread_once(&g_once, android_cpuInit); + return g_cpuIdArm; +} + +int android_setCpuArm(int cpu_count, uint64_t cpu_features, uint32_t cpu_id) { + if (!android_setCpu(cpu_count, cpu_features)) return 0; + g_cpuIdArm = cpu_id; + return 1; +} + +#endif // CPU_FEATURES_ARCH_ARM diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h b/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h new file mode 100644 index 000000000000..51bea5387962 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef GOOGLE_CPU_FEATURES_H +#define GOOGLE_CPU_FEATURES_H +#include +#include + +__BEGIN_DECLS + +/* A list of valid values returned by android_getCpuFamily(). + * They describe the CPU Architecture of the current process. + */ +typedef enum { + ANDROID_CPU_FAMILY_UNKNOWN = 0, + ANDROID_CPU_FAMILY_ARM, + ANDROID_CPU_FAMILY_X86, + ANDROID_CPU_FAMILY_MIPS, + ANDROID_CPU_FAMILY_ARM64, + ANDROID_CPU_FAMILY_X86_64, + ANDROID_CPU_FAMILY_MIPS64, + ANDROID_CPU_FAMILY_MAX /* do not remove */ +} AndroidCpuFamily; + +/* Return the CPU family of the current process. + * + * Note that this matches the bitness of the current process. I.e. when + * running a 32-bit binary on a 64-bit capable CPU, this will return the + * 32-bit CPU family value. + */ +extern AndroidCpuFamily android_getCpuFamily(void); + +/* Return a bitmap describing a set of optional CPU features that are + * supported by the current device's CPU. The exact bit-flags returned + * depend on the value returned by android_getCpuFamily(). See the + * documentation for the ANDROID_CPU_*_FEATURE_* flags below for details. + */ +extern uint64_t android_getCpuFeatures(void); + +/* The list of feature flags for ANDROID_CPU_FAMILY_ARM that can be + * recognized by the library (see note below for 64-bit ARM). Value details + * are: + * + * VFPv2: + * CPU supports the VFPv2 instruction set. Many, but not all, ARMv6 CPUs + * support these instructions. VFPv2 is a subset of VFPv3 so this will + * be set whenever VFPv3 is set too. + * + * ARMv7: + * CPU supports the ARMv7-A basic instruction set. + * This feature is mandated by the 'armeabi-v7a' ABI. + * + * VFPv3: + * CPU supports the VFPv3-D16 instruction set, providing hardware FPU + * support for single and double precision floating point registers. + * Note that only 16 FPU registers are available by default, unless + * the D32 bit is set too. This feature is also mandated by the + * 'armeabi-v7a' ABI. + * + * VFP_D32: + * CPU VFP optional extension that provides 32 FPU registers, + * instead of 16. Note that ARM mandates this feature is the 'NEON' + * feature is implemented by the CPU. + * + * NEON: + * CPU FPU supports "ARM Advanced SIMD" instructions, also known as + * NEON. Note that this mandates the VFP_D32 feature as well, per the + * ARM Architecture specification. + * + * VFP_FP16: + * Half-width floating precision VFP extension. If set, the CPU + * supports instructions to perform floating-point operations on + * 16-bit registers. This is part of the VFPv4 specification, but + * not mandated by any Android ABI. + * + * VFP_FMA: + * Fused multiply-accumulate VFP instructions extension. Also part of + * the VFPv4 specification, but not mandated by any Android ABI. + * + * NEON_FMA: + * Fused multiply-accumulate NEON instructions extension. Optional + * extension from the VFPv4 specification, but not mandated by any + * Android ABI. + * + * IDIV_ARM: + * Integer division available in ARM mode. Only available + * on recent CPUs (e.g. Cortex-A15). + * + * IDIV_THUMB2: + * Integer division available in Thumb-2 mode. Only available + * on recent CPUs (e.g. Cortex-A15). + * + * iWMMXt: + * Optional extension that adds MMX registers and operations to an + * ARM CPU. This is only available on a few XScale-based CPU designs + * sold by Marvell. Pretty rare in practice. + * + * AES: + * CPU supports AES instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * CRC32: + * CPU supports CRC32 instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * SHA2: + * CPU supports SHA2 instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * SHA1: + * CPU supports SHA1 instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * PMULL: + * CPU supports 64-bit PMULL and PMULL2 instructions. These + * instructions are only available for 32-bit applications + * running on ARMv8 CPU. + * + * If you want to tell the compiler to generate code that targets one of + * the feature set above, you should probably use one of the following + * flags (for more details, see technical note at the end of this file): + * + * -mfpu=vfp + * -mfpu=vfpv2 + * These are equivalent and tell GCC to use VFPv2 instructions for + * floating-point operations. Use this if you want your code to + * run on *some* ARMv6 devices, and any ARMv7-A device supported + * by Android. + * + * Generated code requires VFPv2 feature. + * + * -mfpu=vfpv3-d16 + * Tell GCC to use VFPv3 instructions (using only 16 FPU registers). + * This should be generic code that runs on any CPU that supports the + * 'armeabi-v7a' Android ABI. Note that no ARMv6 CPU supports this. + * + * Generated code requires VFPv3 feature. + * + * -mfpu=vfpv3 + * Tell GCC to use VFPv3 instructions with 32 FPU registers. + * Generated code requires VFPv3|VFP_D32 features. + * + * -mfpu=neon + * Tell GCC to use VFPv3 instructions with 32 FPU registers, and + * also support NEON intrinsics (see ). + * Generated code requires VFPv3|VFP_D32|NEON features. + * + * -mfpu=vfpv4-d16 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA features. + * + * -mfpu=vfpv4 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32 features. + * + * -mfpu=neon-vfpv4 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|NEON|NEON_FMA + * features. + * + * -mcpu=cortex-a7 + * -mcpu=cortex-a15 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32| + * NEON|NEON_FMA|IDIV_ARM|IDIV_THUMB2 + * This flag implies -mfpu=neon-vfpv4. + * + * -mcpu=iwmmxt + * Allows the use of iWMMXt instrinsics with GCC. + * + * IMPORTANT NOTE: These flags should only be tested when + * android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a + * 32-bit process. + * + * When running a 64-bit ARM process on an ARMv8 CPU, + * android_getCpuFeatures() will return a different set of bitflags + */ +enum { + ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0), + ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1), + ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2), + ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3), + ANDROID_CPU_ARM_FEATURE_VFPv2 = (1 << 4), + ANDROID_CPU_ARM_FEATURE_VFP_D32 = (1 << 5), + ANDROID_CPU_ARM_FEATURE_VFP_FP16 = (1 << 6), + ANDROID_CPU_ARM_FEATURE_VFP_FMA = (1 << 7), + ANDROID_CPU_ARM_FEATURE_NEON_FMA = (1 << 8), + ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9), + ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10), + ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11), + ANDROID_CPU_ARM_FEATURE_AES = (1 << 12), + ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13), + ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14), + ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15), + ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16), +}; + +/* The bit flags corresponding to the output of android_getCpuFeatures() + * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM64. Value details + * are: + * + * FP: + * CPU has Floating-point unit. + * + * ASIMD: + * CPU has Advanced SIMD unit. + * + * AES: + * CPU supports AES instructions. + * + * CRC32: + * CPU supports CRC32 instructions. + * + * SHA2: + * CPU supports SHA2 instructions. + * + * SHA1: + * CPU supports SHA1 instructions. + * + * PMULL: + * CPU supports 64-bit PMULL and PMULL2 instructions. + */ +enum { + ANDROID_CPU_ARM64_FEATURE_FP = (1 << 0), + ANDROID_CPU_ARM64_FEATURE_ASIMD = (1 << 1), + ANDROID_CPU_ARM64_FEATURE_AES = (1 << 2), + ANDROID_CPU_ARM64_FEATURE_PMULL = (1 << 3), + ANDROID_CPU_ARM64_FEATURE_SHA1 = (1 << 4), + ANDROID_CPU_ARM64_FEATURE_SHA2 = (1 << 5), + ANDROID_CPU_ARM64_FEATURE_CRC32 = (1 << 6), +}; + +/* The bit flags corresponding to the output of android_getCpuFeatures() + * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_X86 or + * ANDROID_CPU_FAMILY_X86_64. + */ +enum { + ANDROID_CPU_X86_FEATURE_SSSE3 = (1 << 0), + ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1), + ANDROID_CPU_X86_FEATURE_MOVBE = (1 << 2), + ANDROID_CPU_X86_FEATURE_SSE4_1 = (1 << 3), + ANDROID_CPU_X86_FEATURE_SSE4_2 = (1 << 4), + ANDROID_CPU_X86_FEATURE_AES_NI = (1 << 5), + ANDROID_CPU_X86_FEATURE_AVX = (1 << 6), + ANDROID_CPU_X86_FEATURE_RDRAND = (1 << 7), + ANDROID_CPU_X86_FEATURE_AVX2 = (1 << 8), + ANDROID_CPU_X86_FEATURE_SHA_NI = (1 << 9), +}; + +/* The bit flags corresponding to the output of android_getCpuFeatures() + * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_MIPS + * or ANDROID_CPU_FAMILY_MIPS64. Values are: + * + * R6: + * CPU executes MIPS Release 6 instructions natively, and + * supports obsoleted R1..R5 instructions only via kernel traps. + * + * MSA: + * CPU supports Mips SIMD Architecture instructions. + */ +enum { + ANDROID_CPU_MIPS_FEATURE_R6 = (1 << 0), + ANDROID_CPU_MIPS_FEATURE_MSA = (1 << 1), +}; + +/* Return the number of CPU cores detected on this device. + * Please note the current implementation supports up to 32 cpus. + */ +extern int android_getCpuCount(void); + +/* The following is used to force the CPU count and features + * mask in sandboxed processes. Under 4.1 and higher, these processes + * cannot access /proc, which is the only way to get information from + * the kernel about the current hardware (at least on ARM). + * + * It _must_ be called only once, and before any android_getCpuXXX + * function, any other case will fail. + * + * This function return 1 on success, and 0 on failure. + */ +extern int android_setCpu(int cpu_count, uint64_t cpu_features); + +#ifdef __arm__ + +/* Retrieve the ARM 32-bit CPUID value from the kernel. + * Note that this cannot work on sandboxed processes under 4.1 and + * higher, unless you called android_setCpuArm() before. + */ +extern uint32_t android_getCpuIdArm(void); + +/* An ARM-specific variant of android_setCpu() that also allows you + * to set the ARM CPUID field. + */ +extern int android_setCpuArm(int cpu_count, uint64_t cpu_features, + uint32_t cpu_id); + +#endif + +__END_DECLS +#endif /* GOOGLE_CPU_FEATURES_H */ diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c b/cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c new file mode 100644 index 000000000000..782dbbf96375 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c @@ -0,0 +1,11 @@ +#include +#include "cpu-features.h" + +int main() { + printf("android_getCpuFamily()=%d\n", android_getCpuFamily()); + printf("android_getCpuFeatures()=0x%08llx\n", android_getCpuFeatures()); + printf("android_getCpuCount()=%d\n", android_getCpuCount()); +#ifdef __arm__ + printf("android_getCpuIdArm()=0x%04x\n", android_getCpuIdArm()); +#endif //__arm__ +} diff --git a/cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh b/cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh new file mode 100644 index 000000000000..fd88d605e29e --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh @@ -0,0 +1,209 @@ +#!/usr/bin/env bash + +readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) +readonly PROJECT_FOLDER="${SCRIPT_FOLDER}/.." +readonly ARCHIVE_FOLDER=~/cpu_features_archives +readonly QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu +readonly DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" + +function extract() { + case $1 in + *.tar.bz2) tar xjf "$1" ;; + *.tar.xz) tar xJf "$1" ;; + *.tar.gz) tar xzf "$1" ;; + *) + echo "don't know how to extract '$1'..." + exit 1 + esac +} + +function unpackifnotexists() { + mkdir -p "${ARCHIVE_FOLDER}" + cd "${ARCHIVE_FOLDER}" || exit + local URL=$1 + local RELATIVE_FOLDER=$2 + local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}" + if [[ ! -d "${DESTINATION}" ]] ; then + local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///') + test -f "${ARCHIVE_NAME}" || wget -q "${URL}" + extract "${ARCHIVE_NAME}" + rm -f "${ARCHIVE_NAME}" + fi +} + +function installqemuifneeded() { + local VERSION=${QEMU_VERSION:=2.11.1} + local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel mips64 mips64el} + local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} + + if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then + echo "qemu ${VERSION} up to date!" + return 0 + fi + + echo "VERSION: ${VERSION}" + echo "TARGETS: ${TARGETS}" + + rm -rf ${QEMU_INSTALL} + + # Checking for a tarball before downloading makes testing easier :-) + local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" + local QEMU_FOLDER="qemu-${VERSION}" + unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} + cd ${QEMU_FOLDER} || exit + + ./configure \ + --prefix="${QEMU_INSTALL}" \ + --target-list="${TARGETS}" \ + --disable-docs \ + --disable-sdl \ + --disable-gtk \ + --disable-gnutls \ + --disable-gcrypt \ + --disable-nettle \ + --disable-curses \ + --static + + make -j4 + make install + + echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build +} + +function assert_defined(){ + local VALUE=${1} + : "${VALUE?"${1} needs to be defined"}" +} + +function integrate() { + cd "${PROJECT_FOLDER}" + case "${OS}" in + "Windows_NT") CMAKE_BUILD_ARGS="--config Debug --target ALL_BUILD" + CMAKE_TEST_FILES="${BUILD_DIR}/test/Debug/*_test.exe" + DEMO=${BUILD_DIR}/Debug/list_cpu_features.exe + ;; + *) CMAKE_BUILD_ARGS="--target all" + CMAKE_TEST_FILES="${BUILD_DIR}/test/*_test" + DEMO=${BUILD_DIR}/list_cpu_features + ;; + esac + + # Generating CMake configuration + cmake -H. -B"${BUILD_DIR}" ${DEFAULT_CMAKE_ARGS} "${CMAKE_ADDITIONAL_ARGS[@]}" -G"${CMAKE_GENERATOR:-Unix Makefiles}" + + # Building + cmake --build "${BUILD_DIR}" ${CMAKE_BUILD_ARGS} + + # Running tests if needed + if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then + return + fi + RUN_CMD="" + if [[ -n "${QEMU_ARCH}" ]]; then + installqemuifneeded + RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[@]}" + fi + for test_binary in ${CMAKE_TEST_FILES}; do + ${RUN_CMD} ${test_binary} + done + ${RUN_CMD} ${DEMO} +} + +function expand_linaro_config() { + assert_defined TARGET + local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 + + local GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz + local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}" + unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" + + local SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz + local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} + unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" + + local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER} + local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} + + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) + + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSROOT=${SYSROOT_FOLDER}) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=${GCC_FOLDER}/bin/${TARGET}-gcc) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=${GCC_FOLDER}/bin/${TARGET}-g++) + + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY) + + QEMU_ARGS+=(-L ${SYSROOT_FOLDER}) + QEMU_ARGS+=(-E LD_LIBRARY_PATH=/lib) +} + +function expand_codescape_config() { + assert_defined TARGET + local DATE=2017.10-08 + local CODESCAPE_URL=https://codescape.mips.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz + local GCC_URL=${CODESCAPE_URL} + local GCC_RELATIVE_FOLDER="mips-mti-linux-gnu/${DATE}" + unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" + + local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} + local MIPS_FLAGS="" + local LIBC_FOLDER_SUFFIX="" + local FLAVOUR="" + case "${TARGET}" in + "mips32") MIPS_FLAGS="-EB -mabi=32"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;; + "mips32el") MIPS_FLAGS="-EL -mabi=32"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;; + "mips64") MIPS_FLAGS="-EB -mabi=64"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;; + "mips64el") MIPS_FLAGS="-EL -mabi=64"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;; + *) echo 'unknown mips platform'; exit 1;; + esac + + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH=${GCC_FOLDER}) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=mips-mti-linux-gnu-gcc) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=mips-mti-linux-gnu-g++) + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER_ARG1="${MIPS_FLAGS}") + CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER_ARG1="${MIPS_FLAGS}") + + local SYSROOT_FOLDER=${GCC_FOLDER}/sysroot/${FLAVOUR} + + # Keeping only the sysroot of interest to save on travis cache. + if [[ "${CONTINUOUS_INTEGRATION}" = "true" ]]; then + for folder in ${GCC_FOLDER}/sysroot/*; do + if [[ "${folder}" != "${SYSROOT_FOLDER}" ]]; then + rm -rf ${folder} + fi + done + fi + + local LIBC_FOLDER=${GCC_FOLDER}/mips-mti-linux-gnu/lib/${FLAVOUR}/${LIBC_FOLDER_SUFFIX} + QEMU_ARGS+=(-L ${SYSROOT_FOLDER}) + QEMU_ARGS+=(-E LD_PRELOAD=${LIBC_FOLDER}/libstdc++.so.6:${LIBC_FOLDER}/libgcc_s.so.1) +} + +function expand_environment_and_integrate() { + assert_defined PROJECT_FOLDER + assert_defined TARGET + + BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" + mkdir -p "${BUILD_DIR}" + + declare -a CONFIG_NAMES=() + declare -a QEMU_ARGS=() + declare -a CMAKE_ADDITIONAL_ARGS=() + + case ${TOOLCHAIN} in + LINARO) expand_linaro_config ;; + CODESCAPE) expand_codescape_config ;; + NATIVE) QEMU_ARCH="" ;; + *) echo "Unknown toolchain '${TOOLCHAIN}'..."; exit 1;; + esac + integrate +} + +if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then + QEMU_ARCHES=${QEMU_ARCH} + expand_environment_and_integrate +fi diff --git a/cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh b/cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh new file mode 100644 index 000000000000..d1c61b02e6ff --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash + +source "$(dirname -- "$0")"/run_integration.sh + +# Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems +function set_aarch64-linux-gnu() { + TOOLCHAIN=LINARO + TARGET=aarch64-linux-gnu + QEMU_ARCH=aarch64 +} + +# Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_arm-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm +} + +# Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems +function set_armv8l-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=armv8l-linux-gnueabihf + QEMU_ARCH=arm +} + +# Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_arm-linux-gnueabi() { + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabi + QEMU_ARCH=arm +} + +# Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems +function set_aarch64_be-linux-gnu() { + TOOLCHAIN=LINARO + TARGET=aarch64_be-linux-gnu + QEMU_ARCH=DISABLED +} + +# Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_armeb-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabihf + QEMU_ARCH=DISABLED +} + +# Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_armeb-linux-gnueabi() { + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabi + QEMU_ARCH=DISABLED +} + +function set_mips32() { + TOOLCHAIN=CODESCAPE + TARGET=mips32 + QEMU_ARCH=mips +} + +function set_mips32el() { + TOOLCHAIN=CODESCAPE + TARGET=mips32el + QEMU_ARCH=mipsel +} + +function set_mips64() { + TOOLCHAIN=CODESCAPE + TARGET=mips64 + QEMU_ARCH=mips64 +} + +function set_mips64el() { + TOOLCHAIN=CODESCAPE + TARGET=mips64el + QEMU_ARCH=mips64el +} + +function set_native() { + TOOLCHAIN=NATIVE + TARGET=native + QEMU_ARCH="" +} + +ENVIRONMENTS=" + set_aarch64-linux-gnu + set_arm-linux-gnueabihf + set_armv8l-linux-gnueabihf + set_arm-linux-gnueabi + set_aarch64_be-linux-gnu + set_armeb-linux-gnueabihf + set_armeb-linux-gnueabi + set_mips32 + set_mips32el + set_mips64 + set_mips64el + set_native +" + +set -e + +CMAKE_GENERATOR="Ninja" + +for SET_ENVIRONMENT in ${ENVIRONMENTS}; do + ${SET_ENVIRONMENT} + expand_environment_and_integrate +done diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c new file mode 100644 index 000000000000..57e9c8d88050 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c @@ -0,0 +1,141 @@ +// 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. + +#include "cpuinfo_aarch64.h" + +#include "internal/filesystem.h" +#include "internal/hwcaps.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include "internal/unix_features_aggregator.h" + +#include + +DECLARE_SETTER(Aarch64Features, fp) +DECLARE_SETTER(Aarch64Features, asimd) +DECLARE_SETTER(Aarch64Features, aes) +DECLARE_SETTER(Aarch64Features, pmull) +DECLARE_SETTER(Aarch64Features, sha1) +DECLARE_SETTER(Aarch64Features, sha2) +DECLARE_SETTER(Aarch64Features, crc32) + +static const CapabilityConfig kConfigs[] = { + {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp}, // + {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd}, // + {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes}, // + {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull}, // + {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1}, // + {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2}, // + {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32}, // +}; + +static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); + +static bool HandleAarch64Line(const LineResult result, + Aarch64Info* const info) { + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { + if (CpuFeatures_StringView_IsEquals(key, str("Features"))) { + CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) { + info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) { + info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) { + info->part = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) { + info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(Aarch64Info* const info) { + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) { + if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const Aarch64Info kEmptyAarch64Info; + +Aarch64Info GetAarch64Info(void) { + // capabilities are fetched from both getauxval and /proc/cpuinfo so we can + // have some information if the executable is sandboxed (aka no access to + // /proc/cpuinfo). + Aarch64Info info = kEmptyAarch64Info; + + FillProcCpuInfoData(&info); + CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, + CpuFeatures_GetHardwareCapabilities(), + &info.features); + + return info; +} + +//////////////////////////////////////////////////////////////////////////////// +// Introspection functions + +int GetAarch64FeaturesEnumValue(const Aarch64Features* features, + Aarch64FeaturesEnum value) { + switch (value) { + case AARCH64_FP: + return features->fp; + case AARCH64_ASIMD: + return features->asimd; + case AARCH64_AES: + return features->aes; + case AARCH64_PMULL: + return features->pmull; + case AARCH64_SHA1: + return features->sha1; + case AARCH64_SHA2: + return features->sha2; + case AARCH64_CRC32: + return features->crc32; + case AARCH64_LAST_: + break; + } + return false; +} + +const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) { + switch (value) { + case AARCH64_FP: + return "fp"; + case AARCH64_ASIMD: + return "asimd"; + case AARCH64_AES: + return "aes"; + case AARCH64_PMULL: + return "pmull"; + case AARCH64_SHA1: + return "sha1"; + case AARCH64_SHA2: + return "sha2"; + case AARCH64_CRC32: + return "crc32"; + case AARCH64_LAST_: + break; + } + return "unknown feature"; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c new file mode 100644 index 000000000000..afbb9f1937e8 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c @@ -0,0 +1,259 @@ +// 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. + +#include "cpuinfo_arm.h" + +#include "internal/bit_utils.h" +#include "internal/filesystem.h" +#include "internal/hwcaps.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include "internal/unix_features_aggregator.h" + +#include + +DECLARE_SETTER(ArmFeatures, vfp) +DECLARE_SETTER(ArmFeatures, iwmmxt) +DECLARE_SETTER(ArmFeatures, neon) +DECLARE_SETTER(ArmFeatures, vfpv3) +DECLARE_SETTER(ArmFeatures, vfpv3d16) +DECLARE_SETTER(ArmFeatures, vfpv4) +DECLARE_SETTER(ArmFeatures, idiva) +DECLARE_SETTER(ArmFeatures, idivt) +DECLARE_SETTER(ArmFeatures, aes) +DECLARE_SETTER(ArmFeatures, pmull) +DECLARE_SETTER(ArmFeatures, sha1) +DECLARE_SETTER(ArmFeatures, sha2) +DECLARE_SETTER(ArmFeatures, crc32) + +static const CapabilityConfig kConfigs[] = { + {{ARM_HWCAP_VFP, 0}, "vfp", &set_vfp}, // + {{ARM_HWCAP_IWMMXT, 0}, "iwmmxt", &set_iwmmxt}, // + {{ARM_HWCAP_NEON, 0}, "neon", &set_neon}, // + {{ARM_HWCAP_VFPV3, 0}, "vfpv3", &set_vfpv3}, // + {{ARM_HWCAP_VFPV3D16, 0}, "vfpv3d16", &set_vfpv3d16}, // + {{ARM_HWCAP_VFPV4, 0}, "vfpv4", &set_vfpv4}, // + {{ARM_HWCAP_IDIVA, 0}, "idiva", &set_idiva}, // + {{ARM_HWCAP_IDIVT, 0}, "idivt", &set_idivt}, // + {{0, ARM_HWCAP2_AES}, "aes", &set_aes}, // + {{0, ARM_HWCAP2_PMULL}, "pmull", &set_pmull}, // + {{0, ARM_HWCAP2_SHA1}, "sha1", &set_sha1}, // + {{0, ARM_HWCAP2_SHA2}, "sha2", &set_sha2}, // + {{0, ARM_HWCAP2_CRC32}, "crc32", &set_crc32}, // +}; + +static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); + +typedef struct { + bool processor_reports_armv6; + bool hardware_reports_goldfish; +} ProcCpuInfoData; + +static int IndexOfNonDigit(StringView str) { + size_t index = 0; + while (str.size && isdigit(CpuFeatures_StringView_Front(str))) { + str = CpuFeatures_StringView_PopFront(str, 1); + ++index; + } + return index; +} + +static bool HandleArmLine(const LineResult result, ArmInfo* const info, + ProcCpuInfoData* const proc_info) { + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { + if (CpuFeatures_StringView_IsEquals(key, str("Features"))) { + CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) { + info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) { + info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) { + info->part = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) { + info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); + } else if (CpuFeatures_StringView_IsEquals(key, str("CPU architecture"))) { + // CPU architecture is a number that may be followed by letters. e.g. + // "6TEJ", "7". + const StringView digits = + CpuFeatures_StringView_KeepFront(value, IndexOfNonDigit(value)); + info->architecture = CpuFeatures_StringView_ParsePositiveNumber(digits); + } else if (CpuFeatures_StringView_IsEquals(key, str("Processor"))) { + proc_info->processor_reports_armv6 = + CpuFeatures_StringView_IndexOf(value, str("(v6l)")) >= 0; + } else if (CpuFeatures_StringView_IsEquals(key, str("Hardware"))) { + proc_info->hardware_reports_goldfish = + CpuFeatures_StringView_IsEquals(value, str("Goldfish")); + } + } + return !result.eof; +} + +uint32_t GetArmCpuId(const ArmInfo* const info) { + return (ExtractBitRange(info->implementer, 7, 0) << 24) | + (ExtractBitRange(info->variant, 3, 0) << 20) | + (ExtractBitRange(info->part, 11, 0) << 4) | + (ExtractBitRange(info->revision, 3, 0) << 0); +} + +static void FixErrors(ArmInfo* const info, + ProcCpuInfoData* const proc_cpu_info_data) { + // Fixing Samsung kernel reporting invalid cpu architecture. + // http://code.google.com/p/android/issues/detail?id=10812 + if (proc_cpu_info_data->processor_reports_armv6 && info->architecture >= 7) { + info->architecture = 6; + } + + // Handle kernel configuration bugs that prevent the correct reporting of CPU + // features. + switch (GetArmCpuId(info)) { + case 0x4100C080: + // Special case: The emulator-specific Android 4.2 kernel fails to report + // support for the 32-bit ARM IDIV instruction. Technically, this is a + // feature of the virtual CPU implemented by the emulator. Note that it + // could also support Thumb IDIV in the future, and this will have to be + // slightly updated. + if (info->architecture >= 7 && + proc_cpu_info_data->hardware_reports_goldfish) { + info->features.idiva = true; + } + break; + case 0x511004D0: + // https://crbug.com/341598. + info->features.neon = false; + break; + case 0x510006F2: + case 0x510006F3: + // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report + // IDIV support. + info->features.idiva = true; + info->features.idivt = true; + break; + } + + // Propagate cpu features. + if (info->features.vfpv4) info->features.vfpv3 = true; + if (info->features.neon) info->features.vfpv3 = true; + if (info->features.vfpv3) info->features.vfp = true; +} + +static void FillProcCpuInfoData(ArmInfo* const info, + ProcCpuInfoData* proc_cpu_info_data) { + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) { + if (!HandleArmLine(StackLineReader_NextLine(&reader), info, + proc_cpu_info_data)) { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const ArmInfo kEmptyArmInfo; + +static const ProcCpuInfoData kEmptyProcCpuInfoData; + +ArmInfo GetArmInfo(void) { + // capabilities are fetched from both getauxval and /proc/cpuinfo so we can + // have some information if the executable is sandboxed (aka no access to + // /proc/cpuinfo). + ArmInfo info = kEmptyArmInfo; + ProcCpuInfoData proc_cpu_info_data = kEmptyProcCpuInfoData; + + FillProcCpuInfoData(&info, &proc_cpu_info_data); + CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, + CpuFeatures_GetHardwareCapabilities(), + &info.features); + + FixErrors(&info, &proc_cpu_info_data); + + return info; +} + +//////////////////////////////////////////////////////////////////////////////// +// Introspection functions + +int GetArmFeaturesEnumValue(const ArmFeatures* features, + ArmFeaturesEnum value) { + switch (value) { + case ARM_VFP: + return features->vfp; + case ARM_IWMMXT: + return features->iwmmxt; + case ARM_NEON: + return features->neon; + case ARM_VFPV3: + return features->vfpv3; + case ARM_VFPV3D16: + return features->vfpv3d16; + case ARM_VFPV4: + return features->vfpv4; + case ARM_IDIVA: + return features->idiva; + case ARM_IDIVT: + return features->idivt; + case ARM_AES: + return features->aes; + case ARM_PMULL: + return features->pmull; + case ARM_SHA1: + return features->sha1; + case ARM_SHA2: + return features->sha2; + case ARM_CRC32: + return features->crc32; + case ARM_LAST_: + break; + } + return false; +} + +const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) { + switch (value) { + case ARM_VFP: + return "vfp"; + case ARM_IWMMXT: + return "iwmmxt"; + case ARM_NEON: + return "neon"; + case ARM_VFPV3: + return "vfpv3"; + case ARM_VFPV3D16: + return "vfpv3d16"; + case ARM_VFPV4: + return "vfpv4"; + case ARM_IDIVA: + return "idiva"; + case ARM_IDIVT: + return "idivt"; + case ARM_AES: + return "aes"; + case ARM_PMULL: + return "pmull"; + case ARM_SHA1: + return "sha1"; + case ARM_SHA2: + return "sha2"; + case ARM_CRC32: + return "crc32"; + case ARM_LAST_: + break; + } + return "unknown feature"; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c new file mode 100644 index 000000000000..706d55535b3e --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c @@ -0,0 +1,104 @@ +// 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. + +#include "cpuinfo_mips.h" + +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include "internal/unix_features_aggregator.h" + +DECLARE_SETTER(MipsFeatures, msa) +DECLARE_SETTER(MipsFeatures, eva) +DECLARE_SETTER(MipsFeatures, r6) + +static const CapabilityConfig kConfigs[] = { + {{MIPS_HWCAP_MSA, 0}, "msa", &set_msa}, // + {{0, 0}, "eva", &set_eva}, // + {{MIPS_HWCAP_R6, 0}, "r6", &set_r6}, // +}; +static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); + +static bool HandleMipsLine(const LineResult result, + MipsFeatures* const features) { + StringView key, value; + // See tests for an example. + if (CpuFeatures_StringView_GetAttributeKeyValue(result.line, &key, &value)) { + if (CpuFeatures_StringView_IsEquals(key, str("ASEs implemented"))) { + CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, features); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(MipsFeatures* const features) { + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) { + if (!HandleMipsLine(StackLineReader_NextLine(&reader), features)) { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const MipsInfo kEmptyMipsInfo; + +MipsInfo GetMipsInfo(void) { + // capabilities are fetched from both getauxval and /proc/cpuinfo so we can + // have some information if the executable is sandboxed (aka no access to + // /proc/cpuinfo). + MipsInfo info = kEmptyMipsInfo; + + FillProcCpuInfoData(&info.features); + CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, + CpuFeatures_GetHardwareCapabilities(), + &info.features); + return info; +} + +//////////////////////////////////////////////////////////////////////////////// +// Introspection functions + +int GetMipsFeaturesEnumValue(const MipsFeatures* features, + MipsFeaturesEnum value) { + switch (value) { + case MIPS_MSA: + return features->msa; + case MIPS_EVA: + return features->eva; + case MIPS_R6: + return features->r6; + case MIPS_LAST_: + break; + } + return false; +} + +const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value) { + switch (value) { + case MIPS_MSA: + return "msa"; + case MIPS_EVA: + return "eva"; + case MIPS_R6: + return "r6"; + case MIPS_LAST_: + break; + } + return "unknown feature"; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c new file mode 100644 index 000000000000..53d2059c3205 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c @@ -0,0 +1,358 @@ +// Copyright 2018 IBM. +// +// 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. + +#include +#include + +#include "cpuinfo_ppc.h" +#include "internal/bit_utils.h" +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include "internal/unix_features_aggregator.h" + +DECLARE_SETTER(PPCFeatures, ppc32) +DECLARE_SETTER(PPCFeatures, ppc64) +DECLARE_SETTER(PPCFeatures, ppc601) +DECLARE_SETTER(PPCFeatures, altivec) +DECLARE_SETTER(PPCFeatures, fpu) +DECLARE_SETTER(PPCFeatures, mmu) +DECLARE_SETTER(PPCFeatures, mac_4xx) +DECLARE_SETTER(PPCFeatures, unifiedcache) +DECLARE_SETTER(PPCFeatures, spe) +DECLARE_SETTER(PPCFeatures, efpsingle) +DECLARE_SETTER(PPCFeatures, efpdouble) +DECLARE_SETTER(PPCFeatures, no_tb) +DECLARE_SETTER(PPCFeatures, power4) +DECLARE_SETTER(PPCFeatures, power5) +DECLARE_SETTER(PPCFeatures, power5plus) +DECLARE_SETTER(PPCFeatures, cell) +DECLARE_SETTER(PPCFeatures, booke) +DECLARE_SETTER(PPCFeatures, smt) +DECLARE_SETTER(PPCFeatures, icachesnoop) +DECLARE_SETTER(PPCFeatures, arch205) +DECLARE_SETTER(PPCFeatures, pa6t) +DECLARE_SETTER(PPCFeatures, dfp) +DECLARE_SETTER(PPCFeatures, power6ext) +DECLARE_SETTER(PPCFeatures, arch206) +DECLARE_SETTER(PPCFeatures, vsx) +DECLARE_SETTER(PPCFeatures, pseries_perfmon_compat) +DECLARE_SETTER(PPCFeatures, truele) +DECLARE_SETTER(PPCFeatures, ppcle) +DECLARE_SETTER(PPCFeatures, arch207) +DECLARE_SETTER(PPCFeatures, htm) +DECLARE_SETTER(PPCFeatures, dscr) +DECLARE_SETTER(PPCFeatures, ebb) +DECLARE_SETTER(PPCFeatures, isel) +DECLARE_SETTER(PPCFeatures, tar) +DECLARE_SETTER(PPCFeatures, vcrypto) +DECLARE_SETTER(PPCFeatures, htm_nosc) +DECLARE_SETTER(PPCFeatures, arch300) +DECLARE_SETTER(PPCFeatures, ieee128) +DECLARE_SETTER(PPCFeatures, darn) +DECLARE_SETTER(PPCFeatures, scv) +DECLARE_SETTER(PPCFeatures, htm_no_suspend) + +static const CapabilityConfig kConfigs[] = { + {{PPC_FEATURE_32, 0}, "ppc32", &set_ppc32}, + {{PPC_FEATURE_64, 0}, "ppc64", &set_ppc64}, + {{PPC_FEATURE_601_INSTR, 0}, "ppc601", &set_ppc601}, + {{PPC_FEATURE_HAS_ALTIVEC, 0}, "altivec", &set_altivec}, + {{PPC_FEATURE_HAS_FPU, 0}, "fpu", &set_fpu}, + {{PPC_FEATURE_HAS_MMU, 0}, "mmu", &set_mmu}, + {{PPC_FEATURE_HAS_4xxMAC, 0}, "4xxmac", &set_mac_4xx}, + {{PPC_FEATURE_UNIFIED_CACHE, 0}, "ucache", &set_unifiedcache}, + {{PPC_FEATURE_HAS_SPE, 0}, "spe", &set_spe}, + {{PPC_FEATURE_HAS_EFP_SINGLE, 0}, "efpsingle", &set_efpsingle}, + {{PPC_FEATURE_HAS_EFP_DOUBLE, 0}, "efpdouble", &set_efpdouble}, + {{PPC_FEATURE_NO_TB, 0}, "notb", &set_no_tb}, + {{PPC_FEATURE_POWER4, 0}, "power4", &set_power4}, + {{PPC_FEATURE_POWER5, 0}, "power5", &set_power5}, + {{PPC_FEATURE_POWER5_PLUS, 0}, "power5+", &set_power5plus}, + {{PPC_FEATURE_CELL, 0}, "cellbe", &set_cell}, + {{PPC_FEATURE_BOOKE, 0}, "booke", &set_booke}, + {{PPC_FEATURE_SMT, 0}, "smt", &set_smt}, + {{PPC_FEATURE_ICACHE_SNOOP, 0}, "ic_snoop", &set_icachesnoop}, + {{PPC_FEATURE_ARCH_2_05, 0}, "arch_2_05", &set_arch205}, + {{PPC_FEATURE_PA6T, 0}, "pa6t", &set_pa6t}, + {{PPC_FEATURE_HAS_DFP, 0}, "dfp", &set_dfp}, + {{PPC_FEATURE_POWER6_EXT, 0}, "power6x", &set_power6ext}, + {{PPC_FEATURE_ARCH_2_06, 0}, "arch_2_06", &set_arch206}, + {{PPC_FEATURE_HAS_VSX, 0}, "vsx", &set_vsx}, + {{PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0}, + "archpmu", + &set_pseries_perfmon_compat}, + {{PPC_FEATURE_TRUE_LE, 0}, "true_le", &set_truele}, + {{PPC_FEATURE_PPC_LE, 0}, "ppcle", &set_ppcle}, + {{0, PPC_FEATURE2_ARCH_2_07}, "arch_2_07", &set_arch207}, + {{0, PPC_FEATURE2_HTM}, "htm", &set_htm}, + {{0, PPC_FEATURE2_DSCR}, "dscr", &set_dscr}, + {{0, PPC_FEATURE2_EBB}, "ebb", &set_ebb}, + {{0, PPC_FEATURE2_ISEL}, "isel", &set_isel}, + {{0, PPC_FEATURE2_TAR}, "tar", &set_tar}, + {{0, PPC_FEATURE2_VEC_CRYPTO}, "vcrypto", &set_vcrypto}, + {{0, PPC_FEATURE2_HTM_NOSC}, "htm-nosc", &set_htm_nosc}, + {{0, PPC_FEATURE2_ARCH_3_00}, "arch_3_00", &set_arch300}, + {{0, PPC_FEATURE2_HAS_IEEE128}, "ieee128", &set_ieee128}, + {{0, PPC_FEATURE2_DARN}, "darn", &set_darn}, + {{0, PPC_FEATURE2_SCV}, "scv", &set_scv}, + {{0, PPC_FEATURE2_HTM_NO_SUSPEND}, "htm-no-suspend", &set_htm_no_suspend}, +}; +static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); + +static bool HandlePPCLine(const LineResult result, + PPCPlatformStrings* const strings) { + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { + if (CpuFeatures_StringView_HasWord(key, "platform")) { + CpuFeatures_StringView_CopyString(value, strings->platform, + sizeof(strings->platform)); + } else if (CpuFeatures_StringView_IsEquals(key, str("model"))) { + CpuFeatures_StringView_CopyString(value, strings->model, + sizeof(strings->platform)); + } else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) { + CpuFeatures_StringView_CopyString(value, strings->machine, + sizeof(strings->platform)); + } else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) { + CpuFeatures_StringView_CopyString(value, strings->cpu, + sizeof(strings->platform)); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(PPCPlatformStrings* const strings) { + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) { + if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const PPCInfo kEmptyPPCInfo; + +PPCInfo GetPPCInfo(void) { + /* + * On Power feature flags aren't currently in cpuinfo so we only look at + * the auxilary vector. + */ + PPCInfo info = kEmptyPPCInfo; + + CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, + CpuFeatures_GetHardwareCapabilities(), + &info.features); + return info; +} + +static const PPCPlatformStrings kEmptyPPCPlatformStrings; + +PPCPlatformStrings GetPPCPlatformStrings(void) { + PPCPlatformStrings strings = kEmptyPPCPlatformStrings; + + FillProcCpuInfoData(&strings); + strings.type = CpuFeatures_GetPlatformType(); + return strings; +} + +//////////////////////////////////////////////////////////////////////////////// +// Introspection functions + +int GetPPCFeaturesEnumValue(const PPCFeatures* features, + PPCFeaturesEnum value) { + switch (value) { + case PPC_32: + return features->ppc32; + case PPC_64: + return features->ppc64; + case PPC_601_INSTR: + return features->ppc601; + case PPC_HAS_ALTIVEC: + return features->altivec; + case PPC_HAS_FPU: + return features->fpu; + case PPC_HAS_MMU: + return features->mmu; + case PPC_HAS_4xxMAC: + return features->mac_4xx; + case PPC_UNIFIED_CACHE: + return features->unifiedcache; + case PPC_HAS_SPE: + return features->spe; + case PPC_HAS_EFP_SINGLE: + return features->efpsingle; + case PPC_HAS_EFP_DOUBLE: + return features->efpdouble; + case PPC_NO_TB: + return features->no_tb; + case PPC_POWER4: + return features->power4; + case PPC_POWER5: + return features->power5; + case PPC_POWER5_PLUS: + return features->power5plus; + case PPC_CELL: + return features->cell; + case PPC_BOOKE: + return features->booke; + case PPC_SMT: + return features->smt; + case PPC_ICACHE_SNOOP: + return features->icachesnoop; + case PPC_ARCH_2_05: + return features->arch205; + case PPC_PA6T: + return features->pa6t; + case PPC_HAS_DFP: + return features->dfp; + case PPC_POWER6_EXT: + return features->power6ext; + case PPC_ARCH_2_06: + return features->arch206; + case PPC_HAS_VSX: + return features->vsx; + case PPC_PSERIES_PERFMON_COMPAT: + return features->pseries_perfmon_compat; + case PPC_TRUE_LE: + return features->truele; + case PPC_PPC_LE: + return features->ppcle; + case PPC_ARCH_2_07: + return features->arch207; + case PPC_HTM: + return features->htm; + case PPC_DSCR: + return features->dscr; + case PPC_EBB: + return features->ebb; + case PPC_ISEL: + return features->isel; + case PPC_TAR: + return features->tar; + case PPC_VEC_CRYPTO: + return features->vcrypto; + case PPC_HTM_NOSC: + return features->htm_nosc; + case PPC_ARCH_3_00: + return features->arch300; + case PPC_HAS_IEEE128: + return features->ieee128; + case PPC_DARN: + return features->darn; + case PPC_SCV: + return features->scv; + case PPC_HTM_NO_SUSPEND: + return features->htm_no_suspend; + case PPC_LAST_: + break; + } + return false; +} + +/* Have used the same names as glibc */ +const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) { + switch (value) { + case PPC_32: + return "ppc32"; + case PPC_64: + return "ppc64"; + case PPC_601_INSTR: + return "ppc601"; + case PPC_HAS_ALTIVEC: + return "altivec"; + case PPC_HAS_FPU: + return "fpu"; + case PPC_HAS_MMU: + return "mmu"; + case PPC_HAS_4xxMAC: + return "4xxmac"; + case PPC_UNIFIED_CACHE: + return "ucache"; + case PPC_HAS_SPE: + return "spe"; + case PPC_HAS_EFP_SINGLE: + return "efpsingle"; + case PPC_HAS_EFP_DOUBLE: + return "efpdouble"; + case PPC_NO_TB: + return "notb"; + case PPC_POWER4: + return "power4"; + case PPC_POWER5: + return "power5"; + case PPC_POWER5_PLUS: + return "power5+"; + case PPC_CELL: + return "cellbe"; + case PPC_BOOKE: + return "booke"; + case PPC_SMT: + return "smt"; + case PPC_ICACHE_SNOOP: + return "ic_snoop"; + case PPC_ARCH_2_05: + return "arch_2_05"; + case PPC_PA6T: + return "pa6t"; + case PPC_HAS_DFP: + return "dfp"; + case PPC_POWER6_EXT: + return "power6x"; + case PPC_ARCH_2_06: + return "arch_2_06"; + case PPC_HAS_VSX: + return "vsx"; + case PPC_PSERIES_PERFMON_COMPAT: + return "archpmu"; + case PPC_TRUE_LE: + return "true_le"; + case PPC_PPC_LE: + return "ppcle"; + case PPC_ARCH_2_07: + return "arch_2_07"; + case PPC_HTM: + return "htm"; + case PPC_DSCR: + return "dscr"; + case PPC_EBB: + return "ebb"; + case PPC_ISEL: + return "isel"; + case PPC_TAR: + return "tar"; + case PPC_VEC_CRYPTO: + return "vcrypto"; + case PPC_HTM_NOSC: + return "htm-nosc"; + case PPC_ARCH_3_00: + return "arch_3_00"; + case PPC_HAS_IEEE128: + return "ieee128"; + case PPC_DARN: + return "darn"; + case PPC_SCV: + return "scv"; + case PPC_HTM_NO_SUSPEND: + return "htm-no-suspend"; + case PPC_LAST_: + break; + } + return "unknown_feature"; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c new file mode 100644 index 000000000000..52f178fbb0b1 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c @@ -0,0 +1,518 @@ +// 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. + +#include "cpuinfo_x86.h" +#include "internal/bit_utils.h" +#include "internal/cpuid_x86.h" + +#include +#include + +#if !defined(CPU_FEATURES_ARCH_X86) +#error "Cannot compile cpuinfo_x86 on a non x86 platform." +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for CpuId and GetXCR0Eax. +//////////////////////////////////////////////////////////////////////////////// + +#if defined(CPU_FEATURES_MOCK_CPUID_X86) +// Implementation will be provided by test/cpuinfo_x86_test.cc. +#elif defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) + +#include + +Leaf CpuId(uint32_t leaf_id) { + Leaf leaf; + __cpuid_count(leaf_id, 0, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx); + return leaf; +} + +uint32_t GetXCR0Eax(void) { + uint32_t eax, edx; + /* named form of xgetbv not supported on OSX, so must use byte form, see: + https://github.com/asmjit/asmjit/issues/78 + */ + __asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0)); + return eax; +} + +#elif defined(CPU_FEATURES_COMPILER_MSC) + +#include +#include // For __cpuidex() + +Leaf CpuId(uint32_t leaf_id) { + Leaf leaf; + int data[4]; + __cpuid(data, leaf_id); + leaf.eax = data[0]; + leaf.ebx = data[1]; + leaf.ecx = data[2]; + leaf.edx = data[3]; + return leaf; +} + +uint32_t GetXCR0Eax(void) { return _xgetbv(0); } + +#else +#error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC." +#endif + +static const Leaf kEmptyLeaf; + +static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) { + if (leaf_id <= max_cpuid_leaf) { + return CpuId(leaf_id); + } else { + return kEmptyLeaf; + } +} + +#define MASK_XMM 0x2 +#define MASK_YMM 0x4 +#define MASK_MASKREG 0x20 +#define MASK_ZMM0_15 0x40 +#define MASK_ZMM16_31 0x80 + +static bool HasMask(uint32_t value, uint32_t mask) { + return (value & mask) == mask; +} + +// Checks that operating system saves and restores xmm registers during context +// switches. +static bool HasXmmOsXSave(uint32_t xcr0_eax) { + return HasMask(xcr0_eax, MASK_XMM); +} + +// Checks that operating system saves and restores ymm registers during context +// switches. +static bool HasYmmOsXSave(uint32_t xcr0_eax) { + return HasMask(xcr0_eax, MASK_XMM | MASK_YMM); +} + +// Checks that operating system saves and restores zmm registers during context +// switches. +static bool HasZmmOsXSave(uint32_t xcr0_eax) { + return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 | + MASK_ZMM16_31); +} + +static void SetVendor(const Leaf leaf, char* const vendor) { + *(uint32_t*)(vendor) = leaf.ebx; + *(uint32_t*)(vendor + 4) = leaf.edx; + *(uint32_t*)(vendor + 8) = leaf.ecx; + vendor[12] = '\0'; +} + +static int IsVendor(const Leaf leaf, const char* const name) { + const uint32_t ebx = *(const uint32_t*)(name); + const uint32_t edx = *(const uint32_t*)(name + 4); + const uint32_t ecx = *(const uint32_t*)(name + 8); + return leaf.ebx == ebx && leaf.ecx == ecx && leaf.edx == edx; +} + +// Reference https://en.wikipedia.org/wiki/CPUID. +static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info) { + const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1); + const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7); + + const bool have_xsave = IsBitSet(leaf_1.ecx, 26); + const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); + const uint32_t xcr0_eax = (have_xsave && have_osxsave) ? GetXCR0Eax() : 0; + const bool have_sse_os_support = HasXmmOsXSave(xcr0_eax); + const bool have_avx_os_support = HasYmmOsXSave(xcr0_eax); + const bool have_avx512_os_support = HasZmmOsXSave(xcr0_eax); + + const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); + const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); + const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4); + const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16); + + X86Features* const features = &info->features; + + info->family = extended_family + family; + info->model = (extended_model << 4) + model; + info->stepping = ExtractBitRange(leaf_1.eax, 3, 0); + + features->smx = IsBitSet(leaf_1.ecx, 6); + features->cx16 = IsBitSet(leaf_1.ecx, 13); + features->movbe = IsBitSet(leaf_1.ecx, 22); + features->popcnt = IsBitSet(leaf_1.ecx, 23); + features->aes = IsBitSet(leaf_1.ecx, 25); + features->f16c = IsBitSet(leaf_1.ecx, 29); + features->rdrnd = IsBitSet(leaf_1.ecx, 30); + features->sgx = IsBitSet(leaf_7.ebx, 2); + features->bmi1 = IsBitSet(leaf_7.ebx, 3); + features->bmi2 = IsBitSet(leaf_7.ebx, 8); + features->erms = IsBitSet(leaf_7.ebx, 9); + features->sha = IsBitSet(leaf_7.ebx, 29); + features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); + + if (have_sse_os_support) { + features->ssse3 = IsBitSet(leaf_1.ecx, 9); + features->sse4_1 = IsBitSet(leaf_1.ecx, 19); + features->sse4_2 = IsBitSet(leaf_1.ecx, 20); + } + + if (have_avx_os_support) { + features->fma3 = IsBitSet(leaf_1.ecx, 12); + features->avx = IsBitSet(leaf_1.ecx, 28); + features->avx2 = IsBitSet(leaf_7.ebx, 5); + } + + if (have_avx512_os_support) { + features->avx512f = IsBitSet(leaf_7.ebx, 16); + features->avx512cd = IsBitSet(leaf_7.ebx, 28); + features->avx512er = IsBitSet(leaf_7.ebx, 27); + features->avx512pf = IsBitSet(leaf_7.ebx, 26); + features->avx512bw = IsBitSet(leaf_7.ebx, 30); + features->avx512dq = IsBitSet(leaf_7.ebx, 17); + features->avx512vl = IsBitSet(leaf_7.ebx, 31); + features->avx512ifma = IsBitSet(leaf_7.ebx, 21); + features->avx512vbmi = IsBitSet(leaf_7.ecx, 1); + features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6); + features->avx512vnni = IsBitSet(leaf_7.ecx, 11); + features->avx512bitalg = IsBitSet(leaf_7.ecx, 12); + features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14); + features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2); + features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3); + } +} + +static const X86Info kEmptyX86Info; + +X86Info GetX86Info(void) { + X86Info info = kEmptyX86Info; + const Leaf leaf_0 = CpuId(0); + const uint32_t max_cpuid_leaf = leaf_0.eax; + SetVendor(leaf_0, info.vendor); + if (IsVendor(leaf_0, "GenuineIntel") || IsVendor(leaf_0, "AuthenticAMD")) { + ParseCpuId(max_cpuid_leaf, &info); + } + return info; +} + +#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) + +X86Microarchitecture GetX86Microarchitecture(const X86Info* info) { + if (memcmp(info->vendor, "GenuineIntel", sizeof(info->vendor)) == 0) { + switch (CPUID(info->family, info->model)) { + case CPUID(0x06, 0x35): + case CPUID(0x06, 0x36): + // https://en.wikipedia.org/wiki/Bonnell_(microarchitecture) + return INTEL_ATOM_BNL; + case CPUID(0x06, 0x37): + case CPUID(0x06, 0x4C): + // https://en.wikipedia.org/wiki/Silvermont + return INTEL_ATOM_SMT; + case CPUID(0x06, 0x5C): + // https://en.wikipedia.org/wiki/Goldmont + return INTEL_ATOM_GMT; + case CPUID(0x06, 0x0F): + case CPUID(0x06, 0x16): + // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) + return INTEL_CORE; + case CPUID(0x06, 0x17): + case CPUID(0x06, 0x1D): + // https://en.wikipedia.org/wiki/Penryn_(microarchitecture) + return INTEL_PNR; + case CPUID(0x06, 0x1A): + case CPUID(0x06, 0x1E): + case CPUID(0x06, 0x1F): + case CPUID(0x06, 0x2E): + // https://en.wikipedia.org/wiki/Nehalem_(microarchitecture) + return INTEL_NHM; + case CPUID(0x06, 0x25): + case CPUID(0x06, 0x2C): + case CPUID(0x06, 0x2F): + // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) + return INTEL_WSM; + case CPUID(0x06, 0x2A): + case CPUID(0x06, 0x2D): + // https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings + return INTEL_SNB; + case CPUID(0x06, 0x3A): + case CPUID(0x06, 0x3E): + // https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings + return INTEL_IVB; + case CPUID(0x06, 0x3C): + case CPUID(0x06, 0x3F): + case CPUID(0x06, 0x45): + case CPUID(0x06, 0x46): + // https://en.wikipedia.org/wiki/Haswell_(microarchitecture) + return INTEL_HSW; + case CPUID(0x06, 0x3D): + case CPUID(0x06, 0x47): + case CPUID(0x06, 0x4F): + case CPUID(0x06, 0x56): + // https://en.wikipedia.org/wiki/Broadwell_(microarchitecture) + return INTEL_BDW; + case CPUID(0x06, 0x4E): + case CPUID(0x06, 0x55): + case CPUID(0x06, 0x5E): + // https://en.wikipedia.org/wiki/Skylake_(microarchitecture) + return INTEL_SKL; + case CPUID(0x06, 0x8E): + case CPUID(0x06, 0x9E): + // https://en.wikipedia.org/wiki/Kaby_Lake + return INTEL_KBL; + default: + return X86_UNKNOWN; + } + } + if (memcmp(info->vendor, "AuthenticAMD", sizeof(info->vendor)) == 0) { + switch (info->family) { + // https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures + case 0x0F: + return AMD_HAMMER; + case 0x10: + return AMD_K10; + case 0x14: + return AMD_BOBCAT; + case 0x15: + return AMD_BULLDOZER; + case 0x16: + return AMD_JAGUAR; + case 0x17: + return AMD_ZEN; + default: + return X86_UNKNOWN; + } + } + return X86_UNKNOWN; +} + +static void SetString(const uint32_t max_cpuid_ext_leaf, const uint32_t leaf_id, + char* buffer) { + const Leaf leaf = SafeCpuId(max_cpuid_ext_leaf, leaf_id); + // We allow calling memcpy from SetString which is only called when requesting + // X86BrandString. + memcpy(buffer, &leaf, sizeof(Leaf)); +} + +void FillX86BrandString(char brand_string[49]) { + const Leaf leaf_ext_0 = CpuId(0x80000000); + const uint32_t max_cpuid_leaf_ext = leaf_ext_0.eax; + SetString(max_cpuid_leaf_ext, 0x80000002, brand_string); + SetString(max_cpuid_leaf_ext, 0x80000003, brand_string + 16); + SetString(max_cpuid_leaf_ext, 0x80000004, brand_string + 32); + brand_string[48] = '\0'; +} + +//////////////////////////////////////////////////////////////////////////////// +// Introspection functions + +int GetX86FeaturesEnumValue(const X86Features* features, + X86FeaturesEnum value) { + switch (value) { + case X86_AES: + return features->aes; + case X86_ERMS: + return features->erms; + case X86_F16C: + return features->f16c; + case X86_FMA3: + return features->fma3; + case X86_VPCLMULQDQ: + return features->vpclmulqdq; + case X86_BMI1: + return features->bmi1; + case X86_BMI2: + return features->bmi2; + case X86_SSSE3: + return features->ssse3; + case X86_SSE4_1: + return features->sse4_1; + case X86_SSE4_2: + return features->sse4_2; + case X86_AVX: + return features->avx; + case X86_AVX2: + return features->avx2; + case X86_AVX512F: + return features->avx512f; + case X86_AVX512CD: + return features->avx512cd; + case X86_AVX512ER: + return features->avx512er; + case X86_AVX512PF: + return features->avx512pf; + case X86_AVX512BW: + return features->avx512bw; + case X86_AVX512DQ: + return features->avx512dq; + case X86_AVX512VL: + return features->avx512vl; + case X86_AVX512IFMA: + return features->avx512ifma; + case X86_AVX512VBMI: + return features->avx512vbmi; + case X86_AVX512VBMI2: + return features->avx512vbmi2; + case X86_AVX512VNNI: + return features->avx512vnni; + case X86_AVX512BITALG: + return features->avx512bitalg; + case X86_AVX512VPOPCNTDQ: + return features->avx512vpopcntdq; + case X86_AVX512_4VNNIW: + return features->avx512_4vnniw; + case X86_AVX512_4VBMI2: + return features->avx512_4vbmi2; + case X86_SMX: + return features->smx; + case X86_SGX: + return features->sgx; + case X86_CX16: + return features->cx16; + case X86_SHA: + return features->sha; + case X86_POPCNT: + return features->popcnt; + case X86_MOVBE: + return features->movbe; + case X86_RDRND: + return features->rdrnd; + case X86_LAST_: + break; + } + return false; +} + +const char* GetX86FeaturesEnumName(X86FeaturesEnum value) { + switch (value) { + case X86_AES: + return "aes"; + case X86_ERMS: + return "erms"; + case X86_F16C: + return "f16c"; + case X86_FMA3: + return "fma3"; + case X86_VPCLMULQDQ: + return "vpclmulqdq"; + case X86_BMI1: + return "bmi1"; + case X86_BMI2: + return "bmi2"; + case X86_SSSE3: + return "ssse3"; + case X86_SSE4_1: + return "sse4_1"; + case X86_SSE4_2: + return "sse4_2"; + case X86_AVX: + return "avx"; + case X86_AVX2: + return "avx2"; + case X86_AVX512F: + return "avx512f"; + case X86_AVX512CD: + return "avx512cd"; + case X86_AVX512ER: + return "avx512er"; + case X86_AVX512PF: + return "avx512pf"; + case X86_AVX512BW: + return "avx512bw"; + case X86_AVX512DQ: + return "avx512dq"; + case X86_AVX512VL: + return "avx512vl"; + case X86_AVX512IFMA: + return "avx512ifma"; + case X86_AVX512VBMI: + return "avx512vbmi"; + case X86_AVX512VBMI2: + return "avx512vbmi2"; + case X86_AVX512VNNI: + return "avx512vnni"; + case X86_AVX512BITALG: + return "avx512bitalg"; + case X86_AVX512VPOPCNTDQ: + return "avx512vpopcntdq"; + case X86_AVX512_4VNNIW: + return "avx512_4vnniw"; + case X86_AVX512_4VBMI2: + return "avx512_4vbmi2"; + case X86_SMX: + return "smx"; + case X86_SGX: + return "sgx"; + case X86_CX16: + return "cx16"; + case X86_SHA: + return "sha"; + case X86_POPCNT: + return "popcnt"; + case X86_MOVBE: + return "movbe"; + case X86_RDRND: + return "rdrnd"; + case X86_LAST_: + break; + } + return "unknown_feature"; +} + +const char* GetX86MicroarchitectureName(X86Microarchitecture uarch) { + switch (uarch) { + case X86_UNKNOWN: + return "X86_UNKNOWN"; + case INTEL_CORE: + return "INTEL_CORE"; + case INTEL_PNR: + return "INTEL_PNR"; + case INTEL_NHM: + return "INTEL_NHM"; + case INTEL_ATOM_BNL: + return "INTEL_ATOM_BNL"; + case INTEL_WSM: + return "INTEL_WSM"; + case INTEL_SNB: + return "INTEL_SNB"; + case INTEL_IVB: + return "INTEL_IVB"; + case INTEL_ATOM_SMT: + return "INTEL_ATOM_SMT"; + case INTEL_HSW: + return "INTEL_HSW"; + case INTEL_BDW: + return "INTEL_BDW"; + case INTEL_SKL: + return "INTEL_SKL"; + case INTEL_ATOM_GMT: + return "INTEL_ATOM_GMT"; + case INTEL_KBL: + return "INTEL_KBL"; + case INTEL_CFL: + return "INTEL_CFL"; + case INTEL_CNL: + return "INTEL_CNL"; + case AMD_HAMMER: + return "AMD_HAMMER"; + case AMD_K10: + return "AMD_K10"; + case AMD_BOBCAT: + return "AMD_BOBCAT"; + case AMD_BULLDOZER: + return "AMD_BULLDOZER"; + case AMD_JAGUAR: + return "AMD_JAGUAR"; + case AMD_ZEN: + return "AMD_ZEN"; + } + return "unknown microarchitecture"; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/filesystem.c b/cpp/src/arrow/vendored/cpu_features/src/filesystem.c new file mode 100644 index 000000000000..25444da5d71e --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/filesystem.c @@ -0,0 +1,59 @@ +// 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. + +#include "internal/filesystem.h" + +#include +#include +#include +#include + +#if defined(CPU_FEATURES_MOCK_FILESYSTEM) +// Implementation will be provided by test/filesystem_for_testing.cc. +#elif defined(_MSC_VER) +#include +int CpuFeatures_OpenFile(const char* filename) { + return _open(filename, _O_RDONLY); +} + +void CpuFeatures_CloseFile(int file_descriptor) { _close(file_descriptor); } + +int CpuFeatures_ReadFile(int file_descriptor, void* buffer, + size_t buffer_size) { + return _read(file_descriptor, buffer, buffer_size); +} + +#else +#include + +int CpuFeatures_OpenFile(const char* filename) { + int result; + do { + result = open(filename, O_RDONLY); + } while (result == -1L && errno == EINTR); + return result; +} + +void CpuFeatures_CloseFile(int file_descriptor) { close(file_descriptor); } + +int CpuFeatures_ReadFile(int file_descriptor, void* buffer, + size_t buffer_size) { + int result; + do { + result = read(file_descriptor, buffer, buffer_size); + } while (result == -1L && errno == EINTR); + return result; +} + +#endif diff --git a/cpp/src/arrow/vendored/cpu_features/src/hwcaps.c b/cpp/src/arrow/vendored/cpu_features/src/hwcaps.c new file mode 100644 index 000000000000..815e5c185c7d --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/hwcaps.c @@ -0,0 +1,162 @@ +// 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. + +#include +#include + +#include "cpu_features_macros.h" +#include "internal/filesystem.h" +#include "internal/hwcaps.h" +#include "internal/string_view.h" + +#if defined(NDEBUG) +#define D(...) +#else +#include +#define D(...) \ + do { \ + printf(__VA_ARGS__); \ + fflush(stdout); \ + } while (0) +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Implementation of GetElfHwcapFromGetauxval +//////////////////////////////////////////////////////////////////////////////// + +#if defined(CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL) +// Implementation will be provided by test/hwcaps_for_testing.cc. +#elif defined(HAVE_STRONG_GETAUXVAL) +#include +static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) { + return getauxval(hwcap_type); +} +#elif defined(HAVE_DLFCN_H) +// On Android we probe the system's C library for a 'getauxval' function and +// call it if it exits, or return 0 for failure. This function is available +// since API level 20. +// +// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge +// case where some NDK developers use headers for a platform that is newer than +// the one really targetted by their application. This is typically done to use +// newer native APIs only when running on more recent Android versions, and +// requires careful symbol management. +// +// Note that getauxval() can't really be re-implemented here, because its +// implementation does not parse /proc/self/auxv. Instead it depends on values +// that are passed by the kernel at process-init time to the C runtime +// initialization layer. + +#include +#define AT_HWCAP 16 +#define AT_HWCAP2 26 +#define AT_PLATFORM 15 +#define AT_BASE_PLATFORM 24 + +typedef unsigned long getauxval_func_t(unsigned long); + +static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type) { + uint32_t ret = 0; + void* libc_handle = NULL; + getauxval_func_t* func = NULL; + + dlerror(); // Cleaning error state before calling dlopen. + libc_handle = dlopen("libc.so", RTLD_NOW); + if (!libc_handle) { + D("Could not dlopen() C library: %s\n", dlerror()); + return 0; + } + func = (getauxval_func_t*)dlsym(libc_handle, "getauxval"); + if (!func) { + D("Could not find getauxval() in C library\n"); + } else { + // Note: getauxval() returns 0 on failure. Doesn't touch errno. + ret = (uint32_t)(*func)(hwcap_type); + } + dlclose(libc_handle); + return ret; +} +#else +#error "This platform does not provide hardware capabilities." +#endif + +// Implementation of GetHardwareCapabilities for OS that provide +// GetElfHwcapFromGetauxval(). + +// Fallback when getauxval is not available, retrieves hwcaps from +// "/proc/self/auxv". +static uint32_t GetElfHwcapFromProcSelfAuxv(uint32_t hwcap_type) { + struct { + uint32_t tag; + uint32_t value; + } entry; + uint32_t result = 0; + const char filepath[] = "/proc/self/auxv"; + const int fd = CpuFeatures_OpenFile(filepath); + if (fd < 0) { + D("Could not open %s\n", filepath); + return 0; + } + for (;;) { + const int ret = CpuFeatures_ReadFile(fd, (char*)&entry, sizeof entry); + if (ret < 0) { + D("Error while reading %s\n", filepath); + break; + } + // Detect end of list. + if (ret == 0 || (entry.tag == 0 && entry.value == 0)) { + break; + } + if (entry.tag == hwcap_type) { + result = entry.value; + break; + } + } + CpuFeatures_CloseFile(fd); + return result; +} + +// Retrieves hardware capabilities by first trying to call getauxval, if not +// available falls back to reading "/proc/self/auxv". +static unsigned long GetHardwareCapabilitiesFor(uint32_t type) { + unsigned long hwcaps = GetElfHwcapFromGetauxval(type); + if (!hwcaps) { + D("Parsing /proc/self/auxv to extract ELF hwcaps!\n"); + hwcaps = GetElfHwcapFromProcSelfAuxv(type); + } + return hwcaps; +} + +HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) { + HardwareCapabilities capabilities; + capabilities.hwcaps = GetHardwareCapabilitiesFor(AT_HWCAP); + capabilities.hwcaps2 = GetHardwareCapabilitiesFor(AT_HWCAP2); + return capabilities; +} + +PlatformType kEmptyPlatformType; + +PlatformType CpuFeatures_GetPlatformType(void) { + PlatformType type = kEmptyPlatformType; + char *platform = (char *)GetHardwareCapabilitiesFor(AT_PLATFORM); + char *base_platform = (char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM); + + if (platform != NULL) + CpuFeatures_StringView_CopyString(str(platform), type.platform, + sizeof(type.platform)); + if (base_platform != NULL) + CpuFeatures_StringView_CopyString(str(base_platform), type.base_platform, + sizeof(type.base_platform)); + return type; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c b/cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c new file mode 100644 index 000000000000..b2c48ba6df30 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c @@ -0,0 +1,131 @@ +// 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. + +#include "internal/stack_line_reader.h" +#include "internal/filesystem.h" + +#include +#include +#include + +void StackLineReader_Initialize(StackLineReader* reader, int fd) { + reader->view.ptr = reader->buffer; + reader->view.size = 0; + reader->skip_mode = false; + reader->fd = fd; +} + +// Replaces the content of buffer with bytes from the file. +static int LoadFullBuffer(StackLineReader* reader) { + const int read = CpuFeatures_ReadFile(reader->fd, reader->buffer, + STACK_LINE_READER_BUFFER_SIZE); + assert(read >= 0); + reader->view.ptr = reader->buffer; + reader->view.size = read; + return read; +} + +// Appends with bytes from the file to buffer, filling the remaining space. +static int LoadMore(StackLineReader* reader) { + char* const ptr = reader->buffer + reader->view.size; + const size_t size_to_read = STACK_LINE_READER_BUFFER_SIZE - reader->view.size; + const int read = CpuFeatures_ReadFile(reader->fd, ptr, size_to_read); + assert(read >= 0); + assert(read <= (int)size_to_read); + reader->view.size += read; + return read; +} + +static int IndexOfEol(StackLineReader* reader) { + return CpuFeatures_StringView_IndexOfChar(reader->view, '\n'); +} + +// Relocate buffer's pending bytes at the beginning of the array and fills the +// remaining space with bytes from the file. +static int BringToFrontAndLoadMore(StackLineReader* reader) { + if (reader->view.size && reader->view.ptr != reader->buffer) { + memmove(reader->buffer, reader->view.ptr, reader->view.size); + } + reader->view.ptr = reader->buffer; + return LoadMore(reader); +} + +// Loads chunks of buffer size from disks until it contains a newline character +// or end of file. +static void SkipToNextLine(StackLineReader* reader) { + for (;;) { + const int read = LoadFullBuffer(reader); + if (read == 0) { + break; + } else { + const int eol_index = IndexOfEol(reader); + if (eol_index >= 0) { + reader->view = + CpuFeatures_StringView_PopFront(reader->view, eol_index + 1); + break; + } + } + } +} + +static LineResult CreateLineResult(bool eof, bool full_line, StringView view) { + LineResult result; + result.eof = eof; + result.full_line = full_line; + result.line = view; + return result; +} + +// Helper methods to provide clearer semantic in StackLineReader_NextLine. +static LineResult CreateEOFLineResult(StringView view) { + return CreateLineResult(true, true, view); +} + +static LineResult CreateTruncatedLineResult(StringView view) { + return CreateLineResult(false, false, view); +} + +static LineResult CreateValidLineResult(StringView view) { + return CreateLineResult(false, true, view); +} + +LineResult StackLineReader_NextLine(StackLineReader* reader) { + if (reader->skip_mode) { + SkipToNextLine(reader); + reader->skip_mode = false; + } + { + const bool can_load_more = + reader->view.size < STACK_LINE_READER_BUFFER_SIZE; + int eol_index = IndexOfEol(reader); + if (eol_index < 0 && can_load_more) { + const int read = BringToFrontAndLoadMore(reader); + if (read == 0) { + return CreateEOFLineResult(reader->view); + } + eol_index = IndexOfEol(reader); + } + if (eol_index < 0) { + reader->skip_mode = true; + return CreateTruncatedLineResult(reader->view); + } + { + StringView line = + CpuFeatures_StringView_KeepFront(reader->view, eol_index); + reader->view = + CpuFeatures_StringView_PopFront(reader->view, eol_index + 1); + return CreateValidLineResult(line); + } + } +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/string_view.c b/cpp/src/arrow/vendored/cpu_features/src/string_view.c new file mode 100644 index 000000000000..856731c3470c --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/string_view.c @@ -0,0 +1,182 @@ +// 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. + +#include "internal/string_view.h" + +#include +#include +#include + +int CpuFeatures_StringView_IndexOfChar(const StringView view, char c) { + if (view.ptr && view.size) { + const char* const found = (const char*)memchr(view.ptr, c, view.size); + if (found) { + return (int)(found - view.ptr); + } + } + return -1; +} + +int CpuFeatures_StringView_IndexOf(const StringView view, + const StringView sub_view) { + if (sub_view.size) { + StringView remainder = view; + while (remainder.size >= sub_view.size) { + const int found_index = + CpuFeatures_StringView_IndexOfChar(remainder, sub_view.ptr[0]); + if (found_index < 0) break; + remainder = CpuFeatures_StringView_PopFront(remainder, found_index); + if (CpuFeatures_StringView_StartsWith(remainder, sub_view)) { + return (int)(remainder.ptr - view.ptr); + } + remainder = CpuFeatures_StringView_PopFront(remainder, 1); + } + } + return -1; +} + +bool CpuFeatures_StringView_IsEquals(const StringView a, const StringView b) { + if (a.size == b.size) { + return a.ptr == b.ptr || memcmp(a.ptr, b.ptr, b.size) == 0; + } + return false; +} + +bool CpuFeatures_StringView_StartsWith(const StringView a, const StringView b) { + return a.ptr && b.ptr && b.size && a.size >= b.size + ? memcmp(a.ptr, b.ptr, b.size) == 0 + : false; +} + +StringView CpuFeatures_StringView_PopFront(const StringView str_view, + size_t count) { + if (count > str_view.size) { + return kEmptyStringView; + } + return view(str_view.ptr + count, str_view.size - count); +} + +StringView CpuFeatures_StringView_PopBack(const StringView str_view, + size_t count) { + if (count > str_view.size) { + return kEmptyStringView; + } + return view(str_view.ptr, str_view.size - count); +} + +StringView CpuFeatures_StringView_KeepFront(const StringView str_view, + size_t count) { + return count <= str_view.size ? view(str_view.ptr, count) : str_view; +} + +char CpuFeatures_StringView_Front(const StringView view) { + assert(view.size); + assert(view.ptr); + return view.ptr[0]; +} + +char CpuFeatures_StringView_Back(const StringView view) { + assert(view.size); + return view.ptr[view.size - 1]; +} + +StringView CpuFeatures_StringView_TrimWhitespace(StringView view) { + while (view.size && isspace(CpuFeatures_StringView_Front(view))) + view = CpuFeatures_StringView_PopFront(view, 1); + while (view.size && isspace(CpuFeatures_StringView_Back(view))) + view = CpuFeatures_StringView_PopBack(view, 1); + return view; +} + +static int HexValue(const char c) { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} + +// Returns -1 if view contains non digits. +static int ParsePositiveNumberWithBase(const StringView view, int base) { + int result = 0; + StringView remainder = view; + for (; remainder.size; + remainder = CpuFeatures_StringView_PopFront(remainder, 1)) { + const int value = HexValue(CpuFeatures_StringView_Front(remainder)); + if (value < 0 || value >= base) return -1; + result = (result * base) + value; + } + return result; +} + +int CpuFeatures_StringView_ParsePositiveNumber(const StringView view) { + if (view.size) { + const StringView hex_prefix = str("0x"); + if (CpuFeatures_StringView_StartsWith(view, hex_prefix)) { + const StringView span_no_prefix = + CpuFeatures_StringView_PopFront(view, hex_prefix.size); + return ParsePositiveNumberWithBase(span_no_prefix, 16); + } + return ParsePositiveNumberWithBase(view, 10); + } + return -1; +} + +void CpuFeatures_StringView_CopyString(const StringView src, char* dst, + size_t dst_size) { + if (dst_size > 0) { + const size_t max_copy_size = dst_size - 1; + const size_t copy_size = + src.size > max_copy_size ? max_copy_size : src.size; + memcpy(dst, src.ptr, copy_size); + dst[copy_size] = '\0'; + } +} + +bool CpuFeatures_StringView_HasWord(const StringView line, + const char* const word_str) { + const StringView word = str(word_str); + StringView remainder = line; + for (;;) { + const int index_of_word = CpuFeatures_StringView_IndexOf(remainder, word); + if (index_of_word < 0) { + return false; + } else { + const StringView before = + CpuFeatures_StringView_KeepFront(line, index_of_word); + const StringView after = + CpuFeatures_StringView_PopFront(line, index_of_word + word.size); + const bool valid_before = + before.size == 0 || CpuFeatures_StringView_Back(before) == ' '; + const bool valid_after = + after.size == 0 || CpuFeatures_StringView_Front(after) == ' '; + if (valid_before && valid_after) return true; + remainder = + CpuFeatures_StringView_PopFront(remainder, index_of_word + word.size); + } + } + return false; +} + +bool CpuFeatures_StringView_GetAttributeKeyValue(const StringView line, + StringView* key, + StringView* value) { + const StringView sep = str(": "); + const int index_of_separator = CpuFeatures_StringView_IndexOf(line, sep); + if (index_of_separator < 0) return false; + *value = CpuFeatures_StringView_TrimWhitespace( + CpuFeatures_StringView_PopFront(line, index_of_separator + sep.size)); + *key = CpuFeatures_StringView_TrimWhitespace( + CpuFeatures_StringView_KeepFront(line, index_of_separator)); + return true; +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c b/cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c new file mode 100644 index 000000000000..1b43a362ac2e --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c @@ -0,0 +1,52 @@ +// 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. + +#include "internal/unix_features_aggregator.h" +#include "internal/string_view.h" + +void CpuFeatures_SetFromFlags(const size_t configs_size, + const CapabilityConfig* configs, + const StringView flags_line, + void* const features) { + size_t i = 0; + for (; i < configs_size; ++i) { + const CapabilityConfig config = configs[i]; + config.set_bit(features, CpuFeatures_StringView_HasWord( + flags_line, config.proc_cpuinfo_flag)); + } +} + +static bool IsSet(const uint32_t mask, const uint32_t value) { + if (mask == 0) return false; + return (value & mask) == mask; +} + +static bool IsHwCapsSet(const HardwareCapabilities hwcaps_mask, + const HardwareCapabilities hwcaps) { + return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) || + IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2); +} + +void CpuFeatures_OverrideFromHwCaps(const size_t configs_size, + const CapabilityConfig* configs, + const HardwareCapabilities hwcaps, + void* const features) { + size_t i = 0; + for (; i < configs_size; ++i) { + const CapabilityConfig* config = &configs[i]; + if (IsHwCapsSet(config->hwcaps_mask, hwcaps)) { + config->set_bit(features, true); + } + } +} diff --git a/cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c b/cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c new file mode 100644 index 000000000000..a9ff82908256 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c @@ -0,0 +1,246 @@ +// 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. + +#include +#include +#include + +#include "cpu_features_macros.h" + +#if defined(CPU_FEATURES_ARCH_X86) +#include "cpuinfo_x86.h" +#elif defined(CPU_FEATURES_ARCH_ARM) +#include "cpuinfo_arm.h" +#elif defined(CPU_FEATURES_ARCH_AARCH64) +#include "cpuinfo_aarch64.h" +#elif defined(CPU_FEATURES_ARCH_MIPS) +#include "cpuinfo_mips.h" +#elif defined(CPU_FEATURES_ARCH_PPC) +#include "cpuinfo_ppc.h" +#endif + +static void PrintEscapedAscii(const char* str) { + putchar('"'); + for (; str && *str; ++str) { + switch (*str) { + case '\"': + case '\\': + case '/': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + putchar('\\'); + } + putchar(*str); + } + putchar('"'); +} + +static void PrintVoid(void) {} +static void PrintComma(void) { putchar(','); } +static void PrintLineFeed(void) { putchar('\n'); } +static void PrintOpenBrace(void) { putchar('{'); } +static void PrintCloseBrace(void) { putchar('}'); } +static void PrintOpenBracket(void) { putchar('['); } +static void PrintCloseBracket(void) { putchar(']'); } +static void PrintString(const char* field) { printf("%s", field); } +static void PrintAlignedHeader(const char* field) { printf("%-15s : ", field); } +static void PrintIntValue(int value) { printf("%d", value); } +static void PrintDecHexValue(int value) { + printf("%3d (0x%02X)", value, value); +} +static void PrintJsonHeader(const char* field) { + PrintEscapedAscii(field); + putchar(':'); +} + +typedef struct { + void (*Start)(void); + void (*ArrayStart)(void); + void (*ArraySeparator)(void); + void (*ArrayEnd)(void); + void (*PrintString)(const char* value); + void (*PrintValue)(int value); + void (*EndField)(void); + void (*StartField)(const char* field); + void (*End)(void); +} Printer; + +static Printer getJsonPrinter(void) { + return (Printer){ + .Start = &PrintOpenBrace, + .ArrayStart = &PrintOpenBracket, + .ArraySeparator = &PrintComma, + .ArrayEnd = &PrintCloseBracket, + .PrintString = &PrintEscapedAscii, + .PrintValue = &PrintIntValue, + .EndField = &PrintComma, + .StartField = &PrintJsonHeader, + .End = &PrintCloseBrace, + }; +} + +static Printer getTextPrinter(void) { + return (Printer){ + .Start = &PrintVoid, + .ArrayStart = &PrintVoid, + .ArraySeparator = &PrintComma, + .ArrayEnd = &PrintVoid, + .PrintString = &PrintString, + .PrintValue = &PrintDecHexValue, + .EndField = &PrintLineFeed, + .StartField = &PrintAlignedHeader, + .End = &PrintVoid, + }; +} + +// Prints a named numeric value in both decimal and hexadecimal. +static void PrintN(const Printer p, const char* field, int value) { + p.StartField(field); + p.PrintValue(value); + p.EndField(); +} + +// Prints a named string. +static void PrintS(const Printer p, const char* field, const char* value) { + p.StartField(field); + p.PrintString(value); + p.EndField(); +} + +static int cmp(const void* p1, const void* p2) { + return strcmp(*(const char* const*)p1, *(const char* const*)p2); +} + +#define DEFINE_PRINT_FLAGS(HasFeature, FeatureName, FeatureType, LastEnum) \ + static void PrintFlags(const Printer p, const FeatureType* features) { \ + size_t i; \ + const char* ptrs[LastEnum] = {0}; \ + size_t count = 0; \ + for (i = 0; i < LastEnum; ++i) { \ + if (HasFeature(features, i)) { \ + ptrs[count] = FeatureName(i); \ + ++count; \ + } \ + } \ + qsort(ptrs, count, sizeof(char*), cmp); \ + p.StartField("flags"); \ + p.ArrayStart(); \ + for (i = 0; i < count; ++i) { \ + if (i > 0) p.ArraySeparator(); \ + p.PrintString(ptrs[i]); \ + } \ + p.ArrayEnd(); \ + } + +#if defined(CPU_FEATURES_ARCH_X86) +DEFINE_PRINT_FLAGS(GetX86FeaturesEnumValue, GetX86FeaturesEnumName, X86Features, + X86_LAST_) +#elif defined(CPU_FEATURES_ARCH_ARM) +DEFINE_PRINT_FLAGS(GetArmFeaturesEnumValue, GetArmFeaturesEnumName, ArmFeatures, + ARM_LAST_) +#elif defined(CPU_FEATURES_ARCH_AARCH64) +DEFINE_PRINT_FLAGS(GetAarch64FeaturesEnumValue, GetAarch64FeaturesEnumName, + Aarch64Features, AARCH64_LAST_) +#elif defined(CPU_FEATURES_ARCH_MIPS) +DEFINE_PRINT_FLAGS(GetMipsFeaturesEnumValue, GetMipsFeaturesEnumName, + MipsFeatures, MIPS_LAST_) +#elif defined(CPU_FEATURES_ARCH_PPC) +DEFINE_PRINT_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures, + PPC_LAST_) +#endif + +static void PrintFeatures(const Printer printer) { +#if defined(CPU_FEATURES_ARCH_X86) + char brand_string[49]; + const X86Info info = GetX86Info(); + FillX86BrandString(brand_string); + PrintS(printer, "arch", "x86"); + PrintS(printer, "brand", brand_string); + PrintN(printer, "family", info.family); + PrintN(printer, "model", info.model); + PrintN(printer, "stepping", info.stepping); + PrintS(printer, "uarch", + GetX86MicroarchitectureName(GetX86Microarchitecture(&info))); + PrintFlags(printer, &info.features); +#elif defined(CPU_FEATURES_ARCH_ARM) + const ArmInfo info = GetArmInfo(); + PrintS(printer, "arch", "ARM"); + PrintN(printer, "implementer", info.implementer); + PrintN(printer, "architecture", info.architecture); + PrintN(printer, "variant", info.variant); + PrintN(printer, "part", info.part); + PrintN(printer, "revision", info.revision); + PrintFlags(printer, &info.features); +#elif defined(CPU_FEATURES_ARCH_AARCH64) + const Aarch64Info info = GetAarch64Info(); + PrintS(printer, "arch", "aarch64"); + PrintN(printer, "implementer", info.implementer); + PrintN(printer, "variant", info.variant); + PrintN(printer, "part", info.part); + PrintN(printer, "revision", info.revision); + PrintFlags(printer, &info.features); +#elif defined(CPU_FEATURES_ARCH_MIPS) + (void)&PrintN; // Remove unused function warning. + const MipsInfo info = GetMipsInfo(); + PrintS(printer, "arch", "mips"); + PrintFlags(printer, &info.features); +#elif defined(CPU_FEATURES_ARCH_PPC) + (void)&PrintN; // Remove unused function warning. + const PPCInfo info = GetPPCInfo(); + const PPCPlatformStrings strings = GetPPCPlatformStrings(); + PrintS(printer, "arch", "ppc"); + PrintS(printer, "platform", strings.platform); + PrintS(printer, "model", strings.model); + PrintS(printer, "machine", strings.machine); + PrintS(printer, "cpu", strings.cpu); + PrintS(printer, "instruction set", strings.type.platform); + PrintS(printer, "microarchitecture", strings.type.base_platform); + PrintFlags(printer, &info.features); +#endif +} + +static void showUsage(const char* name) { + printf( + "\n" + "Usage: %s [options]\n" + " Options:\n" + " -h | --help Show help message.\n" + " -j | --json Format output as json instead of plain text.\n" + "\n", + name); +} + +int main(int argc, char** argv) { + Printer printer = getTextPrinter(); + int i = 1; + for (; i < argc; ++i) { + const char* arg = argv[i]; + if (strcmp(arg, "-j") == 0 || strcmp(arg, "--json") == 0) { + printer = getJsonPrinter(); + } else { + showUsage(argv[0]); + if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) + return EXIT_SUCCESS; + return EXIT_FAILURE; + } + } + printer.Start(); + PrintFeatures(printer); + printer.End(); + PrintLineFeed(); + return EXIT_SUCCESS; +} diff --git a/cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt b/cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt new file mode 100644 index 000000000000..a744ee98bfee --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt @@ -0,0 +1,92 @@ +# +# libraries for tests +# + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) # prefer use of -std11 instead of -gnustd11 + +include_directories(../include) +add_definitions(-DCPU_FEATURES_TEST) + +##------------------------------------------------------------------------------ +add_library(string_view ../src/string_view.c) +##------------------------------------------------------------------------------ +add_library(filesystem_for_testing filesystem_for_testing.cc) +target_compile_definitions(filesystem_for_testing PUBLIC CPU_FEATURES_MOCK_FILESYSTEM) +##------------------------------------------------------------------------------ +add_library(hwcaps_for_testing hwcaps_for_testing.cc) +target_compile_definitions(hwcaps_for_testing PUBLIC CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL) +target_link_libraries(hwcaps_for_testing filesystem_for_testing) +##------------------------------------------------------------------------------ +add_library(stack_line_reader ../src/stack_line_reader.c) +target_compile_definitions(stack_line_reader PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024) +target_link_libraries(stack_line_reader string_view) +##------------------------------------------------------------------------------ +add_library(stack_line_reader_for_test ../src/stack_line_reader.c) +target_compile_definitions(stack_line_reader_for_test PUBLIC STACK_LINE_READER_BUFFER_SIZE=16) +target_link_libraries(stack_line_reader_for_test string_view filesystem_for_testing) +##------------------------------------------------------------------------------ +add_library(all_libraries ../src/stack_line_reader.c ../src/unix_features_aggregator.c) +target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view) + +# +# tests +# +link_libraries(gtest gmock_main) + +## bit_utils_test +add_executable(bit_utils_test bit_utils_test.cc) +target_link_libraries(bit_utils_test) +add_test(NAME bit_utils_test COMMAND bit_utils_test) +##------------------------------------------------------------------------------ +## string_view_test +add_executable(string_view_test string_view_test.cc ../src/string_view.c) +target_link_libraries(string_view_test string_view) +add_test(NAME string_view_test COMMAND string_view_test) +##------------------------------------------------------------------------------ +## stack_line_reader_test +add_executable(stack_line_reader_test stack_line_reader_test.cc) +target_link_libraries(stack_line_reader_test stack_line_reader_for_test) +add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test) +##------------------------------------------------------------------------------ +## unix_features_aggregator_test +add_executable(unix_features_aggregator_test unix_features_aggregator_test.cc) +target_link_libraries(unix_features_aggregator_test all_libraries) +add_test(NAME unix_features_aggregator_test COMMAND unix_features_aggregator_test) +##------------------------------------------------------------------------------ +## cpuinfo_x86_test +if(PROCESSOR_IS_X86) + add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c) + target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86) + target_link_libraries(cpuinfo_x86_test all_libraries) + add_test(NAME cpuinfo_x86_test COMMAND cpuinfo_x86_test) +endif() +##------------------------------------------------------------------------------ +## cpuinfo_arm_test +if(PROCESSOR_IS_ARM) + add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c) + target_link_libraries(cpuinfo_arm_test all_libraries) + add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test) +endif() +##------------------------------------------------------------------------------ +## cpuinfo_aarch64_test +if(PROCESSOR_IS_AARCH64) + add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c) + target_link_libraries(cpuinfo_aarch64_test all_libraries) + add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) +endif() +##------------------------------------------------------------------------------ +## cpuinfo_mips_test +if(PROCESSOR_IS_MIPS) + add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/cpuinfo_mips.c) + target_link_libraries(cpuinfo_mips_test all_libraries) + add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test) +endif() +##------------------------------------------------------------------------------ +## cpuinfo_ppc_test +if(PROCESSOR_IS_POWER) + add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/cpuinfo_ppc.c) + target_link_libraries(cpuinfo_ppc_test all_libraries) + add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test) +endif() diff --git a/cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc b/cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc new file mode 100644 index 000000000000..8937cbc2e617 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc @@ -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. + +#include "internal/bit_utils.h" + +#include "gtest/gtest.h" + +namespace cpu_features { +namespace { + +TEST(UtilsTest, IsBitSet) { + for (size_t bit_set = 0; bit_set < 32; ++bit_set) { + const uint32_t value = 1UL << bit_set; + for (size_t i = 0; i < 32; ++i) { + EXPECT_EQ(IsBitSet(value, i), i == bit_set); + } + } + + // testing 0, all bits should be 0. + for (size_t i = 0; i < 32; ++i) { + EXPECT_FALSE(IsBitSet(0, i)); + } + + // testing ~0, all bits should be 1. + for (size_t i = 0; i < 32; ++i) { + EXPECT_TRUE(IsBitSet(-1, i)); + } +} + +TEST(UtilsTest, ExtractBitRange) { + // Extracting all bits gives the same number. + EXPECT_EQ(ExtractBitRange(123, 31, 0), 123); + // Extracting 1 bit gives parity. + EXPECT_EQ(ExtractBitRange(123, 0, 0), 1); + EXPECT_EQ(ExtractBitRange(122, 0, 0), 0); + + EXPECT_EQ(ExtractBitRange(0xF0, 7, 4), 0xF); + EXPECT_EQ(ExtractBitRange(0x42 << 2, 10, 2), 0x42); +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc new file mode 100644 index 000000000000..bdb4d17c65e3 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc @@ -0,0 +1,74 @@ +// 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. + +#include "cpuinfo_aarch64.h" +#include "filesystem_for_testing.h" +#include "hwcaps_for_testing.h" + +#include "gtest/gtest.h" + +namespace cpu_features { +namespace { + +void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } + +TEST(CpuinfoAarch64Test, FromHardwareCap) { + SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0); + GetEmptyFilesystem(); // disabling /proc/cpuinfo + const auto info = GetAarch64Info(); + EXPECT_TRUE(info.features.fp); + EXPECT_FALSE(info.features.asimd); + EXPECT_TRUE(info.features.aes); + EXPECT_FALSE(info.features.pmull); + EXPECT_FALSE(info.features.sha1); + EXPECT_FALSE(info.features.sha2); + EXPECT_FALSE(info.features.crc32); +} + +TEST(CpuinfoAarch64Test, ARMCortexA53) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(Processor : AArch64 Processor rev 3 (aarch64) +processor : 0 +processor : 1 +processor : 2 +processor : 3 +processor : 4 +processor : 5 +processor : 6 +processor : 7 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 +CPU implementer : 0x41 +CPU architecture: AArch64 +CPU variant : 0x0 +CPU part : 0xd03 +CPU revision : 3)"); + const auto info = GetAarch64Info(); + EXPECT_EQ(info.implementer, 0x41); + EXPECT_EQ(info.variant, 0x0); + EXPECT_EQ(info.part, 0xd03); + EXPECT_EQ(info.revision, 3); + + EXPECT_TRUE(info.features.fp); + EXPECT_TRUE(info.features.asimd); + EXPECT_TRUE(info.features.aes); + EXPECT_TRUE(info.features.pmull); + EXPECT_TRUE(info.features.sha1); + EXPECT_TRUE(info.features.sha2); + EXPECT_TRUE(info.features.crc32); +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc new file mode 100644 index 000000000000..34c755169d62 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc @@ -0,0 +1,186 @@ +// 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. + +#include "cpuinfo_arm.h" +#include "filesystem_for_testing.h" +#include "hwcaps_for_testing.h" + +#include "gtest/gtest.h" + +namespace cpu_features { +namespace { + +void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } + +TEST(CpuinfoArmTest, FromHardwareCap) { + SetHardwareCapabilities(ARM_HWCAP_NEON, ARM_HWCAP2_AES | ARM_HWCAP2_CRC32); + GetEmptyFilesystem(); // disabling /proc/cpuinfo + const auto info = GetArmInfo(); + EXPECT_TRUE(info.features.vfp); // triggered by vfpv3 + EXPECT_TRUE(info.features.vfpv3); // triggered by neon + EXPECT_TRUE(info.features.neon); + EXPECT_TRUE(info.features.aes); + EXPECT_TRUE(info.features.crc32); + + EXPECT_FALSE(info.features.vfpv4); + EXPECT_FALSE(info.features.iwmmxt); + EXPECT_FALSE(info.features.vfpv3d16); + EXPECT_FALSE(info.features.idiva); + EXPECT_FALSE(info.features.idivt); + EXPECT_FALSE(info.features.pmull); + EXPECT_FALSE(info.features.sha1); + EXPECT_FALSE(info.features.sha2); +} + +TEST(CpuinfoArmTest, ODroidFromCpuInfo) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", R"(processor : 0 +model name : ARMv7 Processor rev 3 (v71) +BogoMIPS : 120.00 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x2 +CPU part : 0xc0f +CPU revision : 3)"); + const auto info = GetArmInfo(); + EXPECT_EQ(info.implementer, 0x41); + EXPECT_EQ(info.variant, 0x2); + EXPECT_EQ(info.part, 0xc0f); + EXPECT_EQ(info.revision, 3); + EXPECT_EQ(info.architecture, 7); + + EXPECT_TRUE(info.features.vfp); + EXPECT_FALSE(info.features.iwmmxt); + EXPECT_TRUE(info.features.neon); + EXPECT_TRUE(info.features.vfpv3); + EXPECT_FALSE(info.features.vfpv3d16); + EXPECT_TRUE(info.features.vfpv4); + EXPECT_TRUE(info.features.idiva); + EXPECT_TRUE(info.features.idivt); + EXPECT_FALSE(info.features.aes); + EXPECT_FALSE(info.features.pmull); + EXPECT_FALSE(info.features.sha1); + EXPECT_FALSE(info.features.sha2); + EXPECT_FALSE(info.features.crc32); +} + +// http://code.google.com/p/android/issues/detail?id=10812 +TEST(CpuinfoArmTest, InvalidArmv7) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(Processor : ARMv6-compatible processor rev 6 (v6l) +BogoMIPS : 199.47 +Features : swp half thumb fastmult vfp edsp java +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xb76 +CPU revision : 6 + +Hardware : SPICA +Revision : 0020 +Serial : 33323613546d00ec )"); + const auto info = GetArmInfo(); + EXPECT_EQ(info.architecture, 6); +} + +// https://crbug.com/341598. +TEST(CpuinfoArmTest, InvalidNeon) { + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(Processor: ARMv7 Processory rev 0 (v71) +processor: 0 +BogoMIPS: 13.50 + +Processor: 1 +BogoMIPS: 13.50 + +Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt +CPU implementer : 0x51 +CPU architecture: 7 +CPU variant: 0x1 +CPU part: 0x04d +CPU revision: 0 + +Hardware: SAMSUNG M2 +Revision: 0010 +Serial: 00001e030000354e)"); + const auto info = GetArmInfo(); + EXPECT_FALSE(info.features.neon); +} + +// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV +// support. +TEST(CpuinfoArmTest, Nexus4_0x510006f2) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(CPU implementer : 0x51 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0x6f +CPU revision : 2)"); + const auto info = GetArmInfo(); + EXPECT_TRUE(info.features.idiva); + EXPECT_TRUE(info.features.idivt); + + EXPECT_EQ(GetArmCpuId(&info), 0x510006f2); +} + +// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV +// support. +TEST(CpuinfoArmTest, Nexus4_0x510006f3) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(CPU implementer : 0x51 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0x6f +CPU revision : 3)"); + const auto info = GetArmInfo(); + EXPECT_TRUE(info.features.idiva); + EXPECT_TRUE(info.features.idivt); + + EXPECT_EQ(GetArmCpuId(&info), 0x510006f3); +} + +// The emulator-specific Android 4.2 kernel fails to report support for the +// 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual +// CPU implemented by the emulator. +TEST(CpuinfoArmTest, EmulatorSpecificIdiv) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(Processor : ARMv7 Processor rev 0 (v7l) +BogoMIPS : 629.14 +Features : swp half thumb fastmult vfp edsp neon vfpv3 +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xc08 +CPU revision : 0 + +Hardware : Goldfish +Revision : 0000 +Serial : 0000000000000000)"); + const auto info = GetArmInfo(); + EXPECT_TRUE(info.features.idiva); +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc new file mode 100644 index 000000000000..fbec04d59311 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc @@ -0,0 +1,126 @@ +// 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. + +#include "cpuinfo_mips.h" +#include "filesystem_for_testing.h" +#include "hwcaps_for_testing.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" + +#include "gtest/gtest.h" + +namespace cpu_features { + +namespace { + +void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } + +TEST(CpuinfoMipsTest, FromHardwareCapBoth) { + SetHardwareCapabilities(MIPS_HWCAP_MSA | MIPS_HWCAP_R6, 0); + GetEmptyFilesystem(); // disabling /proc/cpuinfo + const auto info = GetMipsInfo(); + EXPECT_TRUE(info.features.msa); + EXPECT_FALSE(info.features.eva); + EXPECT_TRUE(info.features.r6); +} + +TEST(CpuinfoMipsTest, FromHardwareCapOnlyOne) { + SetHardwareCapabilities(MIPS_HWCAP_MSA, 0); + GetEmptyFilesystem(); // disabling /proc/cpuinfo + const auto info = GetMipsInfo(); + EXPECT_TRUE(info.features.msa); + EXPECT_FALSE(info.features.eva); +} + +TEST(CpuinfoMipsTest, Ci40) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", R"(system type : IMG Pistachio SoC (B0) +machine : IMG Marduk – Ci40 with cc2520 +processor : 0 +cpu model : MIPS interAptiv (multi) V2.0 FPU V0.0 +BogoMIPS : 363.72 +wait instruction : yes +microsecond timers : yes +tlb_entries : 64 +extra interrupt vector : yes +hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb] +isa : mips1 mips2 mips32r1 mips32r2 +ASEs implemented : mips16 dsp mt eva +shadow register sets : 1 +kscratch registers : 0 +package : 0 +core : 0 +VCED exceptions : not available +VCEI exceptions : not available +VPE : 0 +)"); + const auto info = GetMipsInfo(); + EXPECT_FALSE(info.features.msa); + EXPECT_TRUE(info.features.eva); +} + +TEST(CpuinfoMipsTest, AR7161) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(system type : Atheros AR7161 rev 2 +machine : NETGEAR WNDR3700/WNDR3800/WNDRMAC +processor : 0 +cpu model : MIPS 24Kc V7.4 +BogoMIPS : 452.19 +wait instruction : yes +microsecond timers : yes +tlb_entries : 16 +extra interrupt vector : yes +hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0f98, 0x0f78, 0x0df8] +ASEs implemented : mips16 +shadow register sets : 1 +kscratch registers : 0 +core : 0 +VCED exceptions : not available +VCEI exceptions : not available +)"); + const auto info = GetMipsInfo(); + EXPECT_FALSE(info.features.msa); + EXPECT_FALSE(info.features.eva); +} + +TEST(CpuinfoMipsTest, Goldfish) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", R"(system type : MIPS-Goldfish +Hardware : goldfish +Revison : 1 +processor : 0 +cpu model : MIPS 24Kc V0.0 FPU V0.0 +BogoMIPS : 1042.02 +wait instruction : yes +microsecond timers : yes +tlb_entries : 16 +extra interrupt vector : yes +hardware watchpoint : yes, count: 1, address/irw mask: [0x0ff8] +ASEs implemented : +shadow register sets : 1 +core : 0 +VCED exceptions : not available +VCEI exceptions : not available +)"); + const auto info = GetMipsInfo(); + EXPECT_FALSE(info.features.msa); + EXPECT_FALSE(info.features.eva); +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc new file mode 100644 index 000000000000..5d5e79808710 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc @@ -0,0 +1,119 @@ +// Copyright 2018 IBM. +// +// 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. + +#include "cpuinfo_ppc.h" +#include "filesystem_for_testing.h" +#include "hwcaps_for_testing.h" +#include "internal/string_view.h" + +#include "gtest/gtest.h" + +namespace cpu_features { +namespace { + +void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } + +TEST(CpustringsPPCTest, FromHardwareCap) { + SetHardwareCapabilities(PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_VSX, + PPC_FEATURE2_ARCH_3_00); + GetEmptyFilesystem(); // disabling /proc/cpuinfo + const auto info = GetPPCInfo(); + EXPECT_TRUE(info.features.fpu); + EXPECT_FALSE(info.features.mmu); + EXPECT_TRUE(info.features.vsx); + EXPECT_TRUE(info.features.arch300); + EXPECT_FALSE(info.features.power4); + EXPECT_FALSE(info.features.altivec); + EXPECT_FALSE(info.features.vcrypto); + EXPECT_FALSE(info.features.htm); +} + +TEST(CpustringsPPCTest, Blade) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(processor : 14 +cpu : POWER7 (architected), altivec supported +clock : 3000.000000MHz +revision : 2.1 (pvr 003f 0201) + +processor : 15 +cpu : POWER7 (architected), altivec supported +clock : 3000.000000MHz +revision : 2.1 (pvr 003f 0201) + +timebase : 512000000 +platform : pSeries +model : IBM,8406-70Y +machine : CHRP IBM,8406-70Y)"); + SetPlatformTypes("power7", "power8"); + const auto strings = GetPPCPlatformStrings(); + ASSERT_STREQ(strings.platform, "pSeries"); + ASSERT_STREQ(strings.model, "IBM,8406-70Y"); + ASSERT_STREQ(strings.machine, "CHRP IBM,8406-70Y"); + ASSERT_STREQ(strings.cpu, "POWER7 (architected), altivec supported"); + ASSERT_STREQ(strings.type.platform, "power7"); + ASSERT_STREQ(strings.type.base_platform, "power8"); +} + +TEST(CpustringsPPCTest, Firestone) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(processor : 126 +cpu : POWER8 (raw), altivec supported +clock : 2061.000000MHz +revision : 2.0 (pvr 004d 0200) + +processor : 127 +cpu : POWER8 (raw), altivec supported +clock : 2061.000000MHz +revision : 2.0 (pvr 004d 0200) + +timebase : 512000000 +platform : PowerNV +model : 8335-GTA +machine : PowerNV 8335-GTA +firmware : OPAL v3)"); + const auto strings = GetPPCPlatformStrings(); + ASSERT_STREQ(strings.platform, "PowerNV"); + ASSERT_STREQ(strings.model, "8335-GTA"); + ASSERT_STREQ(strings.machine, "PowerNV 8335-GTA"); + ASSERT_STREQ(strings.cpu, "POWER8 (raw), altivec supported"); +} + +TEST(CpustringsPPCTest, w8) { + DisableHardwareCapabilities(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(processor : 143 +cpu : POWER9, altivec supported +clock : 2300.000000MHz +revision : 2.2 (pvr 004e 1202) + +timebase : 512000000 +platform : PowerNV +model : 0000000000000000 +machine : PowerNV 0000000000000000 +firmware : OPAL +MMU : Radix)"); + const auto strings = GetPPCPlatformStrings(); + ASSERT_STREQ(strings.platform, "PowerNV"); + ASSERT_STREQ(strings.model, "0000000000000000"); + ASSERT_STREQ(strings.machine, "PowerNV 0000000000000000"); + ASSERT_STREQ(strings.cpu, "POWER9, altivec supported"); +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc new file mode 100644 index 000000000000..2389de9ab548 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc @@ -0,0 +1,176 @@ +// 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. + +#include +#include +#include + +#include "gtest/gtest.h" + +#include "cpuinfo_x86.h" +#include "internal/cpuid_x86.h" + +namespace cpu_features { + +class FakeCpu { + public: + Leaf CpuId(uint32_t leaf_id) const { + const auto itr = cpuid_leaves_.find(leaf_id); + EXPECT_TRUE(itr != cpuid_leaves_.end()) << "Missing leaf " << leaf_id; + return itr->second; + } + + uint32_t GetXCR0Eax() const { return xcr0_eax_; } + + void SetLeaves(std::map configuration) { + cpuid_leaves_ = std::move(configuration); + } + + void SetOsBackupsExtendedRegisters(bool os_backups_extended_registers) { + xcr0_eax_ = os_backups_extended_registers ? -1 : 0; + } + + private: + std::map cpuid_leaves_; + uint32_t xcr0_eax_; +}; + +auto* g_fake_cpu = new FakeCpu(); + +extern "C" Leaf CpuId(uint32_t leaf_id) { return g_fake_cpu->CpuId(leaf_id); } +extern "C" uint32_t GetXCR0Eax(void) { return g_fake_cpu->GetXCR0Eax(); } + +namespace { + +TEST(CpuidX86Test, SandyBridge) { + g_fake_cpu->SetOsBackupsExtendedRegisters(true); + g_fake_cpu->SetLeaves({ + {0x00000000, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {0x00000001, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}}, + {0x00000007, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, + }); + const auto info = GetX86Info(); + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x06); + EXPECT_EQ(info.model, 0x02A); + EXPECT_EQ(info.stepping, 0x06); + // Leaf 7 is zeroed out so none of the Leaf 7 flags are set. + const auto features = info.features; + EXPECT_FALSE(features.erms); + EXPECT_FALSE(features.avx2); + EXPECT_FALSE(features.avx512f); + EXPECT_FALSE(features.avx512cd); + EXPECT_FALSE(features.avx512er); + EXPECT_FALSE(features.avx512pf); + EXPECT_FALSE(features.avx512bw); + EXPECT_FALSE(features.avx512dq); + EXPECT_FALSE(features.avx512vl); + EXPECT_FALSE(features.avx512ifma); + EXPECT_FALSE(features.avx512vbmi); + EXPECT_FALSE(features.avx512vbmi2); + EXPECT_FALSE(features.avx512vnni); + EXPECT_FALSE(features.avx512bitalg); + EXPECT_FALSE(features.avx512vpopcntdq); + EXPECT_FALSE(features.avx512_4vnniw); + EXPECT_FALSE(features.avx512_4vbmi2); + // All old cpu features should be set. + EXPECT_TRUE(features.aes); + EXPECT_TRUE(features.ssse3); + EXPECT_TRUE(features.sse4_1); + EXPECT_TRUE(features.sse4_2); + EXPECT_TRUE(features.avx); + EXPECT_FALSE(features.sha); + EXPECT_TRUE(features.popcnt); + EXPECT_FALSE(features.movbe); + EXPECT_FALSE(features.rdrnd); +} + +TEST(CpuidX86Test, SandyBridgeTestOsSupport) { + g_fake_cpu->SetLeaves({ + {0x00000000, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {0x00000001, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}}, + {0x00000007, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, + }); + // avx is disabled if os does not support backing up ymm registers. + g_fake_cpu->SetOsBackupsExtendedRegisters(false); + EXPECT_FALSE(GetX86Info().features.avx); + // avx is disabled if os does not support backing up ymm registers. + g_fake_cpu->SetOsBackupsExtendedRegisters(true); + EXPECT_TRUE(GetX86Info().features.avx); +} + +TEST(CpuidX86Test, SkyLake) { + g_fake_cpu->SetOsBackupsExtendedRegisters(true); + g_fake_cpu->SetLeaves({ + {0x00000000, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {0x00000001, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, + {0x00000007, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}}, + }); + const auto info = GetX86Info(); + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x06); + EXPECT_EQ(info.model, 0x04E); + EXPECT_EQ(info.stepping, 0x03); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL); +} + +TEST(CpuidX86Test, Branding) { + g_fake_cpu->SetLeaves({ + {0x00000000, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {0x00000001, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, + {0x00000007, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}}, + {0x80000000, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}}, + {0x80000001, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}}, + {0x80000002, Leaf{0x65746E49, 0x2952286C, 0x726F4320, 0x4D542865}}, + {0x80000003, Leaf{0x37692029, 0x3035362D, 0x43205530, 0x40205550}}, + {0x80000004, Leaf{0x352E3220, 0x7A484730, 0x00000000, 0x00000000}}, + }); + char brand_string[49]; + FillX86BrandString(brand_string); + EXPECT_STREQ(brand_string, "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz"); +} + +// http://users.atw.hu/instlatx64/AuthenticAMD0630F81_K15_Godavari_CPUID.txt +TEST(CpuidX86Test, AMD_K15) { + g_fake_cpu->SetLeaves({ + {0x00000000, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}}, + {0x00000001, Leaf{0x00630F81, 0x00040800, 0x3E98320B, 0x178BFBFF}}, + {0x00000007, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, + {0x80000000, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}}, + {0x80000001, Leaf{0x00630F81, 0x10000000, 0x0FEBBFFF, 0x2FD3FBFF}}, + {0x80000002, Leaf{0x20444D41, 0x372D3841, 0x4B303736, 0x64615220}}, + {0x80000003, Leaf{0x206E6F65, 0x202C3752, 0x43203031, 0x75706D6F}}, + {0x80000004, Leaf{0x43206574, 0x7365726F, 0x2B433420, 0x00204736}}, + {0x80000005, Leaf{0xFF40FF18, 0xFF40FF30, 0x10040140, 0x60030140}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "AuthenticAMD"); + EXPECT_EQ(info.family, 0x15); + EXPECT_EQ(info.model, 0x38); + EXPECT_EQ(info.stepping, 0x01); + EXPECT_EQ(GetX86Microarchitecture(&info), + X86Microarchitecture::AMD_BULLDOZER); + + char brand_string[49]; + FillX86BrandString(brand_string); + EXPECT_STREQ(brand_string, "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G "); +} + +// TODO(user): test what happens when xsave/osxsave are not present. +// TODO(user): test what happens when xmm/ymm/zmm os support are not +// present. + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc b/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc new file mode 100644 index 000000000000..4554c1f0a0b4 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc @@ -0,0 +1,103 @@ +// 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. + +#include "filesystem_for_testing.h" + +#include +#include +#include +#include +#include + +namespace cpu_features { + +FakeFile::FakeFile(int file_descriptor, const char* content) + : file_descriptor_(file_descriptor), content_(content) {} + +FakeFile::~FakeFile() { assert(!opened_); } + +void FakeFile::Open() { + assert(!opened_); + opened_ = true; +} + +void FakeFile::Close() { + assert(opened_); + opened_ = false; +} + +int FakeFile::Read(int fd, void* buf, size_t count) { + assert(count < INT_MAX); + assert(fd == file_descriptor_); + const size_t remainder = content_.size() - head_index_; + const size_t read = count > remainder ? remainder : count; + memcpy(buf, content_.data() + head_index_, read); + head_index_ += read; + assert(read < INT_MAX); + return read; +} + +void FakeFilesystem::Reset() { files_.clear(); } + +FakeFile* FakeFilesystem::CreateFile(const std::string& filename, + const char* content) { + auto& file = files_[filename]; + file = + std::unique_ptr(new FakeFile(next_file_descriptor_++, content)); + return file.get(); +} + +FakeFile* FakeFilesystem::FindFileOrNull(const std::string& filename) const { + const auto itr = files_.find(filename); + return itr == files_.end() ? nullptr : itr->second.get(); +} + +FakeFile* FakeFilesystem::FindFileOrDie(const int file_descriptor) const { + for (const auto& filename_file_pair : files_) { + FakeFile* const file_ptr = filename_file_pair.second.get(); + if (file_ptr->GetFileDescriptor() == file_descriptor) { + return file_ptr; + } + } + assert(false); + return nullptr; +} + +static FakeFilesystem* kFilesystem = new FakeFilesystem(); + +FakeFilesystem& GetEmptyFilesystem() { + kFilesystem->Reset(); + return *kFilesystem; +} + +extern "C" int CpuFeatures_OpenFile(const char* filename) { + auto* const file = kFilesystem->FindFileOrNull(filename); + if (file) { + file->Open(); + return file->GetFileDescriptor(); + } + return -1; +} + +extern "C" void CpuFeatures_CloseFile(int file_descriptor) { + kFilesystem->FindFileOrDie(file_descriptor)->Close(); +} + +extern "C" int CpuFeatures_ReadFile(int file_descriptor, void* buffer, + size_t buffer_size) { + return kFilesystem->FindFileOrDie(file_descriptor) + ->Read(file_descriptor, buffer, buffer_size); +} + +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h b/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h new file mode 100644 index 000000000000..ca269e523d9c --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h @@ -0,0 +1,61 @@ +// 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. + +// Implements a fake filesystem, useful for tests. +#ifndef CPU_FEATURES_TEST_FILESYSTEM_FOR_TESTING_H_ +#define CPU_FEATURES_TEST_FILESYSTEM_FOR_TESTING_H_ + +#include +#include +#include + +#include "internal/filesystem.h" + +namespace cpu_features { + +class FakeFile { + public: + explicit FakeFile(int file_descriptor, const char* content); + ~FakeFile(); + + void Open(); + void Close(); + int Read(int fd, void* buf, size_t count); + + int GetFileDescriptor() const { return file_descriptor_; } + + private: + const int file_descriptor_; + const std::string content_; + bool opened_ = false; + size_t head_index_ = 0; +}; + +class FakeFilesystem { + public: + void Reset(); + FakeFile* CreateFile(const std::string& filename, const char* content); + FakeFile* FindFileOrDie(const int file_descriptor) const; + FakeFile* FindFileOrNull(const std::string& filename) const; + + private: + size_t next_file_descriptor_ = 0; + std::unordered_map> files_; +}; + +FakeFilesystem& GetEmptyFilesystem(); + +} // namespace cpu_features + +#endif // CPU_FEATURES_TEST_FILESYSTEM_FOR_TESTING_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc b/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc new file mode 100644 index 000000000000..07f68e8a3ec3 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc @@ -0,0 +1,45 @@ +// 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. + +#include + +#include "hwcaps_for_testing.h" +#include "internal/string_view.h" + +namespace cpu_features { + +namespace { +static auto* const g_hardware_capabilities = new HardwareCapabilities(); +static auto* const g_platform_types = new PlatformType(); +} // namespace + +void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2) { + g_hardware_capabilities->hwcaps = hwcaps; + g_hardware_capabilities->hwcaps2 = hwcaps2; +} + +HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) { + return *g_hardware_capabilities; +} + +void SetPlatformTypes(const char* platform, const char* base_platform) { + CpuFeatures_StringView_CopyString(str(platform), g_platform_types->platform, + sizeof(g_platform_types->platform)); + CpuFeatures_StringView_CopyString(str(base_platform), + g_platform_types->base_platform, + sizeof(g_platform_types->base_platform)); +} + +PlatformType CpuFeatures_GetPlatformType(void) { return *g_platform_types; } +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h b/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h new file mode 100644 index 000000000000..0d0377727718 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h @@ -0,0 +1,27 @@ +// 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 CPU_FEATURES_TEST_HWCAPS_FOR_TESTING_H_ +#define CPU_FEATURES_TEST_HWCAPS_FOR_TESTING_H_ + +#include "internal/hwcaps.h" + +namespace cpu_features { + +void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2); +void SetPlatformTypes(const char *platform, const char *base_platform); + +} // namespace cpu_features + +#endif // CPU_FEATURES_TEST_HWCAPS_FOR_TESTING_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc b/cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc new file mode 100644 index 000000000000..c8f9691006a9 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc @@ -0,0 +1,132 @@ +// 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. + +#include "internal/stack_line_reader.h" +#include "filesystem_for_testing.h" + +#include "gtest/gtest.h" + +namespace cpu_features { + +bool operator==(const StringView& a, const StringView& b) { + return CpuFeatures_StringView_IsEquals(a, b); +} + +namespace { + +std::string ToString(StringView view) { return {view.ptr, view.size}; } + +TEST(StackLineReaderTest, Empty) { + auto& fs = GetEmptyFilesystem(); + auto* file = fs.CreateFile("/proc/cpuinfo", ""); + StackLineReader reader; + StackLineReader_Initialize(&reader, file->GetFileDescriptor()); + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_TRUE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("")); + } +} + +TEST(StackLineReaderTest, ManySmallLines) { + auto& fs = GetEmptyFilesystem(); + auto* file = fs.CreateFile("/proc/cpuinfo", "a\nb\nc"); + + StackLineReader reader; + StackLineReader_Initialize(&reader, file->GetFileDescriptor()); + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("a")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("b")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_TRUE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("c")); + } +} + +TEST(StackLineReaderTest, TruncatedLine) { + auto& fs = GetEmptyFilesystem(); + auto* file = fs.CreateFile("/proc/cpuinfo", R"(First +Second +More than 16 characters, this will be truncated. +last)"); + + StackLineReader reader; + StackLineReader_Initialize(&reader, file->GetFileDescriptor()); + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("First")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("Second")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_FALSE(result.full_line); + EXPECT_EQ(result.line, str("More than 16 cha")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_TRUE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("last")); + } +} + +TEST(StackLineReaderTest, TruncatedLines) { + auto& fs = GetEmptyFilesystem(); + auto* file = fs.CreateFile("/proc/cpuinfo", R"(More than 16 characters +Another line that is too long)"); + + StackLineReader reader; + StackLineReader_Initialize(&reader, file->GetFileDescriptor()); + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_FALSE(result.full_line); + EXPECT_EQ(result.line, str("More than 16 cha")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_FALSE(result.eof); + EXPECT_FALSE(result.full_line); + EXPECT_EQ(result.line, str("Another line tha")); + } + { + const auto result = StackLineReader_NextLine(&reader); + EXPECT_TRUE(result.eof); + EXPECT_TRUE(result.full_line); + EXPECT_EQ(result.line, str("")); + } +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc b/cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc new file mode 100644 index 000000000000..abfcc2cdffcf --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc @@ -0,0 +1,144 @@ +// 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. + +#include "internal/string_view.h" + +#include "gtest/gtest.h" + +namespace cpu_features { + +bool operator==(const StringView& a, const StringView& b) { + return CpuFeatures_StringView_IsEquals(a, b); +} + +namespace { + +TEST(StringViewTest, Empty) { + EXPECT_EQ(kEmptyStringView.ptr, nullptr); + EXPECT_EQ(kEmptyStringView.size, 0); +} + +TEST(StringViewTest, Build) { + const auto view = str("test"); + EXPECT_EQ(view.ptr[0], 't'); + EXPECT_EQ(view.size, 4); +} + +TEST(StringViewTest, CpuFeatures_StringView_IndexOfChar) { + // Found. + EXPECT_EQ(CpuFeatures_StringView_IndexOfChar(str("test"), 'e'), 1); + // Not found. + EXPECT_EQ(CpuFeatures_StringView_IndexOfChar(str("test"), 'z'), -1); + // Empty. + EXPECT_EQ(CpuFeatures_StringView_IndexOfChar(kEmptyStringView, 'z'), -1); +} + +TEST(StringViewTest, CpuFeatures_StringView_IndexOf) { + // Found. + EXPECT_EQ(CpuFeatures_StringView_IndexOf(str("test"), str("es")), 1); + // Not found. + EXPECT_EQ(CpuFeatures_StringView_IndexOf(str("test"), str("aa")), -1); + // Empty. + EXPECT_EQ(CpuFeatures_StringView_IndexOf(kEmptyStringView, str("aa")), -1); + EXPECT_EQ(CpuFeatures_StringView_IndexOf(str("aa"), kEmptyStringView), -1); +} + +TEST(StringViewTest, CpuFeatures_StringView_StartsWith) { + EXPECT_TRUE(CpuFeatures_StringView_StartsWith(str("test"), str("te"))); + EXPECT_FALSE(CpuFeatures_StringView_StartsWith(str("test"), str(""))); + EXPECT_FALSE( + CpuFeatures_StringView_StartsWith(str("test"), kEmptyStringView)); + EXPECT_FALSE( + CpuFeatures_StringView_StartsWith(kEmptyStringView, str("test"))); +} + +TEST(StringViewTest, CpuFeatures_StringView_IsEquals) { + EXPECT_TRUE( + CpuFeatures_StringView_IsEquals(kEmptyStringView, kEmptyStringView)); + EXPECT_TRUE(CpuFeatures_StringView_IsEquals(kEmptyStringView, str(""))); + EXPECT_TRUE(CpuFeatures_StringView_IsEquals(str(""), kEmptyStringView)); + EXPECT_TRUE(CpuFeatures_StringView_IsEquals(str("a"), str("a"))); + EXPECT_FALSE(CpuFeatures_StringView_IsEquals(str("a"), str("b"))); + EXPECT_FALSE(CpuFeatures_StringView_IsEquals(str("a"), kEmptyStringView)); + EXPECT_FALSE(CpuFeatures_StringView_IsEquals(kEmptyStringView, str("a"))); +} + +TEST(StringViewTest, CpuFeatures_StringView_PopFront) { + EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 2), str("st")); + EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 0), str("test")); + EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 4), str("")); + EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 100), str("")); +} + +TEST(StringViewTest, CpuFeatures_StringView_ParsePositiveNumber) { + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("42")), 42); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2a")), 42); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2A")), 42); + + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("-0x2A")), -1); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("abc")), -1); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("")), -1); +} + +TEST(StringViewTest, CpuFeatures_StringView_CopyString) { + char buf[4]; + buf[0] = 'X'; + + // Empty + CpuFeatures_StringView_CopyString(str(""), buf, sizeof(buf)); + EXPECT_STREQ(buf, ""); + + // Less + CpuFeatures_StringView_CopyString(str("a"), buf, sizeof(buf)); + EXPECT_STREQ(buf, "a"); + + // exact + CpuFeatures_StringView_CopyString(str("abc"), buf, sizeof(buf)); + EXPECT_STREQ(buf, "abc"); + + // More + CpuFeatures_StringView_CopyString(str("abcd"), buf, sizeof(buf)); + EXPECT_STREQ(buf, "abc"); +} + +TEST(StringViewTest, CpuFeatures_StringView_HasWord) { + // Find flags at beginning, middle and end. + EXPECT_TRUE( + CpuFeatures_StringView_HasWord(str("first middle last"), "first")); + EXPECT_TRUE( + CpuFeatures_StringView_HasWord(str("first middle last"), "middle")); + EXPECT_TRUE(CpuFeatures_StringView_HasWord(str("first middle last"), "last")); + // Do not match partial flags + EXPECT_FALSE( + CpuFeatures_StringView_HasWord(str("first middle last"), "irst")); + EXPECT_FALSE(CpuFeatures_StringView_HasWord(str("first middle last"), "mid")); + EXPECT_FALSE(CpuFeatures_StringView_HasWord(str("first middle last"), "las")); +} + +TEST(StringViewTest, CpuFeatures_StringView_GetAttributeKeyValue) { + const StringView line = str(" key : first middle last "); + StringView key, value; + EXPECT_TRUE(CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)); + EXPECT_EQ(key, str("key")); + EXPECT_EQ(value, str("first middle last")); +} + +TEST(StringViewTest, FailingGetAttributeKeyValue) { + const StringView line = str("key first middle last"); + StringView key, value; + EXPECT_FALSE(CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)); +} + +} // namespace +} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc b/cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc new file mode 100644 index 000000000000..dd491f25a2e3 --- /dev/null +++ b/cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc @@ -0,0 +1,95 @@ +// 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. + +#include + +#include "internal/unix_features_aggregator.h" + +#include "gtest/gtest.h" + +namespace cpu_features { + +namespace { + +struct Features { + bool a = false; + bool b = false; + bool c = false; +}; + +DECLARE_SETTER(Features, a) +DECLARE_SETTER(Features, b) +DECLARE_SETTER(Features, c) + +class LinuxFeatureAggregatorTest : public testing::Test { + public: + const std::array kConfigs = { + {{{0b0001, 0b0000}, "a", &set_a}, + {{0b0010, 0b0000}, "b", &set_b}, + {{0b0000, 0b1100}, "c", &set_c}}}; +}; + +TEST_F(LinuxFeatureAggregatorTest, FromFlagsEmpty) { + Features features; + CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str(""), + &features); + EXPECT_FALSE(features.a); + EXPECT_FALSE(features.b); + EXPECT_FALSE(features.c); +} + +TEST_F(LinuxFeatureAggregatorTest, FromFlagsAllSet) { + Features features; + CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str("a c b"), + &features); + EXPECT_TRUE(features.a); + EXPECT_TRUE(features.b); + EXPECT_TRUE(features.c); +} + +TEST_F(LinuxFeatureAggregatorTest, FromFlagsOnlyA) { + Features features; + CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str("a"), + &features); + EXPECT_TRUE(features.a); + EXPECT_FALSE(features.b); + EXPECT_FALSE(features.c); +} + +TEST_F(LinuxFeatureAggregatorTest, FromHwcapsNone) { + HardwareCapabilities capability; + capability.hwcaps = 0; // matches none + capability.hwcaps2 = 0; // matches none + Features features; + CpuFeatures_OverrideFromHwCaps(kConfigs.size(), kConfigs.data(), capability, + &features); + EXPECT_FALSE(features.a); + EXPECT_FALSE(features.b); + EXPECT_FALSE(features.c); +} + +TEST_F(LinuxFeatureAggregatorTest, FromHwcapsSet) { + HardwareCapabilities capability; + capability.hwcaps = 0b0010; // matches b but not a + capability.hwcaps2 = 0b1111; // matches c + Features features; + CpuFeatures_OverrideFromHwCaps(kConfigs.size(), kConfigs.data(), capability, + &features); + EXPECT_FALSE(features.a); + EXPECT_TRUE(features.b); + EXPECT_TRUE(features.c); +} + +} // namespace +} // namespace cpu_features From 47c62df64c2de308090a25d7a4c1bfd5a6997bad Mon Sep 17 00:00:00 2001 From: Areg Melik-Adamyan Date: Thu, 25 Apr 2019 03:07:41 -0500 Subject: [PATCH 2/5] CpuInfo is refactored to use Google's cpu_features library. --- cpp/src/arrow/compute/context.cc | 2 +- cpp/src/arrow/util/cpu-info.cc | 284 ++------------------------ cpp/src/arrow/util/cpu-info.h | 91 +++------ cpp/src/arrow/vendored/CMakeLists.txt | 2 + 4 files changed, 53 insertions(+), 326 deletions(-) diff --git a/cpp/src/arrow/compute/context.cc b/cpp/src/arrow/compute/context.cc index 82c0c238ae46..10779b7795b8 100644 --- a/cpp/src/arrow/compute/context.cc +++ b/cpp/src/arrow/compute/context.cc @@ -26,7 +26,7 @@ namespace arrow { namespace compute { FunctionContext::FunctionContext(MemoryPool* pool) - : pool_(pool), cpu_info_(internal::CpuInfo::GetInstance()) {} + : pool_(pool), cpu_info_(&internal::CpuInfo::GetInstance()) {} MemoryPool* FunctionContext::memory_pool() const { return pool_; } diff --git a/cpp/src/arrow/util/cpu-info.cc b/cpp/src/arrow/util/cpu-info.cc index 9a8cde67ebaa..32cfd9bf3fdf 100644 --- a/cpp/src/arrow/util/cpu-info.cc +++ b/cpp/src/arrow/util/cpu-info.cc @@ -31,11 +31,7 @@ #endif #ifdef _WIN32 -#include -#include -#include #include "arrow/util/windows_compatibility.h" - #endif #include @@ -50,285 +46,41 @@ #include "arrow/util/logging.h" -using boost::algorithm::contains; -using boost::algorithm::trim; -using std::max; - -#if defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 5 -void __cpuidex(int CPUInfo[4], int function_id, int subfunction_id) { - __asm__ __volatile__("cpuid" - : "=a"(CPUInfo[0]), "=b"(CPUInfo[1]), "=c"(CPUInfo[2]), - "=d"(CPUInfo[3]) - : "a"(function_id), "c"(subfunction_id)); -} -#endif - namespace arrow { namespace internal { - -static struct { - std::string name; - int64_t flag; -} flag_mappings[] = { - {"ssse3", CpuInfo::SSSE3}, - {"sse4_1", CpuInfo::SSE4_1}, - {"sse4_2", CpuInfo::SSE4_2}, - {"popcnt", CpuInfo::POPCNT}, -}; -static const int64_t num_flags = sizeof(flag_mappings) / sizeof(flag_mappings[0]); - -#ifndef _WIN32 -namespace { - -// Helper function to parse for hardware flags. -// values contains a list of space-seperated flags. check to see if the flags we -// care about are present. -// Returns a bitmap of flags. -int64_t ParseCPUFlags(const std::string& values) { - int64_t flags = 0; - for (int i = 0; i < num_flags; ++i) { - if (contains(values, flag_mappings[i].name)) { - flags |= flag_mappings[i].flag; - } - } - return flags; -} - -} // namespace -#endif - -#ifdef _WIN32 -bool RetrieveCacheSize(int64_t* cache_sizes) { - if (!cache_sizes) { - return false; - } - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = nullptr; - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer_position = nullptr; - DWORD buffer_size = 0; - size_t offset = 0; - typedef BOOL(WINAPI * GetLogicalProcessorInformationFuncPointer)(void*, void*); - GetLogicalProcessorInformationFuncPointer func_pointer = - (GetLogicalProcessorInformationFuncPointer)GetProcAddress( - GetModuleHandle("kernel32"), "GetLogicalProcessorInformation"); - - if (!func_pointer) { - return false; - } - - // Get buffer size - if (func_pointer(buffer, &buffer_size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return false; - - buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(buffer_size); - - if (!buffer || !func_pointer(buffer, &buffer_size)) { - return false; - } - - buffer_position = buffer; - while (offset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= buffer_size) { - if (RelationCache == buffer_position->Relationship) { - PCACHE_DESCRIPTOR cache = &buffer_position->Cache; - if (cache->Level >= 1 && cache->Level <= 3) { - cache_sizes[cache->Level - 1] += cache->Size; - } - } - offset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); - buffer_position++; - } - - if (buffer) { - free(buffer); - } - return true; + +const cpu_features::X86Features CpuInfo::features_ = cpu_features::GetX86Info().features; + +CpuInfo& CpuInfo::GetInstance() { + // There is no need for heavyweight singleton, + // as CPUID is faster and will always return the same value + static CpuInfo instance; + return instance; } -bool RetrieveCPUInfo(int64_t* hardware_flags, std::string* model_name) { - if (!hardware_flags || !model_name) { - return false; - } - const int register_ECX_id = 1; - int highest_valid_id = 0; - int highest_extended_valid_id = 0; - std::bitset<32> features_ECX; - std::array cpu_info; - - // Get highest valid id - __cpuid(cpu_info.data(), 0); - highest_valid_id = cpu_info[0]; - - if (highest_valid_id <= register_ECX_id) return false; - - __cpuidex(cpu_info.data(), register_ECX_id, 0); - features_ECX = cpu_info[2]; - - // Get highest extended id - __cpuid(cpu_info.data(), 0x80000000); - highest_extended_valid_id = cpu_info[0]; - - // Retrieve CPU model name - if (highest_extended_valid_id >= static_cast(0x80000004)) { - model_name->clear(); - for (int i = 0x80000002; i <= static_cast(0x80000004); ++i) { - __cpuidex(cpu_info.data(), i, 0); - *model_name += - std::string(reinterpret_cast(cpu_info.data()), sizeof(cpu_info)); - } - } - - if (features_ECX[9]) *hardware_flags |= CpuInfo::SSSE3; - if (features_ECX[19]) *hardware_flags |= CpuInfo::SSE4_1; - if (features_ECX[20]) *hardware_flags |= CpuInfo::SSE4_2; - if (features_ECX[23]) *hardware_flags |= CpuInfo::POPCNT; - return true; +const cpu_features::X86Features CpuInfo::Features() const { + return features_; } -#endif - -CpuInfo::CpuInfo() : hardware_flags_(0), num_cores_(1), model_name_("unknown") {} - -std::unique_ptr g_cpu_info; -static std::mutex cpuinfo_mutex; -CpuInfo* CpuInfo::GetInstance() { - std::lock_guard lock(cpuinfo_mutex); - if (!g_cpu_info) { - g_cpu_info.reset(new CpuInfo); - g_cpu_info->Init(); - } - return g_cpu_info.get(); -} - -void CpuInfo::Init() { - std::string line; - std::string name; - std::string value; - - float max_mhz = 0; - int num_cores = 0; - - memset(&cache_sizes_, 0, sizeof(cache_sizes_)); - -#ifdef _WIN32 - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - num_cores = system_info.dwNumberOfProcessors; - - LARGE_INTEGER performance_frequency; - if (QueryPerformanceFrequency(&performance_frequency)) { - max_mhz = static_cast(performance_frequency.QuadPart); - } -#else - // Read from /proc/cpuinfo - std::ifstream cpuinfo("/proc/cpuinfo", std::ios::in); - while (cpuinfo) { - getline(cpuinfo, line); - size_t colon = line.find(':'); - if (colon != std::string::npos) { - name = line.substr(0, colon - 1); - value = line.substr(colon + 1, std::string::npos); - trim(name); - trim(value); - if (name.compare("flags") == 0) { - hardware_flags_ |= ParseCPUFlags(value); - } else if (name.compare("cpu MHz") == 0) { - // Every core will report a different speed. We'll take the max, assuming - // that when impala is running, the core will not be in a lower power state. - // TODO: is there a more robust way to do this, such as - // Window's QueryPerformanceFrequency() - float mhz = static_cast(atof(value.c_str())); - max_mhz = max(mhz, max_mhz); - } else if (name.compare("processor") == 0) { - ++num_cores; - } else if (name.compare("model name") == 0) { - model_name_ = value; - } - } - } - if (cpuinfo.is_open()) cpuinfo.close(); -#endif - -#ifdef __APPLE__ - // On Mac OS X use sysctl() to get the cache sizes - size_t len = 0; - sysctlbyname("hw.cachesize", NULL, &len, NULL, 0); - uint64_t* data = static_cast(malloc(len)); - sysctlbyname("hw.cachesize", data, &len, NULL, 0); - DCHECK_GE(len / sizeof(uint64_t), 3); - for (size_t i = 0; i < 3; ++i) { - cache_sizes_[i] = data[i]; - } -#elif _WIN32 - if (!RetrieveCacheSize(cache_sizes_)) { - SetDefaultCacheSize(); - } - RetrieveCPUInfo(&hardware_flags_, &model_name_); -#else - SetDefaultCacheSize(); -#endif - - if (max_mhz != 0) { - cycles_per_ms_ = static_cast(max_mhz); -#ifndef _WIN32 - cycles_per_ms_ *= 1000; -#endif - } else { - cycles_per_ms_ = 1000000; - } - original_hardware_flags_ = hardware_flags_; - - if (num_cores > 0) { - num_cores_ = num_cores; - } else { - num_cores_ = 1; - } -} - -void CpuInfo::VerifyCpuRequirements() { - if (!IsSupported(CpuInfo::SSSE3)) { +void CpuInfo::CheckMinCpuAndHalt() { + if (!features_.ssse3) { DCHECK(false) << "CPU does not support the Supplemental SSE3 instruction set"; } } bool CpuInfo::CanUseSSE4_2() const { #ifdef ARROW_USE_SIMD - return IsSupported(CpuInfo::SSE4_2); + return features_.sse4_2; #else return false; #endif } -void CpuInfo::EnableFeature(int64_t flag, bool enable) { - if (!enable) { - hardware_flags_ &= ~flag; - } else { - // Can't turn something on that can't be supported - DCHECK_NE(original_hardware_flags_ & flag, 0); - hardware_flags_ |= flag; - } -} - -int64_t CpuInfo::hardware_flags() { return hardware_flags_; } - -int64_t CpuInfo::CacheSize(CacheLevel level) { return cache_sizes_[level]; } - -int64_t CpuInfo::cycles_per_ms() { return cycles_per_ms_; } - -int CpuInfo::num_cores() { return num_cores_; } - -std::string CpuInfo::model_name() { return model_name_; } - -void CpuInfo::SetDefaultCacheSize() { -#ifndef _SC_LEVEL1_DCACHE_SIZE - // Provide reasonable default values if no info - cache_sizes_[0] = 32 * 1024; // Level 1: 32k - cache_sizes_[1] = 256 * 1024; // Level 2: 256k - cache_sizes_[2] = 3072 * 1024; // Level 3: 3M -#else - // Call sysconf to query for the cache sizes - cache_sizes_[0] = sysconf(_SC_LEVEL1_DCACHE_SIZE); - cache_sizes_[1] = sysconf(_SC_LEVEL2_CACHE_SIZE); - cache_sizes_[2] = sysconf(_SC_LEVEL3_CACHE_SIZE); -#endif +std::string CpuInfo::ModelName() { + char brand_string[49]; + const cpu_features::X86Info info = cpu_features::GetX86Info(); + cpu_features::FillX86BrandString( brand_string ); + return brand_string; } } // namespace internal diff --git a/cpp/src/arrow/util/cpu-info.h b/cpp/src/arrow/util/cpu-info.h index 714d7ac5bc56..2409c6040db3 100644 --- a/cpp/src/arrow/util/cpu-info.h +++ b/cpp/src/arrow/util/cpu-info.h @@ -15,9 +15,6 @@ // specific language governing permissions and limitations // under the License. -// From Apache Impala (incubating) as of 2016-01-29. Pared down to a minimal -// set of functions needed for Apache Arrow / Apache parquet-cpp - #ifndef ARROW_UTIL_CPU_INFO_H #define ARROW_UTIL_CPU_INFO_H @@ -25,74 +22,50 @@ #include #include "arrow/util/visibility.h" +#include "arrow/vendored/cpu_features/include/cpu_features_macros.h" + +#if defined(CPU_FEATURES_ARCH_X86) +#include "arrow/vendored/cpu_features/include/cpuinfo_x86.h" +#endif namespace arrow { namespace internal { /// CpuInfo is an interface to query for cpu information at runtime. The caller can -/// ask for the sizes of the caches and what hardware features are supported. -/// On Linux, this information is pulled from a couple of sys files (/proc/cpuinfo and -/// /sys/devices) +/// query on hardware features support, i.e. is SSSE4. AVX2, etc. +/// It is cross platform as Google's cpu_features library is used under the hood class ARROW_EXPORT CpuInfo { public: - static constexpr int64_t SSSE3 = (1 << 1); - static constexpr int64_t SSE4_1 = (1 << 2); - static constexpr int64_t SSE4_2 = (1 << 3); - static constexpr int64_t POPCNT = (1 << 4); - - /// Cache enums for L1 (data), L2 and L3 - enum CacheLevel { - L1_CACHE = 0, - L2_CACHE = 1, - L3_CACHE = 2, - }; - - static CpuInfo* GetInstance(); - /// Determine if the CPU meets the minimum CPU requirements and if not, issue an error - /// and terminate. - void VerifyCpuRequirements(); - - /// Returns all the flags for this cpu - int64_t hardware_flags(); - - /// Returns whether of not the cpu supports this flag - bool IsSupported(int64_t flag) const { return (hardware_flags_ & flag) != 0; } - - /// \brief The processor supports SSE4.2 and the Arrow libraries are built - /// with support for it - bool CanUseSSE4_2() const; - - /// Toggle a hardware feature on and off. It is not valid to turn on a feature - /// that the underlying hardware cannot support. This is useful for testing. - void EnableFeature(int64_t flag, bool enable); - - /// Returns the size of the cache in KB at this cache level - int64_t CacheSize(CacheLevel level); - - /// Returns the number of cpu cycles per millisecond - int64_t cycles_per_ms(); - - /// Returns the number of cores (including hyper-threaded) on this machine. - int num_cores(); + /// CpuInfo is defined as a singletion without rigorious thread safety checks, + /// as CPUID is safe itself + static CpuInfo& GetInstance(); /// Returns the model name of the cpu (e.g. Intel i7-2600) - std::string model_name(); + std::string ModelName(); - private: - CpuInfo(); - - void Init(); - - /// Inits CPU cache size variables with default values - void SetDefaultCacheSize(); + /// Checks for the existence of SSE 4.2 on x*6-64 compatible processors + bool CanUseSSE4_2() const; - int64_t hardware_flags_; - int64_t original_hardware_flags_; - int64_t cache_sizes_[L3_CACHE + 1]; - int64_t cycles_per_ms_; - int num_cores_; - std::string model_name_; + /// Checks for the existence of Suplemental SSE3 and halts if the feature is not available + void CheckMinCpuAndHalt(); + + /// Returns the initialized feature type appropriate for the current arhcitecture +#if defined(CPU_FEATURES_ARCH_X86) + const cpu_features::X86Features +#endif + Features() const; + +private : + CpuInfo() = default; + ~CpuInfo() = default; + CpuInfo(const CpuInfo&) = delete; + CpuInfo& operator=(const CpuInfo&) = delete; + +private: +#if defined(CPU_FEATURES_ARCH_X86) + static const cpu_features::X86Features features_; +#endif }; } // namespace internal diff --git a/cpp/src/arrow/vendored/CMakeLists.txt b/cpp/src/arrow/vendored/CMakeLists.txt index 4cda3f852ec9..0702e90e1b42 100644 --- a/cpp/src/arrow/vendored/CMakeLists.txt +++ b/cpp/src/arrow/vendored/CMakeLists.txt @@ -19,3 +19,5 @@ arrow_install_all_headers("arrow/vendored") add_subdirectory(datetime) add_subdirectory(variant) +add_subdirectory(cpu_features) + From 31de5a6bb5011efe4c409cc86eb983364b60cf73 Mon Sep 17 00:00:00 2001 From: Areg Melik-Adamyan Date: Thu, 25 Apr 2019 03:25:26 -0500 Subject: [PATCH 3/5] Removed a comment to trigger CI --- cpp/src/arrow/util/cpu-info.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/src/arrow/util/cpu-info.cc b/cpp/src/arrow/util/cpu-info.cc index 32cfd9bf3fdf..a784e34b53b4 100644 --- a/cpp/src/arrow/util/cpu-info.cc +++ b/cpp/src/arrow/util/cpu-info.cc @@ -15,8 +15,6 @@ // specific language governing permissions and limitations // under the License. -// From Apache Impala (incubating) as of 2016-01-29. - #include "arrow/util/cpu-info.h" #ifdef __APPLE__ From 565789eee0c4e1eadc8436933a18face97b756d6 Mon Sep 17 00:00:00 2001 From: Areg Melik-Adamyan Date: Thu, 25 Apr 2019 13:19:20 -0500 Subject: [PATCH 4/5] Another attempt to pass Appveyor... --- cpp/src/arrow/util/cpu-info.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cpp/src/arrow/util/cpu-info.cc b/cpp/src/arrow/util/cpu-info.cc index a784e34b53b4..032419f33f04 100644 --- a/cpp/src/arrow/util/cpu-info.cc +++ b/cpp/src/arrow/util/cpu-info.cc @@ -24,10 +24,6 @@ #include #include -#ifndef _MSC_VER -#include -#endif - #ifdef _WIN32 #include "arrow/util/windows_compatibility.h" #endif From a2004fa3c4ad05f1146e7f693caf3c1e6c7ca3a2 Mon Sep 17 00:00:00 2001 From: Artem Alekseev Date: Tue, 16 Jul 2019 07:40:28 +0000 Subject: [PATCH 5/5] use conda-forge's cpu_features --- ci/conda_env_cpp.yml | 1 + cpp/CMakeLists.txt | 3 + cpp/cmake_modules/Findcpu_features.cmake | 37 ++ cpp/cmake_modules/ThirdpartyToolchain.cmake | 61 ++- cpp/src/arrow/util/cpu-info.cc | 1 - cpp/src/arrow/util/cpu-info.h | 5 +- .../arrow/vendored/cpu_features/.clang-format | 4 - .../arrow/vendored/cpu_features/.gitignore | 1 - .../arrow/vendored/cpu_features/.travis.yml | 117 ---- .../vendored/cpu_features/CMakeLists.txt | 234 -------- .../vendored/cpu_features/CONTRIBUTING.md | 23 - cpp/src/arrow/vendored/cpu_features/LICENSE | 202 ------- cpp/src/arrow/vendored/cpu_features/README.md | 174 ------ cpp/src/arrow/vendored/cpu_features/WORKSPACE | 7 - .../arrow/vendored/cpu_features/appveyor.yml | 24 - .../cmake/CpuFeaturesConfig.cmake.in | 3 - .../cmake/CpuFeaturesNdkCompatConfig.cmake.in | 3 - .../vendored/cpu_features/cmake/README.md | 28 - .../cmake/googletest.CMakeLists.txt.in | 15 - .../include/cpu_features_macros.h | 143 ----- .../cpu_features/include/cpuinfo_aarch64.h | 69 --- .../cpu_features/include/cpuinfo_arm.h | 88 --- .../cpu_features/include/cpuinfo_mips.h | 59 -- .../cpu_features/include/cpuinfo_ppc.h | 145 ----- .../cpu_features/include/cpuinfo_x86.h | 167 ------ .../cpu_features/include/internal/bit_utils.h | 39 -- .../cpu_features/include/internal/cpuid_x86.h | 37 -- .../include/internal/filesystem.h | 38 -- .../cpu_features/include/internal/hwcaps.h | 124 ----- .../include/internal/stack_line_reader.h | 49 -- .../include/internal/string_view.h | 108 ---- .../internal/unix_features_aggregator.h | 60 -- .../cpu_features/ndk_compat/CMakeLists.txt | 59 -- .../cpu_features/ndk_compat/README.md | 4 - .../cpu_features/ndk_compat/cpu-features.c | 204 ------- .../cpu_features/ndk_compat/cpu-features.h | 320 ----------- .../cpu_features/ndk_compat/ndk-compat-test.c | 11 - .../cpu_features/scripts/run_integration.sh | 209 ------- .../cpu_features/scripts/test_integration.sh | 106 ---- .../cpu_features/src/cpuinfo_aarch64.c | 141 ----- .../vendored/cpu_features/src/cpuinfo_arm.c | 259 --------- .../vendored/cpu_features/src/cpuinfo_mips.c | 104 ---- .../vendored/cpu_features/src/cpuinfo_ppc.c | 358 ------------ .../vendored/cpu_features/src/cpuinfo_x86.c | 518 ------------------ .../vendored/cpu_features/src/filesystem.c | 59 -- .../arrow/vendored/cpu_features/src/hwcaps.c | 162 ------ .../cpu_features/src/stack_line_reader.c | 131 ----- .../vendored/cpu_features/src/string_view.c | 182 ------ .../src/unix_features_aggregator.c | 52 -- .../src/utils/list_cpu_features.c | 246 --------- .../vendored/cpu_features/test/CMakeLists.txt | 92 ---- .../cpu_features/test/bit_utils_test.cc | 53 -- .../cpu_features/test/cpuinfo_aarch64_test.cc | 74 --- .../cpu_features/test/cpuinfo_arm_test.cc | 186 ------- .../cpu_features/test/cpuinfo_mips_test.cc | 126 ----- .../cpu_features/test/cpuinfo_ppc_test.cc | 119 ---- .../cpu_features/test/cpuinfo_x86_test.cc | 176 ------ .../test/filesystem_for_testing.cc | 103 ---- .../test/filesystem_for_testing.h | 61 --- .../cpu_features/test/hwcaps_for_testing.cc | 45 -- .../cpu_features/test/hwcaps_for_testing.h | 27 - .../test/stack_line_reader_test.cc | 132 ----- .../cpu_features/test/string_view_test.cc | 144 ----- .../test/unix_features_aggregator_test.cc | 95 ---- cpp/thirdparty/versions.txt | 1 + dev/tasks/conda-recipes/arrow-cpp/meta.yaml | 2 + 66 files changed, 106 insertions(+), 6524 deletions(-) create mode 100644 cpp/cmake_modules/Findcpu_features.cmake delete mode 100644 cpp/src/arrow/vendored/cpu_features/.clang-format delete mode 100644 cpp/src/arrow/vendored/cpu_features/.gitignore delete mode 100644 cpp/src/arrow/vendored/cpu_features/.travis.yml delete mode 100644 cpp/src/arrow/vendored/cpu_features/CMakeLists.txt delete mode 100644 cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md delete mode 100644 cpp/src/arrow/vendored/cpu_features/LICENSE delete mode 100644 cpp/src/arrow/vendored/cpu_features/README.md delete mode 100644 cpp/src/arrow/vendored/cpu_features/WORKSPACE delete mode 100644 cpp/src/arrow/vendored/cpu_features/appveyor.yml delete mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in delete mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in delete mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/README.md delete mode 100644 cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt delete mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md delete mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh delete mode 100644 cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/filesystem.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/hwcaps.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/string_view.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc delete mode 100644 cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc diff --git a/ci/conda_env_cpp.yml b/ci/conda_env_cpp.yml index fd21ed8d3faf..e5e4bace1aea 100644 --- a/ci/conda_env_cpp.yml +++ b/ci/conda_env_cpp.yml @@ -21,6 +21,7 @@ brotli bzip2 c-ares cmake +cpu_features double-conversion flatbuffers gflags diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 93b5f0199c16..56265eeb5fac 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -578,6 +578,9 @@ set(ARROW_LINK_LIBS ${double-conversion_LIBRARIES}) set(ARROW_STATIC_LINK_LIBS ${double-conversion_LIBRARIES}) set(ARROW_STATIC_INSTALL_INTERFACE_LIBS ${double-conversion_LIBRARIES}) +list(APPEND ARROW_STATIC_LINK_LIBS cpu_features::cpu_features) +list(APPEND ARROW_STATIC_INSTALL_INTERFACE_LIBS cpu_features::cpu_features) + if(ARROW_WITH_URIPARSER) list(APPEND ARROW_STATIC_LINK_LIBS uriparser::uriparser) list(APPEND ARROW_STATIC_INSTALL_INTERFACE_LIBS uriparser::uriparser) diff --git a/cpp/cmake_modules/Findcpu_features.cmake b/cpp/cmake_modules/Findcpu_features.cmake new file mode 100644 index 000000000000..542fd2411916 --- /dev/null +++ b/cpp/cmake_modules/Findcpu_features.cmake @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +if(cpu_features_ROOT) + find_library(cpu_features_LIB + NAMES cpu_features + PATHS ${cpu_features_ROOT} + NO_DEFAULT_PATH + PATH_SUFFIXES ${LIB_PATH_SUFFIXES}) +else() + find_library(cpu_features_LIB NAMES cpu_features) +endif() + +find_package_handle_standard_args(cpu_features REQUIRED_VARS cpu_features_LIB + cpu_features_INCLUDE_DIR) + +if(cpu_features_FOUND) + add_library(cpu_features::cpu_features UNKNOWN IMPORTED) + set_target_properties(cpu_features::cpu_features + PROPERTIES IMPORTED_LOCATION "${cpu_features_LIB}" + INTERFACE_INCLUDE_DIRECTORIES + "${cpu_features_INCLUDE_DIR}") +endif() diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake index aa1e557af809..66bbe11db97d 100644 --- a/cpp/cmake_modules/ThirdpartyToolchain.cmake +++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake @@ -73,7 +73,8 @@ set(ARROW_THIRDPARTY_DEPENDENCIES Thrift uriparser ZLIB - ZSTD) + ZSTD + cpu_features) # TODO(wesm): External GTest shared libraries are not currently # supported when building with MSVC because of the way that @@ -162,6 +163,8 @@ macro(build_dependency DEPENDENCY_NAME) build_zlib() elseif("${DEPENDENCY_NAME}" STREQUAL "ZSTD") build_zstd() + elseif("${DEPENDENCY_NAME}" STREQUAL "cpu_features") + build_cpu_features() else() message(FATAL_ERROR "Unknown thirdparty dependency to build: ${DEPENDENCY_NAME}") endif() @@ -412,6 +415,12 @@ else() set(BZIP2_SOURCE_URL "https://fossies.org/linux/misc/bzip2-${BZIP2_VERSION}.tar.gz") endif() +if(DEFINED ENV{ARROW_CPU_FEATURES_URL}) + set(CPU_FEATURES_SOURCE_URL "$ENV{ARROW_CPU_FEATURES_URL}") +else() + set(CPU_FEATURES_SOURCE_URL "https://github.com/google/cpu_features/archive/${CPU_FEATURES_VERSION}.tar.gz") +endif() + # ---------------------------------------------------------------------- # ExternalProject options @@ -2366,6 +2375,56 @@ if(ARROW_ORC) message(STATUS "Found ORC headers: ${ORC_INCLUDE_DIR}") endif() +# ---------------------------------------------------------------------- +# cpu_features +macro(build_cpu_features) + message(STATUS "Building cpu_features from source") + set(CPU_FEATURES_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cpu_features_ep-install") + + set(CPU_FEATURES_CMAKE_ARGS + ${EP_COMMON_TOOLCHAIN} + "-DCMAKE_INSTALL_PREFIX=${CPU_FEATURES_PREFIX}" + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}) + + if(MSVC) + set(CPU_FEATURES_STATIC_LIB "${CPU_FEATURES_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cpu_features_static.lib") + else() + set(CPU_FEATURES_STATIC_LIB "${CPU_FEATURES_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libcpu_features.a") + endif() + + externalproject_add(cpu_features_ep + ${EP_LOG_OPTIONS} + CMAKE_ARGS ${CPU_FEATURES_CMAKE_ARGS} + INSTALL_DIR ${CPU_FEATURES_PREFIX} + URL ${CPU_FEATURES_SOURCE_URL} + BUILD_BYPRODUCTS "${CPU_FEATURES_STATIC_LIB}") + + file(MAKE_DIRECTORY "${CPU_FEATURES_PREFIX}/include") + + add_library(cpu_features::cpu_features STATIC IMPORTED) + set_target_properties(cpu_features::cpu_features + PROPERTIES IMPORTED_LOCATION "${CPU_FEATURES_STATIC_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${CPU_FEATURES_PREFIX}/include") + + add_dependencies(toolchain cpu_features_ep) + add_dependencies(cpu_features::cpu_features cpu_features_ep) +endmacro() + +set(ARROW_CPU_FEATURES_REQUIRED_VERSION "0.4.0") +if(cpu_features_SOURCE STREQUAL "AUTO") + find_package(cpu_features ${ARROW_CPU_FEATURES_REQUIRED_VERSION} QUIET) + if(NOT cpu_features_FOUND) + build_cpu_features() + endif() +elseif(cpu_features_SOURCE STREQUAL "BUNDLED") + build_cpu_features() +endif() + +get_target_property(cpu_features_INCLUDE_DIR cpu_features::cpu_features + INTERFACE_INCLUDE_DIRECTORIES) +include_directories(SYSTEM ${cpu_features_INCLUDE_DIR}) + # Write out the package configurations. configure_file("src/arrow/util/config.h.cmake" "src/arrow/util/config.h") diff --git a/cpp/src/arrow/util/cpu-info.cc b/cpp/src/arrow/util/cpu-info.cc index 032419f33f04..a71b722e27f5 100644 --- a/cpp/src/arrow/util/cpu-info.cc +++ b/cpp/src/arrow/util/cpu-info.cc @@ -72,7 +72,6 @@ bool CpuInfo::CanUseSSE4_2() const { std::string CpuInfo::ModelName() { char brand_string[49]; - const cpu_features::X86Info info = cpu_features::GetX86Info(); cpu_features::FillX86BrandString( brand_string ); return brand_string; } diff --git a/cpp/src/arrow/util/cpu-info.h b/cpp/src/arrow/util/cpu-info.h index 2409c6040db3..fbcfd2752d05 100644 --- a/cpp/src/arrow/util/cpu-info.h +++ b/cpp/src/arrow/util/cpu-info.h @@ -22,10 +22,9 @@ #include #include "arrow/util/visibility.h" -#include "arrow/vendored/cpu_features/include/cpu_features_macros.h" - +#include #if defined(CPU_FEATURES_ARCH_X86) -#include "arrow/vendored/cpu_features/include/cpuinfo_x86.h" +#include #endif namespace arrow { diff --git a/cpp/src/arrow/vendored/cpu_features/.clang-format b/cpp/src/arrow/vendored/cpu_features/.clang-format deleted file mode 100644 index 06ea346a1067..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/.clang-format +++ /dev/null @@ -1,4 +0,0 @@ ---- -Language: Cpp -BasedOnStyle: Google -... diff --git a/cpp/src/arrow/vendored/cpu_features/.gitignore b/cpp/src/arrow/vendored/cpu_features/.gitignore deleted file mode 100644 index 0690aa44237d..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cmake_build/ diff --git a/cpp/src/arrow/vendored/cpu_features/.travis.yml b/cpp/src/arrow/vendored/cpu_features/.travis.yml deleted file mode 100644 index e0b4f448d6f9..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/.travis.yml +++ /dev/null @@ -1,117 +0,0 @@ -language: c - -sudo: false - -cache: - timeout: 1000 - directories: - - $HOME/cpu_features_archives - -addons: - apt: - packages: - - ninja-build - -env: - global: - TOOLCHAIN=NATIVE - CMAKE_GENERATOR=Ninja - -matrix: - include: - - os: linux - compiler: gcc - env: - TARGET=x86_64-linux-gnu - - os: linux - compiler: clang - env: - TARGET=x86_64-linux-gnu - - os: osx - compiler: gcc - env: - TARGET=x86_64-osx - CMAKE_GENERATOR="Unix Makefiles" - - os: osx - compiler: clang - env: - TARGET=x86_64-osx - CMAKE_GENERATOR="Unix Makefiles" - - os: windows - env: - TARGET=x86_64-windows - CMAKE_GENERATOR="Visual Studio 15 2017 Win64" - - os: linux-ppc64le - compiler: gcc - env: - TARGET=ppc64le-linux-gnu - - os: linux-ppc64le - compiler: clang - env: - TARGET=ppc64le-linux-gnu - # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=aarch64-linux-gnu - QEMU_ARCH=aarch64 - # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabihf - QEMU_ARCH=arm - # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=armv8l-linux-gnueabihf - QEMU_ARCH=arm - # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabi - QEMU_ARCH=arm - # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=aarch64_be-linux-gnu - QEMU_ARCH=DISABLED - # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabihf - QEMU_ARCH=DISABLED - # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems - - os: linux - env: - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabi - QEMU_ARCH=DISABLED - - os: linux - env: - TOOLCHAIN=CODESCAPE - TARGET=mips32 - QEMU_ARCH=mips - - os: linux - env: - TOOLCHAIN=CODESCAPE - TARGET=mips32el - QEMU_ARCH=mipsel - - os: linux - env: - TOOLCHAIN=CODESCAPE - TARGET=mips64 - QEMU_ARCH=mips64 - - os: linux - env: - TOOLCHAIN=CODESCAPE - TARGET=mips64el - QEMU_ARCH=mips64el - -script: - - cmake --version - - bash -e -x ./scripts/run_integration.sh diff --git a/cpp/src/arrow/vendored/cpu_features/CMakeLists.txt b/cpp/src/arrow/vendored/cpu_features/CMakeLists.txt deleted file mode 100644 index 6e0d33e3bf16..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/CMakeLists.txt +++ /dev/null @@ -1,234 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -project(CpuFeatures VERSION 0.1.0) - -# Default Build Type to be Release -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif(NOT CMAKE_BUILD_TYPE) - -# BUILD_TESTING is a standard CMake variable, but we declare it here to make it -# prominent in the GUI. -option(BUILD_TESTING "Enable test (depends on googletest)." OFF) -# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make -# it prominent in the GUI. -# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field). -# As a consequence it is discouraged to use cpu_features as a shared library because different compilers may interpret the code in different ways. -# Prefer static linking from source whenever possible. -option(BUILD_SHARED_LIBS "Build library as shared." OFF) -# PIC -option(BUILD_PIC "Build with Position Independant Code." OFF) # Default is off at least for GCC - -include(CheckIncludeFile) -include(CheckSymbolExists) -include(GNUInstallDirs) - -macro(setup_include_and_definitions TARGET_NAME) - target_include_directories(${TARGET_NAME} - PUBLIC $ - PRIVATE $ - ) - target_compile_definitions(${TARGET_NAME} - PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024 - ) -endmacro() - -set(PROCESSOR_IS_MIPS FALSE) -set(PROCESSOR_IS_ARM FALSE) -set(PROCESSOR_IS_AARCH64 FALSE) -set(PROCESSOR_IS_X86 FALSE) -set(PROCESSOR_IS_POWER FALSE) - -if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") - set(PROCESSOR_IS_MIPS TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") - set(PROCESSOR_IS_ARM TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") - set(PROCESSOR_IS_AARCH64 TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64)|(^i.86$)") - set(PROCESSOR_IS_X86 TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") - set(PROCESSOR_IS_POWER TRUE) -endif() - -macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) - list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h) - if(PROCESSOR_IS_MIPS) - list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_mips.c) - elseif(PROCESSOR_IS_ARM) - list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_arm.c) - elseif(PROCESSOR_IS_AARCH64) - list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_aarch64.c) - elseif(PROCESSOR_IS_X86) - list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c) - elseif(PROCESSOR_IS_POWER) - list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_ppc.c) - else() - message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") - endif() -endmacro() - -# -# library : utils -# - -add_library(utils OBJECT - ${PROJECT_SOURCE_DIR}/include/internal/bit_utils.h - ${PROJECT_SOURCE_DIR}/include/internal/filesystem.h - ${PROJECT_SOURCE_DIR}/include/internal/stack_line_reader.h - ${PROJECT_SOURCE_DIR}/include/internal/string_view.h - ${PROJECT_SOURCE_DIR}/src/filesystem.c - ${PROJECT_SOURCE_DIR}/src/stack_line_reader.c - ${PROJECT_SOURCE_DIR}/src/string_view.c -) -setup_include_and_definitions(utils) - -arrow_install_all_headers("arrow/vendored/cpu_features") -# -# library : unix_based_hardware_detection -# - -if(UNIX) - add_library(unix_based_hardware_detection OBJECT - ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h - ${PROJECT_SOURCE_DIR}/include/internal/unix_features_aggregator.h - ${PROJECT_SOURCE_DIR}/src/hwcaps.c - ${PROJECT_SOURCE_DIR}/src/unix_features_aggregator.c - ) - setup_include_and_definitions(unix_based_hardware_detection) - check_include_file(dlfcn.h HAVE_DLFCN_H) - if(HAVE_DLFCN_H) - target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H) - endif() - check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL) - if(HAVE_STRONG_GETAUXVAL) - target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL) - endif() - set_property(TARGET unix_based_hardware_detection PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) -endif() - -# -# library : cpu_features -# -set (CPU_FEATURES_HDRS) -set (CPU_FEATURES_SRCS) -add_cpu_features_headers_and_sources(CPU_FEATURES_HDRS CPU_FEATURES_SRCS) -list(APPEND CPU_FEATURES_SRCS $) -if(NOT PROCESSOR_IS_X86 AND UNIX) - list(APPEND CPU_FEATURES_SRCS $) -endif() -add_library(cpu_features ${CPU_FEATURES_HDRS} ${CPU_FEATURES_SRCS}) -set_target_properties(cpu_features PROPERTIES PUBLIC_HEADER "${CPU_FEATURES_HDRS}") -setup_include_and_definitions(cpu_features) -target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS}) -set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}) -target_include_directories(cpu_features - PUBLIC $ -) - -# -# program : list_cpu_features -# - -add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c) -target_link_libraries(list_cpu_features PRIVATE cpu_features) -add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features) - -# -# ndk_compat -# - -if(ANDROID) -add_subdirectory(ndk_compat) -endif() - -# -# tests -# - -include(CTest) -if(BUILD_TESTING) - # Automatically incorporate googletest into the CMake Project if target not - # found. - if(NOT TARGET gtest OR NOT TARGET gmock_main) - # Download and unpack googletest at configure time. - configure_file( - cmake/googletest.CMakeLists.txt.in - googletest-download/CMakeLists.txt - ) - - execute_process( - COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) - - if(result) - message(FATAL_ERROR "CMake step for googletest failed: ${result}") - endif() - - execute_process( - COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) - - if(result) - message(FATAL_ERROR "Build step for googletest failed: ${result}") - endif() - - # Prevent overriding the parent project's compiler/linker settings on - # Windows. - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - - # Add googletest directly to our build. This defines the gtest and - # gtest_main targets. - add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src - ${CMAKE_BINARY_DIR}/googletest-build - EXCLUDE_FROM_ALL) - endif() - - add_subdirectory(test) -endif() - -# -# Install cpu_features and list_cpu_features -# - -include(GNUInstallDirs) -install(TARGETS cpu_features list_cpu_features - EXPORT CpuFeaturesTargets - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) -install(EXPORT CpuFeaturesTargets - NAMESPACE CpuFeatures:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures - COMPONENT Devel -) -include(CMakePackageConfigHelpers) -configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in - "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" - NO_SET_AND_CHECK_MACRO - NO_CHECK_REQUIRED_COMPONENTS_MACRO -) -write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" - COMPATIBILITY SameMajorVersion -) -install( - FILES - "${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" - "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" - COMPONENT Devel -) diff --git a/cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md b/cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md deleted file mode 100644 index c980350f8fc3..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution; -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. diff --git a/cpp/src/arrow/vendored/cpu_features/LICENSE b/cpp/src/arrow/vendored/cpu_features/LICENSE deleted file mode 100644 index 7a4a3ea2424c..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. \ No newline at end of file diff --git a/cpp/src/arrow/vendored/cpu_features/README.md b/cpp/src/arrow/vendored/cpu_features/README.md deleted file mode 100644 index 29d794661cf9..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# cpu_features [![Build Status](https://travis-ci.org/google/cpu_features.svg?branch=master)](https://travis-ci.org/google/cpu_features) [![Build status](https://ci.appveyor.com/api/projects/status/46d1owsj7n8dsylq/branch/master?svg=true)](https://ci.appveyor.com/project/gchatelet/cpu-features/branch/master) - -A cross-platform C library to retrieve CPU features (such as available -instructions) at runtime. - -## Table of Contents - -- [Design Rationale](#rationale) -- [Code samples](#codesample) -- [Running sample code](#usagesample) -- [What's supported](#support) -- [Android NDK's drop in replacement](#ndk) -- [License](#license) -- [Build with cmake](#cmake) - - -## Design Rationale - -- **Simple to use.** See the snippets below for examples. -- **Extensible.** Easy to add missing features or architectures. -- **Compatible with old compilers** and available on many architectures so it - can be used widely. To ensure that cpu_features works on as many platforms - as possible, we implemented it in a highly portable version of C: C99. -- **Sandbox-compatible.** The library uses a variety of strategies to cope - with sandboxed environments or when `cpuid` is unavailable. This is useful - when running integration tests in hermetic environments. -- **Thread safe, no memory allocation, and raises no exceptions.** - cpu_features is suitable for implementing fundamental libc functions like - `malloc`, `memcpy`, and `memcmp`. -- **Unit tested.** - - -### Checking features at runtime - -Here's a simple example that executes a codepath if the CPU supports both the -AES and the SSE4.2 instruction sets: - -```c -#include "cpuinfo_x86.h" - -static const X86Features features = GetX86Info().features; - -void Compute(void) { - if (features.aes && features.sse4_2) { - // Run optimized code. - } else { - // Run standard code. - } -} -``` - -### Caching for faster evaluation of complex checks - -If you wish, you can read all the features at once into a global variable, and -then query for the specific features you care about. Below, we store all the ARM -features and then check whether AES and NEON are supported. - -```c -#include -#include "cpuinfo_arm.h" - -static const ArmFeatures features = GetArmInfo().features; -static const bool has_aes_and_neon = features.aes && features.neon; - -// use has_aes_and_neon. -``` - -This is a good approach to take if you're checking for combinations of features -when using a compiler that is slow to extract individual bits from bit-packed -structures. - -### Checking compile time flags - -The following code determines whether the compiler was told to use the AVX -instruction set (e.g., `g++ -mavx`) and sets `has_avx` accordingly. - -```c -#include -#include "cpuinfo_x86.h" - -static const X86Features features = GetX86Info().features; -static const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx; - -// use has_avx. -``` - -`CPU_FEATURES_COMPILED_X86_AVX` is set to 1 if the compiler was instructed to -use AVX and 0 otherwise, combining compile time and runtime knowledge. - -### Rejecting poor hardware implementations based on microarchitecture - -On x86, the first incarnation of a feature in a microarchitecture might not be -the most efficient (e.g. AVX on Sandy Bridge). We provide a function to retrieve -the underlying microarchitecture so you can decide whether to use it. - -Below, `has_fast_avx` is set to 1 if the CPU supports the AVX instruction -set—but only if it's not Sandy Bridge. - -```c -#include -#include "cpuinfo_x86.h" - -static const X86Info info = GetX86Info(); -static const X86Microarchitecture uarch = GetX86Microarchitecture(&info); -static const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB; - -// use has_fast_avx. -``` - -This feature is currently available only for x86 microarchitectures. - - -### Running sample code - -Building `cpu_features` brings a small executable to test the library. - -```shell - % ./build/list_cpu_features -arch : x86 -brand : Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz -family : 6 (0x06) -model : 45 (0x2D) -stepping : 7 (0x07) -uarch : INTEL_SNB -flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3 -``` - -```shell -% ./build/list_cpu_features --json -{"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"]} -``` - - -## What's supported - -| | x86³ | ARM | AArch64 | MIPS⁴ | POWER | -|---------|:----:|:-------:|:-------:|:------:|:-------:| -| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | -| iOS | N/A | not yet | not yet | N/A | N/A | -| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | -| MacOs | yes² | N/A | not yet | N/A | no | -| Windows | yes² | not yet | not yet | N/A | N/A | - -1. **Features revealed from Linux.** We gather data from several sources - depending on availability: - + from glibc's - [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html) - + by parsing `/proc/self/auxv` - + by parsing `/proc/cpuinfo` -2. **Features revealed from CPU.** features are retrieved by using the `cpuid` - instruction. -3. **Microarchitecture detection.** On x86 some features are not always - implemented efficiently in hardware (e.g. AVX on Sandybridge). Exposing the - microarchitecture allows the client to reject particular microarchitectures. -4. All flavors of Mips are supported, little and big endian as well as 32/64 - bits. - - -## Android NDK's drop in replacement - -[cpu_features](https://github.com/google/cpu_features) is now officially -supporting Android and offers a drop in replacement of for the NDK's [cpu-features.h](https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h) -, see [ndk_compat](ndk_compat) folder for details. - - -## License - -The cpu_features library is licensed under the terms of the Apache license. -See [LICENSE](LICENSE) for more information. - - -## Build with CMake - -Please check the [CMake build instructions](cmake/README.md). diff --git a/cpp/src/arrow/vendored/cpu_features/WORKSPACE b/cpp/src/arrow/vendored/cpu_features/WORKSPACE deleted file mode 100644 index 8ea8a8b6c59b..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/WORKSPACE +++ /dev/null @@ -1,7 +0,0 @@ -# ===== googletest ===== - -git_repository( - name = "com_google_googletest", - remote = "https://github.com/google/googletest.git", - commit = "c3f65335b79f47b05629e79a54685d899bc53b93", -) diff --git a/cpp/src/arrow/vendored/cpu_features/appveyor.yml b/cpp/src/arrow/vendored/cpu_features/appveyor.yml deleted file mode 100644 index f18635a3d195..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/appveyor.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: '{build}' -shallow_clone: true - -platform: x64 - -environment: - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - CMAKE_GENERATOR: "Visual Studio 15 2017 Win64" - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - CMAKE_GENERATOR: "Visual Studio 14 2015 Win64" - -matrix: - fast_finish: true - -before_build: - - cmake --version - - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -H. -Bcmake_build -G "%CMAKE_GENERATOR%" - -build_script: - - cmake --build cmake_build --config Debug --target ALL_BUILD - -test_script: - - cmake --build cmake_build --config Debug --target RUN_TESTS diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in b/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in deleted file mode 100644 index e0bf10e42de1..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesConfig.cmake.in +++ /dev/null @@ -1,3 +0,0 @@ -# CpuFeatures CMake configuration file - -include("${CMAKE_CURRENT_LIST_DIR}/CpuFeaturesTargets.cmake") diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in b/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in deleted file mode 100644 index 5a53ffda9265..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in +++ /dev/null @@ -1,3 +0,0 @@ -# CpuFeaturesNdkCompat CMake configuration file - -include("${CMAKE_CURRENT_LIST_DIR}/CpuFeaturesNdkCompatTargets.cmake") diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/README.md b/cpp/src/arrow/vendored/cpu_features/cmake/README.md deleted file mode 100644 index b6baeaa21c8a..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/cmake/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# CMake build instructions - -## Recommended usage : Incorporating cpu_features into a CMake project - - For API / ABI compatibility reasons, it is recommended to build and use - cpu_features in a subdirectory of your project or as an embedded dependency. - - This is similar to the recommended usage of the googletest framework - ( https://github.com/google/googletest/blob/master/googletest/README.md ) - - Build and use step-by-step - - - 1- Download cpu_features and copy it in a sub-directory in your project. - or add cpu_features as a git-submodule in your project - - 2- You can then use the cmake command `add_subdirectory()` to include - cpu_features directly and use the `cpu_features` target in your project. - - 3- Add the `cpu_features` target to the `target_link_libraries()` section of - your executable or of your library. - -## Enabling tests - - CMake default options for cpu_features is Release built type with tests - disabled. To enable testing set cmake `BUILD_TESTING` variable to `ON`, - [.travis.yml](../.travis.yml) and [appveyor.yml](../appveyor.yml) have up to - date examples. diff --git a/cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in b/cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in deleted file mode 100644 index d60a33e9ac6a..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/cmake/googletest.CMakeLists.txt.in +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 2.8.2) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master - SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) \ No newline at end of file diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h b/cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h deleted file mode 100644 index 2227160367aa..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/cpu_features_macros.h +++ /dev/null @@ -1,143 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ -#define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ - -//////////////////////////////////////////////////////////////////////////////// -// Architectures -//////////////////////////////////////////////////////////////////////////////// - -#if defined(__pnacl__) || defined(__CLR_VER) -#define CPU_FEATURES_ARCH_VM -#endif - -#if (defined(_M_IX86) || defined(__i386__)) && !defined(CPU_FEATURES_ARCH_VM) -#define CPU_FEATURES_ARCH_X86_32 -#endif - -#if (defined(_M_X64) || defined(__x86_64__)) && !defined(CPU_FEATURES_ARCH_VM) -#define CPU_FEATURES_ARCH_X86_64 -#endif - -#if defined(CPU_FEATURES_ARCH_X86_32) || defined(CPU_FEATURES_ARCH_X86_64) -#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(__mips64) -#define CPU_FEATURES_ARCH_MIPS64 -#endif - -#if defined(__mips__) && !defined(__mips64) // mips64 also declares __mips__ -#define CPU_FEATURES_ARCH_MIPS32 -#endif - -#if defined(CPU_FEATURES_ARCH_MIPS32) || defined(CPU_FEATURES_ARCH_MIPS64) -#define CPU_FEATURES_ARCH_MIPS -#endif - -#if defined(__powerpc__) -#define CPU_FEATURES_ARCH_PPC -#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 CPU_FEATURES_START_CPP_NAMESPACE \ - namespace cpu_features { \ - extern "C" { -#define CPU_FEATURES_END_CPP_NAMESPACE \ - } \ - } -#else -#define CPU_FEATURES_START_CPP_NAMESPACE -#define CPU_FEATURES_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 // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h deleted file mode 100644 index a7d22018c228..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_aarch64.h +++ /dev/null @@ -1,69 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ -#define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ - -#include "cpu_features_macros.h" - -CPU_FEATURES_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); - -CPU_FEATURES_END_CPP_NAMESPACE - -#if !defined(CPU_FEATURES_ARCH_AARCH64) -#error "Including cpuinfo_aarch64.h from a non-aarch64 target." -#endif - -#endif // CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h deleted file mode 100644 index 76a49ef58a2f..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_arm.h +++ /dev/null @@ -1,88 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ -#define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ - -#include // uint32_t -#include "cpu_features_macros.h" - -CPU_FEATURES_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); - -// Compute CpuId from ArmInfo. -uint32_t GetArmCpuId(const ArmInfo* const info); - -//////////////////////////////////////////////////////////////////////////////// -// 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); - -CPU_FEATURES_END_CPP_NAMESPACE - -#if !defined(CPU_FEATURES_ARCH_ARM) -#error "Including cpuinfo_arm.h from a non-arm target." -#endif - -#endif // CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h deleted file mode 100644 index fd65a230d729..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_mips.h +++ /dev/null @@ -1,59 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ -#define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ - -#include "cpu_features_macros.h" - -CPU_FEATURES_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/ - int r6 : 1; // True if is release 6 of the processor. - - // 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_R6, - MIPS_LAST_, -} MipsFeaturesEnum; - -int GetMipsFeaturesEnumValue(const MipsFeatures* features, - MipsFeaturesEnum value); - -const char* GetMipsFeaturesEnumName(MipsFeaturesEnum); - -CPU_FEATURES_END_CPP_NAMESPACE - -#if !defined(CPU_FEATURES_ARCH_MIPS) -#error "Including cpuinfo_mips.h from a non-mips target." -#endif - -#endif // CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h deleted file mode 100644 index 53d1cb6e42e4..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_ppc.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2018 IBM -// -// 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 CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ -#define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ - -#include "cpu_features_macros.h" -#include "internal/hwcaps.h" - -CPU_FEATURES_START_CPP_NAMESPACE - -typedef struct { - int ppc32 : 1; - int ppc64 : 1; - int ppc601 : 1; - int altivec : 1; - int fpu : 1; - int mmu : 1; - int mac_4xx : 1; - int unifiedcache : 1; - int spe : 1; - int efpsingle : 1; - int efpdouble : 1; - int no_tb : 1; - int power4 : 1; - int power5 : 1; - int power5plus : 1; - int cell : 1; - int booke : 1; - int smt : 1; - int icachesnoop : 1; - int arch205 : 1; - int pa6t : 1; - int dfp : 1; - int power6ext : 1; - int arch206 : 1; - int vsx : 1; - int pseries_perfmon_compat : 1; - int truele : 1; - int ppcle : 1; - int arch207 : 1; - int htm : 1; - int dscr : 1; - int ebb : 1; - int isel : 1; - int tar : 1; - int vcrypto : 1; - int htm_nosc : 1; - int arch300 : 1; - int ieee128 : 1; - int darn : 1; - int scv : 1; - int htm_no_suspend : 1; - - // Make sure to update PPCFeaturesEnum below if you add a field here. -} PPCFeatures; - -typedef struct { - PPCFeatures features; -} PPCInfo; - -// This function is guaranteed to be malloc, memset and memcpy free. -PPCInfo GetPPCInfo(void); - -typedef struct { - char platform[64]; // 0 terminated string - char model[64]; // 0 terminated string - char machine[64]; // 0 terminated string - char cpu[64]; // 0 terminated string - PlatformType type; -} PPCPlatformStrings; - -PPCPlatformStrings GetPPCPlatformStrings(void); - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -typedef enum { - PPC_32, /* 32 bit mode execution */ - PPC_64, /* 64 bit mode execution */ - PPC_601_INSTR, /* Old POWER ISA */ - PPC_HAS_ALTIVEC, /* SIMD Unit*/ - PPC_HAS_FPU, /* Floating Point Unit */ - PPC_HAS_MMU, /* Memory management unit */ - PPC_HAS_4xxMAC, - PPC_UNIFIED_CACHE, /* Unified instruction and data cache */ - PPC_HAS_SPE, /* Signal processing extention unit */ - PPC_HAS_EFP_SINGLE, /* SPE single precision fpu */ - PPC_HAS_EFP_DOUBLE, /* SPE double precision fpu */ - PPC_NO_TB, /* No timebase */ - PPC_POWER4, - PPC_POWER5, - PPC_POWER5_PLUS, - PPC_CELL, /* Cell broadband engine */ - PPC_BOOKE, /* Embedded ISA */ - PPC_SMT, /* Simultaneous multi-threading */ - PPC_ICACHE_SNOOP, - PPC_ARCH_2_05, /* ISA 2.05 - POWER6 */ - PPC_PA6T, /* PA Semi 6T core ISA */ - PPC_HAS_DFP, /* Decimal floating point unit */ - PPC_POWER6_EXT, - PPC_ARCH_2_06, /* ISA 2.06 - POWER7 */ - PPC_HAS_VSX, /* Vector-scalar extension */ - PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatibile performance - monitoring events */ - PPC_TRUE_LE, - PPC_PPC_LE, - PPC_ARCH_2_07, /* ISA 2.07 - POWER8 */ - PPC_HTM, /* Hardware Transactional Memory */ - PPC_DSCR, /* Data stream control register */ - PPC_EBB, /* Event base branching */ - PPC_ISEL, /* Integer select instructions */ - PPC_TAR, /* Target address register */ - PPC_VEC_CRYPTO, /* Vector cryptography instructions */ - PPC_HTM_NOSC, /* Transactions aborted when syscall made*/ - PPC_ARCH_3_00, /* ISA 3.00 - POWER9 */ - PPC_HAS_IEEE128, /* VSX IEEE Binary Float 128-bit */ - PPC_DARN, /* Deliver a random number instruction */ - PPC_SCV, /* scv syscall */ - PPC_HTM_NO_SUSPEND, /* TM w/out suspended state */ - PPC_LAST_, -} PPCFeaturesEnum; - -int GetPPCFeaturesEnumValue(const PPCFeatures* features, PPCFeaturesEnum value); - -const char* GetPPCFeaturesEnumName(PPCFeaturesEnum); - -CPU_FEATURES_END_CPP_NAMESPACE - -#if !defined(CPU_FEATURES_ARCH_PPC) -#error "Including cpuinfo_ppc.h from a non-ppc target." -#endif - -#endif // CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h b/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h deleted file mode 100644 index bb61293b3748..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/cpuinfo_x86.h +++ /dev/null @@ -1,167 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ -#define CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ - -#include "cpu_features_macros.h" - -CPU_FEATURES_START_CPP_NAMESPACE - -// See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features. -// The field names are based on the short name provided in the wikipedia tables. -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; - - int smx : 1; - int sgx : 1; - int cx16 : 1; // aka. CMPXCHG16B - int sha : 1; - int popcnt : 1; - int movbe : 1; - int rdrnd : 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, // CANNON 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_SMX, - X86_SGX, - X86_CX16, - X86_SHA, - X86_POPCNT, - X86_MOVBE, - X86_RDRND, - X86_LAST_, -} X86FeaturesEnum; - -int GetX86FeaturesEnumValue(const X86Features* features, X86FeaturesEnum value); - -const char* GetX86FeaturesEnumName(X86FeaturesEnum); - -const char* GetX86MicroarchitectureName(X86Microarchitecture); - -CPU_FEATURES_END_CPP_NAMESPACE - -#if !defined(CPU_FEATURES_ARCH_X86) -#error "Including cpuinfo_x86.h from a non-x86 target." -#endif - -#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h b/cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h deleted file mode 100644 index bc965cb6e313..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/bit_utils.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ - -#include -#include -#include -#include "cpu_features_macros.h" - -CPU_FEATURES_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 + 1ULL; - const uint64_t mask = (1ULL << bits) - 1ULL; - assert(msb >= lsb); - return (reg >> lsb) & mask; -} - -CPU_FEATURES_END_CPP_NAMESPACE - -#endif // CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h b/cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h deleted file mode 100644 index 9dcee0de95b4..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/cpuid_x86.h +++ /dev/null @@ -1,37 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ - -#include - -#include "cpu_features_macros.h" - -CPU_FEATURES_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); - -CPU_FEATURES_END_CPP_NAMESPACE - -#endif // CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h b/cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h deleted file mode 100644 index 3378881358eb..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/filesystem.h +++ /dev/null @@ -1,38 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ - -#include -#include -#include "cpu_features_macros.h" - -CPU_FEATURES_START_CPP_NAMESPACE - -// Same as linux "open(filename, O_RDONLY)", retries automatically on EINTR. -int CpuFeatures_OpenFile(const char* filename); - -// Same as linux "read(file_descriptor, buffer, buffer_size)", retries -// automatically on EINTR. -int CpuFeatures_ReadFile(int file_descriptor, void* buffer, size_t buffer_size); - -// Same as linux "close(file_descriptor)". -void CpuFeatures_CloseFile(int file_descriptor); - -CPU_FEATURES_END_CPP_NAMESPACE - -#endif // CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h b/cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h deleted file mode 100644 index cb38e294aa4e..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/hwcaps.h +++ /dev/null @@ -1,124 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ - -#include -#include "cpu_features_macros.h" - -CPU_FEATURES_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_R6 (1UL << 0) -#define MIPS_HWCAP_MSA (1UL << 1) -#define MIPS_HWCAP_CRC32 (1UL << 2) - -// http://elixir.free-electrons.com/linux/latest/source/arch/powerpc/include/uapi/asm/cputable.h -#ifndef _UAPI__ASM_POWERPC_CPUTABLE_H -/* in AT_HWCAP */ -#define PPC_FEATURE_32 0x80000000 -#define PPC_FEATURE_64 0x40000000 -#define PPC_FEATURE_601_INSTR 0x20000000 -#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 -#define PPC_FEATURE_HAS_FPU 0x08000000 -#define PPC_FEATURE_HAS_MMU 0x04000000 -#define PPC_FEATURE_HAS_4xxMAC 0x02000000 -#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 -#define PPC_FEATURE_HAS_SPE 0x00800000 -#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 -#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 -#define PPC_FEATURE_NO_TB 0x00100000 -#define PPC_FEATURE_POWER4 0x00080000 -#define PPC_FEATURE_POWER5 0x00040000 -#define PPC_FEATURE_POWER5_PLUS 0x00020000 -#define PPC_FEATURE_CELL 0x00010000 -#define PPC_FEATURE_BOOKE 0x00008000 -#define PPC_FEATURE_SMT 0x00004000 -#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 -#define PPC_FEATURE_ARCH_2_05 0x00001000 -#define PPC_FEATURE_PA6T 0x00000800 -#define PPC_FEATURE_HAS_DFP 0x00000400 -#define PPC_FEATURE_POWER6_EXT 0x00000200 -#define PPC_FEATURE_ARCH_2_06 0x00000100 -#define PPC_FEATURE_HAS_VSX 0x00000080 - -#define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040 - -/* Reserved - do not use 0x00000004 */ -#define PPC_FEATURE_TRUE_LE 0x00000002 -#define PPC_FEATURE_PPC_LE 0x00000001 - -/* in AT_HWCAP2 */ -#define PPC_FEATURE2_ARCH_2_07 0x80000000 -#define PPC_FEATURE2_HTM 0x40000000 -#define PPC_FEATURE2_DSCR 0x20000000 -#define PPC_FEATURE2_EBB 0x10000000 -#define PPC_FEATURE2_ISEL 0x08000000 -#define PPC_FEATURE2_TAR 0x04000000 -#define PPC_FEATURE2_VEC_CRYPTO 0x02000000 -#define PPC_FEATURE2_HTM_NOSC 0x01000000 -#define PPC_FEATURE2_ARCH_3_00 0x00800000 -#define PPC_FEATURE2_HAS_IEEE128 0x00400000 -#define PPC_FEATURE2_DARN 0x00200000 -#define PPC_FEATURE2_SCV 0x00100000 -#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 -#endif - -typedef struct { - unsigned long hwcaps; - unsigned long hwcaps2; -} HardwareCapabilities; - -HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void); - -typedef struct { - char platform[64]; // 0 terminated string - char base_platform[64]; // 0 terminated string -} PlatformType; - -PlatformType CpuFeatures_GetPlatformType(void); - -CPU_FEATURES_END_CPP_NAMESPACE - -#endif // CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h b/cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h deleted file mode 100644 index c540f6b23e1e..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/stack_line_reader.h +++ /dev/null @@ -1,49 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ - -#include - -#include "cpu_features_macros.h" -#include "internal/string_view.h" - -CPU_FEATURES_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); - -CPU_FEATURES_END_CPP_NAMESPACE - -#endif // CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h b/cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h deleted file mode 100644 index aa3779c44d01..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/string_view.h +++ /dev/null @@ -1,108 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ - -#include -#include -#include -#include "cpu_features_macros.h" - -CPU_FEATURES_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 CpuFeatures_StringView_IndexOfChar(const StringView view, char c); - -// Returns the index of the first occurrence of sub_view in view or -1 if not -// found. -int CpuFeatures_StringView_IndexOf(const StringView view, - const StringView sub_view); - -// Returns whether a is equal to b (same content). -bool CpuFeatures_StringView_IsEquals(const StringView a, const StringView b); - -// Returns whether a starts with b. -bool CpuFeatures_StringView_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 CpuFeatures_StringView_PopFront(const StringView str_view, - size_t count); - -// Removes count characters from the end of view or kEmptyStringView if count if -// greater than view.size. -StringView CpuFeatures_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 CpuFeatures_StringView_KeepFront(const StringView str_view, - size_t count); - -// Retrieves the first character of view. If view is empty the behavior is -// undefined. -char CpuFeatures_StringView_Front(const StringView view); - -// Retrieves the last character of view. If view is empty the behavior is -// undefined. -char CpuFeatures_StringView_Back(const StringView view); - -// Removes leading and tailing space characters. -StringView CpuFeatures_StringView_TrimWhitespace(StringView view); - -// Convert StringView to positive integer. e.g. "42", "0x2a". -// Returns -1 on error. -int CpuFeatures_StringView_ParsePositiveNumber(const StringView view); - -// Copies src StringView to dst buffer. -void CpuFeatures_StringView_CopyString(const StringView src, char* dst, - size_t dst_size); - -// Checks if line contains the specified whitespace separated word. -bool CpuFeatures_StringView_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 CpuFeatures_StringView_GetAttributeKeyValue(const StringView line, - StringView* key, - StringView* value); - -CPU_FEATURES_END_CPP_NAMESPACE - -#endif // CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h b/cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h deleted file mode 100644 index 77661d4cb399..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/include/internal/unix_features_aggregator.h +++ /dev/null @@ -1,60 +0,0 @@ -// 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 CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_ -#define CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_ - -#include -#include -#include "cpu_features_macros.h" -#include "internal/hwcaps.h" -#include "internal/string_view.h" - -CPU_FEATURES_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 CpuFeatures_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 CpuFeatures_OverrideFromHwCaps(const size_t configs_size, - const CapabilityConfig* configs, - const HardwareCapabilities hwcaps, - void* const features); - -CPU_FEATURES_END_CPP_NAMESPACE -#endif // CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt b/cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt deleted file mode 100644 index d95e523742b3..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/ndk_compat/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ - -# -# library : NDK compat -# -find_package(Threads REQUIRED) -set (NDK_COMPAT_HDRS cpu-features.h) -set (NDK_COMPAT_SRCS - cpu-features.c - $ - $ -) -# Note that following `add_cpu_features_headers_and_sources` will use -# NDK_COMPAT_SRCS in lieu of NDK_COMPAT_HDRS because we don't want cpu_features -# headers to be installed alongside ndk_compat. -add_cpu_features_headers_and_sources(NDK_COMPAT_SRCS NDK_COMPAT_SRCS) -add_library(ndk_compat ${NDK_COMPAT_HDRS} ${NDK_COMPAT_SRCS}) -setup_include_and_definitions(ndk_compat) -target_link_libraries(ndk_compat PUBLIC ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) -set_target_properties(ndk_compat PROPERTIES PUBLIC_HEADER "${NDK_COMPAT_HDRS}") - -include(GNUInstallDirs) -install(TARGETS ndk_compat - EXPORT CpuFeaturesNdkCompatTargets - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ndk_compat - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) -install(EXPORT CpuFeaturesNdkCompatTargets - NAMESPACE CpuFeatures:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeaturesNdkCompat - COMPONENT Devel -) -include(CMakePackageConfigHelpers) -configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/CpuFeaturesNdkCompatConfig.cmake.in - "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfig.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeaturesNdkCompat" - NO_SET_AND_CHECK_MACRO - NO_CHECK_REQUIRED_COMPONENTS_MACRO -) -write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfigVersion.cmake" - COMPATIBILITY SameMajorVersion -) -install( - FILES - "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfig.cmake" - "${PROJECT_BINARY_DIR}/CpuFeaturesNdkCompatConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeaturesNdkCompat" - COMPONENT Devel -) - -# -# program : NDK compat test program -# -if(ENABLE_TESTING) - add_executable(ndk-compat-test ndk-compat-test.c) - target_link_libraries(ndk-compat-test PRIVATE ndk_compat) -endif() diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md b/cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md deleted file mode 100644 index 38c83937f93d..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/ndk_compat/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Provides a header compatible with [android's NDK cpu-features.h](https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h). - -It is intended to be a drop in replacement for this header and help users -transition from the NDK to [Google's cpu_features library](https://github.com/google/cpu_features). diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c b/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c deleted file mode 100644 index 715dc4f7d659..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "cpu-features.h" -#include "cpu_features_macros.h" -#include "internal/filesystem.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" - -#include - -#if defined(CPU_FEATURES_ARCH_ARM) -#include "cpuinfo_arm.h" -#elif defined(CPU_FEATURES_ARCH_X86) -#include "cpuinfo_x86.h" -#elif defined(CPU_FEATURES_ARCH_MIPS) -#include "cpuinfo_mips.h" -#elif defined(CPU_FEATURES_ARCH_AARCH64) -#include "cpuinfo_aarch64.h" -#endif - -static pthread_once_t g_once; -static int g_inited; -static uint64_t g_cpuFeatures; -static int g_cpuCount; - -#ifdef CPU_FEATURES_ARCH_ARM -static uint32_t g_cpuIdArm; -#endif - -static void set_cpu_mask_bit(uint32_t index, uint32_t* cpu_mask) { - *cpu_mask |= 1UL << index; -} - -// Examples of valid inputs: "31", "4-31" -static void parse_cpu_mask(const StringView text, uint32_t* cpu_mask) { - int separator_index = CpuFeatures_StringView_IndexOfChar(text, '-'); - if (separator_index < 0) { // A single cpu index - int cpu_index = CpuFeatures_StringView_ParsePositiveNumber(text); - if (cpu_index < 0) return; - set_cpu_mask_bit(cpu_index, cpu_mask); - } else { - int cpu_index_a = CpuFeatures_StringView_ParsePositiveNumber( - CpuFeatures_StringView_KeepFront(text, separator_index)); - int cpu_index_b = CpuFeatures_StringView_ParsePositiveNumber( - CpuFeatures_StringView_PopFront(text, separator_index + 1)); - int i; - if (cpu_index_a < 0 || cpu_index_b < 0) return; - for (i = cpu_index_a; i <= cpu_index_b; ++i) { - if (i < 32) { - set_cpu_mask_bit(i, cpu_mask); - } - } - } -} - -// Format specification from -// https://www.kernel.org/doc/Documentation/cputopology.txt -// Examples of valid inputs: "31", "2,4-31,32-63", "0-1,3" -static void parse_cpu_mask_line(const LineResult result, uint32_t* cpu_mask) { - if (!result.full_line || result.eof) return; - StringView line = result.line; - for (; line.size > 0;) { - int next_entry_index = CpuFeatures_StringView_IndexOfChar(line, ','); - if (next_entry_index < 0) { - parse_cpu_mask(line, cpu_mask); - break; - } - StringView entry = CpuFeatures_StringView_KeepFront(line, next_entry_index); - parse_cpu_mask(entry, cpu_mask); - line = CpuFeatures_StringView_PopFront(line, next_entry_index + 1); - } -} - -static void update_cpu_mask_from_file(const char* filename, - uint32_t* cpu_mask) { - const int fd = CpuFeatures_OpenFile(filename); - if (fd >= 0) { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - parse_cpu_mask_line(StackLineReader_NextLine(&reader), cpu_mask); - CpuFeatures_CloseFile(fd); - } -} - -static int get_cpu_count(void) { - uint32_t cpu_mask = 0; - update_cpu_mask_from_file("/sys/devices/system/cpu/present", &cpu_mask); - update_cpu_mask_from_file("/sys/devices/system/cpu/possible", &cpu_mask); - return __builtin_popcount(cpu_mask); -} - -static void android_cpuInit(void) { - g_cpuFeatures = 0; - g_cpuCount = 1; - g_inited = 1; - - g_cpuCount = get_cpu_count(); - if (g_cpuCount == 0) { - g_cpuCount = 1; - } -#if defined(CPU_FEATURES_ARCH_ARM) - ArmInfo info = GetArmInfo(); - if (info.architecture == 7) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7; - if (info.features.vfpv3) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3; - if (info.features.neon) { - g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON; - g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFP_D32; - } - if (info.features.vfpv3d16) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFP_FP16; - if (info.features.idiva) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM; - if (info.features.idivt) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2; - if (info.features.iwmmxt) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_iWMMXt; - if (info.features.aes) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_AES; - if (info.features.pmull) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_PMULL; - if (info.features.sha1) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA1; - if (info.features.sha2) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA2; - if (info.features.crc32) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_CRC32; - if (info.architecture >= 6) - g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX; - if (info.features.vfpv) g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv2; - if (info.features.vfpv4) { - g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFP_FMA; - g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON_FMA; - } - g_cpuIdArm = GetArmCpuId(&info); -#elif defined(CPU_FEATURES_ARCH_X86) - X86Info info = GetX86Info(); - if (info.features.ssse3) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3; - if (info.features.popcnt) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT; - if (info.features.movbe) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE; - if (info.features.sse4_1) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_1; - if (info.features.sse4_2) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_2; - if (info.features.aes) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AES_NI; - if (info.features.avx) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX; - if (info.features.rdrnd) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_RDRAND; - if (info.features.avx2) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX2; - if (info.features.sha) g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SHA_NI; -#elif defined(CPU_FEATURES_ARCH_MIPS) - MipsInfo info = GetMipsInfo(); - if (info.features.r6) g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_R6; - if (info.features.msa) g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_MSA; -#elif defined(CPU_FEATURES_ARCH_AARCH64) - Aarch64Info info = GetAarch64Info(); - if (info.features.fp) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_FP; - if (info.features.asimd) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_ASIMD; - if (info.features.aes) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_AES; - if (info.features.pmull) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_PMULL; - if (info.features.sha1) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA1; - if (info.features.sha2) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA2; - if (info.features.crc32) g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_CRC32; -#endif -} - -AndroidCpuFamily android_getCpuFamily(void) { -#if defined(CPU_FEATURES_ARCH_ARM) - return ANDROID_CPU_FAMILY_ARM; -#elif defined(CPU_FEATURES_ARCH_X86_32) - return ANDROID_CPU_FAMILY_X86; -#elif defined(CPU_FEATURES_ARCH_MIPS64) - return ANDROID_CPU_FAMILY_MIPS64; -#elif defined(CPU_FEATURES_ARCH_MIPS32) - return ANDROID_CPU_FAMILY_MIPS; -#elif defined(CPU_FEATURES_ARCH_AARCH64) - return ANDROID_CPU_FAMILY_ARM64; -#elif defined(CPU_FEATURES_ARCH_X86_64) - return ANDROID_CPU_FAMILY_X86_64; -#else - return ANDROID_CPU_FAMILY_UNKNOWN; -#endif -} - -uint64_t android_getCpuFeatures(void) { - pthread_once(&g_once, android_cpuInit); - return g_cpuFeatures; -} - -int android_getCpuCount(void) { - pthread_once(&g_once, android_cpuInit); - return g_cpuCount; -} - -static void android_cpuInitDummy(void) { g_inited = 1; } - -int android_setCpu(int cpu_count, uint64_t cpu_features) { - /* Fail if the library was already initialized. */ - if (g_inited) return 0; - g_cpuCount = (cpu_count <= 0 ? 1 : cpu_count); - g_cpuFeatures = cpu_features; - pthread_once(&g_once, android_cpuInitDummy); - return 1; -} - -#ifdef CPU_FEATURES_ARCH_ARM - -uint32_t android_getCpuIdArm(void) { - pthread_once(&g_once, android_cpuInit); - return g_cpuIdArm; -} - -int android_setCpuArm(int cpu_count, uint64_t cpu_features, uint32_t cpu_id) { - if (!android_setCpu(cpu_count, cpu_features)) return 0; - g_cpuIdArm = cpu_id; - return 1; -} - -#endif // CPU_FEATURES_ARCH_ARM diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h b/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h deleted file mode 100644 index 51bea5387962..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/ndk_compat/cpu-features.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifndef GOOGLE_CPU_FEATURES_H -#define GOOGLE_CPU_FEATURES_H -#include -#include - -__BEGIN_DECLS - -/* A list of valid values returned by android_getCpuFamily(). - * They describe the CPU Architecture of the current process. - */ -typedef enum { - ANDROID_CPU_FAMILY_UNKNOWN = 0, - ANDROID_CPU_FAMILY_ARM, - ANDROID_CPU_FAMILY_X86, - ANDROID_CPU_FAMILY_MIPS, - ANDROID_CPU_FAMILY_ARM64, - ANDROID_CPU_FAMILY_X86_64, - ANDROID_CPU_FAMILY_MIPS64, - ANDROID_CPU_FAMILY_MAX /* do not remove */ -} AndroidCpuFamily; - -/* Return the CPU family of the current process. - * - * Note that this matches the bitness of the current process. I.e. when - * running a 32-bit binary on a 64-bit capable CPU, this will return the - * 32-bit CPU family value. - */ -extern AndroidCpuFamily android_getCpuFamily(void); - -/* Return a bitmap describing a set of optional CPU features that are - * supported by the current device's CPU. The exact bit-flags returned - * depend on the value returned by android_getCpuFamily(). See the - * documentation for the ANDROID_CPU_*_FEATURE_* flags below for details. - */ -extern uint64_t android_getCpuFeatures(void); - -/* The list of feature flags for ANDROID_CPU_FAMILY_ARM that can be - * recognized by the library (see note below for 64-bit ARM). Value details - * are: - * - * VFPv2: - * CPU supports the VFPv2 instruction set. Many, but not all, ARMv6 CPUs - * support these instructions. VFPv2 is a subset of VFPv3 so this will - * be set whenever VFPv3 is set too. - * - * ARMv7: - * CPU supports the ARMv7-A basic instruction set. - * This feature is mandated by the 'armeabi-v7a' ABI. - * - * VFPv3: - * CPU supports the VFPv3-D16 instruction set, providing hardware FPU - * support for single and double precision floating point registers. - * Note that only 16 FPU registers are available by default, unless - * the D32 bit is set too. This feature is also mandated by the - * 'armeabi-v7a' ABI. - * - * VFP_D32: - * CPU VFP optional extension that provides 32 FPU registers, - * instead of 16. Note that ARM mandates this feature is the 'NEON' - * feature is implemented by the CPU. - * - * NEON: - * CPU FPU supports "ARM Advanced SIMD" instructions, also known as - * NEON. Note that this mandates the VFP_D32 feature as well, per the - * ARM Architecture specification. - * - * VFP_FP16: - * Half-width floating precision VFP extension. If set, the CPU - * supports instructions to perform floating-point operations on - * 16-bit registers. This is part of the VFPv4 specification, but - * not mandated by any Android ABI. - * - * VFP_FMA: - * Fused multiply-accumulate VFP instructions extension. Also part of - * the VFPv4 specification, but not mandated by any Android ABI. - * - * NEON_FMA: - * Fused multiply-accumulate NEON instructions extension. Optional - * extension from the VFPv4 specification, but not mandated by any - * Android ABI. - * - * IDIV_ARM: - * Integer division available in ARM mode. Only available - * on recent CPUs (e.g. Cortex-A15). - * - * IDIV_THUMB2: - * Integer division available in Thumb-2 mode. Only available - * on recent CPUs (e.g. Cortex-A15). - * - * iWMMXt: - * Optional extension that adds MMX registers and operations to an - * ARM CPU. This is only available on a few XScale-based CPU designs - * sold by Marvell. Pretty rare in practice. - * - * AES: - * CPU supports AES instructions. These instructions are only - * available for 32-bit applications running on ARMv8 CPU. - * - * CRC32: - * CPU supports CRC32 instructions. These instructions are only - * available for 32-bit applications running on ARMv8 CPU. - * - * SHA2: - * CPU supports SHA2 instructions. These instructions are only - * available for 32-bit applications running on ARMv8 CPU. - * - * SHA1: - * CPU supports SHA1 instructions. These instructions are only - * available for 32-bit applications running on ARMv8 CPU. - * - * PMULL: - * CPU supports 64-bit PMULL and PMULL2 instructions. These - * instructions are only available for 32-bit applications - * running on ARMv8 CPU. - * - * If you want to tell the compiler to generate code that targets one of - * the feature set above, you should probably use one of the following - * flags (for more details, see technical note at the end of this file): - * - * -mfpu=vfp - * -mfpu=vfpv2 - * These are equivalent and tell GCC to use VFPv2 instructions for - * floating-point operations. Use this if you want your code to - * run on *some* ARMv6 devices, and any ARMv7-A device supported - * by Android. - * - * Generated code requires VFPv2 feature. - * - * -mfpu=vfpv3-d16 - * Tell GCC to use VFPv3 instructions (using only 16 FPU registers). - * This should be generic code that runs on any CPU that supports the - * 'armeabi-v7a' Android ABI. Note that no ARMv6 CPU supports this. - * - * Generated code requires VFPv3 feature. - * - * -mfpu=vfpv3 - * Tell GCC to use VFPv3 instructions with 32 FPU registers. - * Generated code requires VFPv3|VFP_D32 features. - * - * -mfpu=neon - * Tell GCC to use VFPv3 instructions with 32 FPU registers, and - * also support NEON intrinsics (see ). - * Generated code requires VFPv3|VFP_D32|NEON features. - * - * -mfpu=vfpv4-d16 - * Generated code requires VFPv3|VFP_FP16|VFP_FMA features. - * - * -mfpu=vfpv4 - * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32 features. - * - * -mfpu=neon-vfpv4 - * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|NEON|NEON_FMA - * features. - * - * -mcpu=cortex-a7 - * -mcpu=cortex-a15 - * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32| - * NEON|NEON_FMA|IDIV_ARM|IDIV_THUMB2 - * This flag implies -mfpu=neon-vfpv4. - * - * -mcpu=iwmmxt - * Allows the use of iWMMXt instrinsics with GCC. - * - * IMPORTANT NOTE: These flags should only be tested when - * android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a - * 32-bit process. - * - * When running a 64-bit ARM process on an ARMv8 CPU, - * android_getCpuFeatures() will return a different set of bitflags - */ -enum { - ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0), - ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1), - ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2), - ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3), - ANDROID_CPU_ARM_FEATURE_VFPv2 = (1 << 4), - ANDROID_CPU_ARM_FEATURE_VFP_D32 = (1 << 5), - ANDROID_CPU_ARM_FEATURE_VFP_FP16 = (1 << 6), - ANDROID_CPU_ARM_FEATURE_VFP_FMA = (1 << 7), - ANDROID_CPU_ARM_FEATURE_NEON_FMA = (1 << 8), - ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9), - ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10), - ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11), - ANDROID_CPU_ARM_FEATURE_AES = (1 << 12), - ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13), - ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14), - ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15), - ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16), -}; - -/* The bit flags corresponding to the output of android_getCpuFeatures() - * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM64. Value details - * are: - * - * FP: - * CPU has Floating-point unit. - * - * ASIMD: - * CPU has Advanced SIMD unit. - * - * AES: - * CPU supports AES instructions. - * - * CRC32: - * CPU supports CRC32 instructions. - * - * SHA2: - * CPU supports SHA2 instructions. - * - * SHA1: - * CPU supports SHA1 instructions. - * - * PMULL: - * CPU supports 64-bit PMULL and PMULL2 instructions. - */ -enum { - ANDROID_CPU_ARM64_FEATURE_FP = (1 << 0), - ANDROID_CPU_ARM64_FEATURE_ASIMD = (1 << 1), - ANDROID_CPU_ARM64_FEATURE_AES = (1 << 2), - ANDROID_CPU_ARM64_FEATURE_PMULL = (1 << 3), - ANDROID_CPU_ARM64_FEATURE_SHA1 = (1 << 4), - ANDROID_CPU_ARM64_FEATURE_SHA2 = (1 << 5), - ANDROID_CPU_ARM64_FEATURE_CRC32 = (1 << 6), -}; - -/* The bit flags corresponding to the output of android_getCpuFeatures() - * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_X86 or - * ANDROID_CPU_FAMILY_X86_64. - */ -enum { - ANDROID_CPU_X86_FEATURE_SSSE3 = (1 << 0), - ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1), - ANDROID_CPU_X86_FEATURE_MOVBE = (1 << 2), - ANDROID_CPU_X86_FEATURE_SSE4_1 = (1 << 3), - ANDROID_CPU_X86_FEATURE_SSE4_2 = (1 << 4), - ANDROID_CPU_X86_FEATURE_AES_NI = (1 << 5), - ANDROID_CPU_X86_FEATURE_AVX = (1 << 6), - ANDROID_CPU_X86_FEATURE_RDRAND = (1 << 7), - ANDROID_CPU_X86_FEATURE_AVX2 = (1 << 8), - ANDROID_CPU_X86_FEATURE_SHA_NI = (1 << 9), -}; - -/* The bit flags corresponding to the output of android_getCpuFeatures() - * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_MIPS - * or ANDROID_CPU_FAMILY_MIPS64. Values are: - * - * R6: - * CPU executes MIPS Release 6 instructions natively, and - * supports obsoleted R1..R5 instructions only via kernel traps. - * - * MSA: - * CPU supports Mips SIMD Architecture instructions. - */ -enum { - ANDROID_CPU_MIPS_FEATURE_R6 = (1 << 0), - ANDROID_CPU_MIPS_FEATURE_MSA = (1 << 1), -}; - -/* Return the number of CPU cores detected on this device. - * Please note the current implementation supports up to 32 cpus. - */ -extern int android_getCpuCount(void); - -/* The following is used to force the CPU count and features - * mask in sandboxed processes. Under 4.1 and higher, these processes - * cannot access /proc, which is the only way to get information from - * the kernel about the current hardware (at least on ARM). - * - * It _must_ be called only once, and before any android_getCpuXXX - * function, any other case will fail. - * - * This function return 1 on success, and 0 on failure. - */ -extern int android_setCpu(int cpu_count, uint64_t cpu_features); - -#ifdef __arm__ - -/* Retrieve the ARM 32-bit CPUID value from the kernel. - * Note that this cannot work on sandboxed processes under 4.1 and - * higher, unless you called android_setCpuArm() before. - */ -extern uint32_t android_getCpuIdArm(void); - -/* An ARM-specific variant of android_setCpu() that also allows you - * to set the ARM CPUID field. - */ -extern int android_setCpuArm(int cpu_count, uint64_t cpu_features, - uint32_t cpu_id); - -#endif - -__END_DECLS -#endif /* GOOGLE_CPU_FEATURES_H */ diff --git a/cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c b/cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c deleted file mode 100644 index 782dbbf96375..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/ndk_compat/ndk-compat-test.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include "cpu-features.h" - -int main() { - printf("android_getCpuFamily()=%d\n", android_getCpuFamily()); - printf("android_getCpuFeatures()=0x%08llx\n", android_getCpuFeatures()); - printf("android_getCpuCount()=%d\n", android_getCpuCount()); -#ifdef __arm__ - printf("android_getCpuIdArm()=0x%04x\n", android_getCpuIdArm()); -#endif //__arm__ -} diff --git a/cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh b/cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh deleted file mode 100644 index fd88d605e29e..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/scripts/run_integration.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env bash - -readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) -readonly PROJECT_FOLDER="${SCRIPT_FOLDER}/.." -readonly ARCHIVE_FOLDER=~/cpu_features_archives -readonly QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu -readonly DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" - -function extract() { - case $1 in - *.tar.bz2) tar xjf "$1" ;; - *.tar.xz) tar xJf "$1" ;; - *.tar.gz) tar xzf "$1" ;; - *) - echo "don't know how to extract '$1'..." - exit 1 - esac -} - -function unpackifnotexists() { - mkdir -p "${ARCHIVE_FOLDER}" - cd "${ARCHIVE_FOLDER}" || exit - local URL=$1 - local RELATIVE_FOLDER=$2 - local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}" - if [[ ! -d "${DESTINATION}" ]] ; then - local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///') - test -f "${ARCHIVE_NAME}" || wget -q "${URL}" - extract "${ARCHIVE_NAME}" - rm -f "${ARCHIVE_NAME}" - fi -} - -function installqemuifneeded() { - local VERSION=${QEMU_VERSION:=2.11.1} - local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel mips64 mips64el} - local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} - - if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then - echo "qemu ${VERSION} up to date!" - return 0 - fi - - echo "VERSION: ${VERSION}" - echo "TARGETS: ${TARGETS}" - - rm -rf ${QEMU_INSTALL} - - # Checking for a tarball before downloading makes testing easier :-) - local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" - local QEMU_FOLDER="qemu-${VERSION}" - unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} - cd ${QEMU_FOLDER} || exit - - ./configure \ - --prefix="${QEMU_INSTALL}" \ - --target-list="${TARGETS}" \ - --disable-docs \ - --disable-sdl \ - --disable-gtk \ - --disable-gnutls \ - --disable-gcrypt \ - --disable-nettle \ - --disable-curses \ - --static - - make -j4 - make install - - echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build -} - -function assert_defined(){ - local VALUE=${1} - : "${VALUE?"${1} needs to be defined"}" -} - -function integrate() { - cd "${PROJECT_FOLDER}" - case "${OS}" in - "Windows_NT") CMAKE_BUILD_ARGS="--config Debug --target ALL_BUILD" - CMAKE_TEST_FILES="${BUILD_DIR}/test/Debug/*_test.exe" - DEMO=${BUILD_DIR}/Debug/list_cpu_features.exe - ;; - *) CMAKE_BUILD_ARGS="--target all" - CMAKE_TEST_FILES="${BUILD_DIR}/test/*_test" - DEMO=${BUILD_DIR}/list_cpu_features - ;; - esac - - # Generating CMake configuration - cmake -H. -B"${BUILD_DIR}" ${DEFAULT_CMAKE_ARGS} "${CMAKE_ADDITIONAL_ARGS[@]}" -G"${CMAKE_GENERATOR:-Unix Makefiles}" - - # Building - cmake --build "${BUILD_DIR}" ${CMAKE_BUILD_ARGS} - - # Running tests if needed - if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then - return - fi - RUN_CMD="" - if [[ -n "${QEMU_ARCH}" ]]; then - installqemuifneeded - RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[@]}" - fi - for test_binary in ${CMAKE_TEST_FILES}; do - ${RUN_CMD} ${test_binary} - done - ${RUN_CMD} ${DEMO} -} - -function expand_linaro_config() { - assert_defined TARGET - local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 - - local GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz - local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}" - unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" - - local SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz - local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} - unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" - - local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER} - local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} - - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) - - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSROOT=${SYSROOT_FOLDER}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=${GCC_FOLDER}/bin/${TARGET}-gcc) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=${GCC_FOLDER}/bin/${TARGET}-g++) - - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY) - - QEMU_ARGS+=(-L ${SYSROOT_FOLDER}) - QEMU_ARGS+=(-E LD_LIBRARY_PATH=/lib) -} - -function expand_codescape_config() { - assert_defined TARGET - local DATE=2017.10-08 - local CODESCAPE_URL=https://codescape.mips.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz - local GCC_URL=${CODESCAPE_URL} - local GCC_RELATIVE_FOLDER="mips-mti-linux-gnu/${DATE}" - unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" - - local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} - local MIPS_FLAGS="" - local LIBC_FOLDER_SUFFIX="" - local FLAVOUR="" - case "${TARGET}" in - "mips32") MIPS_FLAGS="-EB -mabi=32"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;; - "mips32el") MIPS_FLAGS="-EL -mabi=32"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;; - "mips64") MIPS_FLAGS="-EB -mabi=64"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;; - "mips64el") MIPS_FLAGS="-EL -mabi=64"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;; - *) echo 'unknown mips platform'; exit 1;; - esac - - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH=${GCC_FOLDER}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=mips-mti-linux-gnu-gcc) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=mips-mti-linux-gnu-g++) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER_ARG1="${MIPS_FLAGS}") - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER_ARG1="${MIPS_FLAGS}") - - local SYSROOT_FOLDER=${GCC_FOLDER}/sysroot/${FLAVOUR} - - # Keeping only the sysroot of interest to save on travis cache. - if [[ "${CONTINUOUS_INTEGRATION}" = "true" ]]; then - for folder in ${GCC_FOLDER}/sysroot/*; do - if [[ "${folder}" != "${SYSROOT_FOLDER}" ]]; then - rm -rf ${folder} - fi - done - fi - - local LIBC_FOLDER=${GCC_FOLDER}/mips-mti-linux-gnu/lib/${FLAVOUR}/${LIBC_FOLDER_SUFFIX} - QEMU_ARGS+=(-L ${SYSROOT_FOLDER}) - QEMU_ARGS+=(-E LD_PRELOAD=${LIBC_FOLDER}/libstdc++.so.6:${LIBC_FOLDER}/libgcc_s.so.1) -} - -function expand_environment_and_integrate() { - assert_defined PROJECT_FOLDER - assert_defined TARGET - - BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" - mkdir -p "${BUILD_DIR}" - - declare -a CONFIG_NAMES=() - declare -a QEMU_ARGS=() - declare -a CMAKE_ADDITIONAL_ARGS=() - - case ${TOOLCHAIN} in - LINARO) expand_linaro_config ;; - CODESCAPE) expand_codescape_config ;; - NATIVE) QEMU_ARCH="" ;; - *) echo "Unknown toolchain '${TOOLCHAIN}'..."; exit 1;; - esac - integrate -} - -if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then - QEMU_ARCHES=${QEMU_ARCH} - expand_environment_and_integrate -fi diff --git a/cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh b/cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh deleted file mode 100644 index d1c61b02e6ff..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/scripts/test_integration.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env bash - -source "$(dirname -- "$0")"/run_integration.sh - -# Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems -function set_aarch64-linux-gnu() { - TOOLCHAIN=LINARO - TARGET=aarch64-linux-gnu - QEMU_ARCH=aarch64 -} - -# Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems -function set_arm-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabihf - QEMU_ARCH=arm -} - -# Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems -function set_armv8l-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=armv8l-linux-gnueabihf - QEMU_ARCH=arm -} - -# Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems -function set_arm-linux-gnueabi() { - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabi - QEMU_ARCH=arm -} - -# Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems -function set_aarch64_be-linux-gnu() { - TOOLCHAIN=LINARO - TARGET=aarch64_be-linux-gnu - QEMU_ARCH=DISABLED -} - -# Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems -function set_armeb-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabihf - QEMU_ARCH=DISABLED -} - -# Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems -function set_armeb-linux-gnueabi() { - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabi - QEMU_ARCH=DISABLED -} - -function set_mips32() { - TOOLCHAIN=CODESCAPE - TARGET=mips32 - QEMU_ARCH=mips -} - -function set_mips32el() { - TOOLCHAIN=CODESCAPE - TARGET=mips32el - QEMU_ARCH=mipsel -} - -function set_mips64() { - TOOLCHAIN=CODESCAPE - TARGET=mips64 - QEMU_ARCH=mips64 -} - -function set_mips64el() { - TOOLCHAIN=CODESCAPE - TARGET=mips64el - QEMU_ARCH=mips64el -} - -function set_native() { - TOOLCHAIN=NATIVE - TARGET=native - QEMU_ARCH="" -} - -ENVIRONMENTS=" - set_aarch64-linux-gnu - set_arm-linux-gnueabihf - set_armv8l-linux-gnueabihf - set_arm-linux-gnueabi - set_aarch64_be-linux-gnu - set_armeb-linux-gnueabihf - set_armeb-linux-gnueabi - set_mips32 - set_mips32el - set_mips64 - set_mips64el - set_native -" - -set -e - -CMAKE_GENERATOR="Ninja" - -for SET_ENVIRONMENT in ${ENVIRONMENTS}; do - ${SET_ENVIRONMENT} - expand_environment_and_integrate -done diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c deleted file mode 100644 index 57e9c8d88050..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_aarch64.c +++ /dev/null @@ -1,141 +0,0 @@ -// 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. - -#include "cpuinfo_aarch64.h" - -#include "internal/filesystem.h" -#include "internal/hwcaps.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include "internal/unix_features_aggregator.h" - -#include - -DECLARE_SETTER(Aarch64Features, fp) -DECLARE_SETTER(Aarch64Features, asimd) -DECLARE_SETTER(Aarch64Features, aes) -DECLARE_SETTER(Aarch64Features, pmull) -DECLARE_SETTER(Aarch64Features, sha1) -DECLARE_SETTER(Aarch64Features, sha2) -DECLARE_SETTER(Aarch64Features, crc32) - -static const CapabilityConfig kConfigs[] = { - {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp}, // - {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd}, // - {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes}, // - {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull}, // - {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1}, // - {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2}, // - {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32}, // -}; - -static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); - -static bool HandleAarch64Line(const LineResult result, - Aarch64Info* const info) { - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { - if (CpuFeatures_StringView_IsEquals(key, str("Features"))) { - CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) { - info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) { - info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) { - info->part = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) { - info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(Aarch64Info* const info) { - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) { - if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -static const Aarch64Info kEmptyAarch64Info; - -Aarch64Info GetAarch64Info(void) { - // capabilities are fetched from both getauxval and /proc/cpuinfo so we can - // have some information if the executable is sandboxed (aka no access to - // /proc/cpuinfo). - Aarch64Info info = kEmptyAarch64Info; - - FillProcCpuInfoData(&info); - CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, - CpuFeatures_GetHardwareCapabilities(), - &info.features); - - return info; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetAarch64FeaturesEnumValue(const Aarch64Features* features, - Aarch64FeaturesEnum value) { - switch (value) { - case AARCH64_FP: - return features->fp; - case AARCH64_ASIMD: - return features->asimd; - case AARCH64_AES: - return features->aes; - case AARCH64_PMULL: - return features->pmull; - case AARCH64_SHA1: - return features->sha1; - case AARCH64_SHA2: - return features->sha2; - case AARCH64_CRC32: - return features->crc32; - case AARCH64_LAST_: - break; - } - return false; -} - -const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) { - switch (value) { - case AARCH64_FP: - return "fp"; - case AARCH64_ASIMD: - return "asimd"; - case AARCH64_AES: - return "aes"; - case AARCH64_PMULL: - return "pmull"; - case AARCH64_SHA1: - return "sha1"; - case AARCH64_SHA2: - return "sha2"; - case AARCH64_CRC32: - return "crc32"; - case AARCH64_LAST_: - break; - } - return "unknown feature"; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c deleted file mode 100644 index afbb9f1937e8..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_arm.c +++ /dev/null @@ -1,259 +0,0 @@ -// 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. - -#include "cpuinfo_arm.h" - -#include "internal/bit_utils.h" -#include "internal/filesystem.h" -#include "internal/hwcaps.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include "internal/unix_features_aggregator.h" - -#include - -DECLARE_SETTER(ArmFeatures, vfp) -DECLARE_SETTER(ArmFeatures, iwmmxt) -DECLARE_SETTER(ArmFeatures, neon) -DECLARE_SETTER(ArmFeatures, vfpv3) -DECLARE_SETTER(ArmFeatures, vfpv3d16) -DECLARE_SETTER(ArmFeatures, vfpv4) -DECLARE_SETTER(ArmFeatures, idiva) -DECLARE_SETTER(ArmFeatures, idivt) -DECLARE_SETTER(ArmFeatures, aes) -DECLARE_SETTER(ArmFeatures, pmull) -DECLARE_SETTER(ArmFeatures, sha1) -DECLARE_SETTER(ArmFeatures, sha2) -DECLARE_SETTER(ArmFeatures, crc32) - -static const CapabilityConfig kConfigs[] = { - {{ARM_HWCAP_VFP, 0}, "vfp", &set_vfp}, // - {{ARM_HWCAP_IWMMXT, 0}, "iwmmxt", &set_iwmmxt}, // - {{ARM_HWCAP_NEON, 0}, "neon", &set_neon}, // - {{ARM_HWCAP_VFPV3, 0}, "vfpv3", &set_vfpv3}, // - {{ARM_HWCAP_VFPV3D16, 0}, "vfpv3d16", &set_vfpv3d16}, // - {{ARM_HWCAP_VFPV4, 0}, "vfpv4", &set_vfpv4}, // - {{ARM_HWCAP_IDIVA, 0}, "idiva", &set_idiva}, // - {{ARM_HWCAP_IDIVT, 0}, "idivt", &set_idivt}, // - {{0, ARM_HWCAP2_AES}, "aes", &set_aes}, // - {{0, ARM_HWCAP2_PMULL}, "pmull", &set_pmull}, // - {{0, ARM_HWCAP2_SHA1}, "sha1", &set_sha1}, // - {{0, ARM_HWCAP2_SHA2}, "sha2", &set_sha2}, // - {{0, ARM_HWCAP2_CRC32}, "crc32", &set_crc32}, // -}; - -static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); - -typedef struct { - bool processor_reports_armv6; - bool hardware_reports_goldfish; -} ProcCpuInfoData; - -static int IndexOfNonDigit(StringView str) { - size_t index = 0; - while (str.size && isdigit(CpuFeatures_StringView_Front(str))) { - str = CpuFeatures_StringView_PopFront(str, 1); - ++index; - } - return index; -} - -static bool HandleArmLine(const LineResult result, ArmInfo* const info, - ProcCpuInfoData* const proc_info) { - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { - if (CpuFeatures_StringView_IsEquals(key, str("Features"))) { - CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) { - info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) { - info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) { - info->part = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) { - info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); - } else if (CpuFeatures_StringView_IsEquals(key, str("CPU architecture"))) { - // CPU architecture is a number that may be followed by letters. e.g. - // "6TEJ", "7". - const StringView digits = - CpuFeatures_StringView_KeepFront(value, IndexOfNonDigit(value)); - info->architecture = CpuFeatures_StringView_ParsePositiveNumber(digits); - } else if (CpuFeatures_StringView_IsEquals(key, str("Processor"))) { - proc_info->processor_reports_armv6 = - CpuFeatures_StringView_IndexOf(value, str("(v6l)")) >= 0; - } else if (CpuFeatures_StringView_IsEquals(key, str("Hardware"))) { - proc_info->hardware_reports_goldfish = - CpuFeatures_StringView_IsEquals(value, str("Goldfish")); - } - } - return !result.eof; -} - -uint32_t GetArmCpuId(const ArmInfo* const info) { - return (ExtractBitRange(info->implementer, 7, 0) << 24) | - (ExtractBitRange(info->variant, 3, 0) << 20) | - (ExtractBitRange(info->part, 11, 0) << 4) | - (ExtractBitRange(info->revision, 3, 0) << 0); -} - -static void FixErrors(ArmInfo* const info, - ProcCpuInfoData* const proc_cpu_info_data) { - // Fixing Samsung kernel reporting invalid cpu architecture. - // http://code.google.com/p/android/issues/detail?id=10812 - if (proc_cpu_info_data->processor_reports_armv6 && info->architecture >= 7) { - info->architecture = 6; - } - - // Handle kernel configuration bugs that prevent the correct reporting of CPU - // features. - switch (GetArmCpuId(info)) { - case 0x4100C080: - // Special case: The emulator-specific Android 4.2 kernel fails to report - // support for the 32-bit ARM IDIV instruction. Technically, this is a - // feature of the virtual CPU implemented by the emulator. Note that it - // could also support Thumb IDIV in the future, and this will have to be - // slightly updated. - if (info->architecture >= 7 && - proc_cpu_info_data->hardware_reports_goldfish) { - info->features.idiva = true; - } - break; - case 0x511004D0: - // https://crbug.com/341598. - info->features.neon = false; - break; - case 0x510006F2: - case 0x510006F3: - // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report - // IDIV support. - info->features.idiva = true; - info->features.idivt = true; - break; - } - - // Propagate cpu features. - if (info->features.vfpv4) info->features.vfpv3 = true; - if (info->features.neon) info->features.vfpv3 = true; - if (info->features.vfpv3) info->features.vfp = true; -} - -static void FillProcCpuInfoData(ArmInfo* const info, - ProcCpuInfoData* proc_cpu_info_data) { - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) { - if (!HandleArmLine(StackLineReader_NextLine(&reader), info, - proc_cpu_info_data)) { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -static const ArmInfo kEmptyArmInfo; - -static const ProcCpuInfoData kEmptyProcCpuInfoData; - -ArmInfo GetArmInfo(void) { - // capabilities are fetched from both getauxval and /proc/cpuinfo so we can - // have some information if the executable is sandboxed (aka no access to - // /proc/cpuinfo). - ArmInfo info = kEmptyArmInfo; - ProcCpuInfoData proc_cpu_info_data = kEmptyProcCpuInfoData; - - FillProcCpuInfoData(&info, &proc_cpu_info_data); - CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, - CpuFeatures_GetHardwareCapabilities(), - &info.features); - - FixErrors(&info, &proc_cpu_info_data); - - return info; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetArmFeaturesEnumValue(const ArmFeatures* features, - ArmFeaturesEnum value) { - switch (value) { - case ARM_VFP: - return features->vfp; - case ARM_IWMMXT: - return features->iwmmxt; - case ARM_NEON: - return features->neon; - case ARM_VFPV3: - return features->vfpv3; - case ARM_VFPV3D16: - return features->vfpv3d16; - case ARM_VFPV4: - return features->vfpv4; - case ARM_IDIVA: - return features->idiva; - case ARM_IDIVT: - return features->idivt; - case ARM_AES: - return features->aes; - case ARM_PMULL: - return features->pmull; - case ARM_SHA1: - return features->sha1; - case ARM_SHA2: - return features->sha2; - case ARM_CRC32: - return features->crc32; - case ARM_LAST_: - break; - } - return false; -} - -const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) { - switch (value) { - case ARM_VFP: - return "vfp"; - case ARM_IWMMXT: - return "iwmmxt"; - case ARM_NEON: - return "neon"; - case ARM_VFPV3: - return "vfpv3"; - case ARM_VFPV3D16: - return "vfpv3d16"; - case ARM_VFPV4: - return "vfpv4"; - case ARM_IDIVA: - return "idiva"; - case ARM_IDIVT: - return "idivt"; - case ARM_AES: - return "aes"; - case ARM_PMULL: - return "pmull"; - case ARM_SHA1: - return "sha1"; - case ARM_SHA2: - return "sha2"; - case ARM_CRC32: - return "crc32"; - case ARM_LAST_: - break; - } - return "unknown feature"; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c deleted file mode 100644 index 706d55535b3e..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_mips.c +++ /dev/null @@ -1,104 +0,0 @@ -// 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. - -#include "cpuinfo_mips.h" - -#include "internal/filesystem.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include "internal/unix_features_aggregator.h" - -DECLARE_SETTER(MipsFeatures, msa) -DECLARE_SETTER(MipsFeatures, eva) -DECLARE_SETTER(MipsFeatures, r6) - -static const CapabilityConfig kConfigs[] = { - {{MIPS_HWCAP_MSA, 0}, "msa", &set_msa}, // - {{0, 0}, "eva", &set_eva}, // - {{MIPS_HWCAP_R6, 0}, "r6", &set_r6}, // -}; -static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); - -static bool HandleMipsLine(const LineResult result, - MipsFeatures* const features) { - StringView key, value; - // See tests for an example. - if (CpuFeatures_StringView_GetAttributeKeyValue(result.line, &key, &value)) { - if (CpuFeatures_StringView_IsEquals(key, str("ASEs implemented"))) { - CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, features); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(MipsFeatures* const features) { - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) { - if (!HandleMipsLine(StackLineReader_NextLine(&reader), features)) { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -static const MipsInfo kEmptyMipsInfo; - -MipsInfo GetMipsInfo(void) { - // capabilities are fetched from both getauxval and /proc/cpuinfo so we can - // have some information if the executable is sandboxed (aka no access to - // /proc/cpuinfo). - MipsInfo info = kEmptyMipsInfo; - - FillProcCpuInfoData(&info.features); - CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, - CpuFeatures_GetHardwareCapabilities(), - &info.features); - return info; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetMipsFeaturesEnumValue(const MipsFeatures* features, - MipsFeaturesEnum value) { - switch (value) { - case MIPS_MSA: - return features->msa; - case MIPS_EVA: - return features->eva; - case MIPS_R6: - return features->r6; - case MIPS_LAST_: - break; - } - return false; -} - -const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value) { - switch (value) { - case MIPS_MSA: - return "msa"; - case MIPS_EVA: - return "eva"; - case MIPS_R6: - return "r6"; - case MIPS_LAST_: - break; - } - return "unknown feature"; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c deleted file mode 100644 index 53d2059c3205..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_ppc.c +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright 2018 IBM. -// -// 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. - -#include -#include - -#include "cpuinfo_ppc.h" -#include "internal/bit_utils.h" -#include "internal/filesystem.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include "internal/unix_features_aggregator.h" - -DECLARE_SETTER(PPCFeatures, ppc32) -DECLARE_SETTER(PPCFeatures, ppc64) -DECLARE_SETTER(PPCFeatures, ppc601) -DECLARE_SETTER(PPCFeatures, altivec) -DECLARE_SETTER(PPCFeatures, fpu) -DECLARE_SETTER(PPCFeatures, mmu) -DECLARE_SETTER(PPCFeatures, mac_4xx) -DECLARE_SETTER(PPCFeatures, unifiedcache) -DECLARE_SETTER(PPCFeatures, spe) -DECLARE_SETTER(PPCFeatures, efpsingle) -DECLARE_SETTER(PPCFeatures, efpdouble) -DECLARE_SETTER(PPCFeatures, no_tb) -DECLARE_SETTER(PPCFeatures, power4) -DECLARE_SETTER(PPCFeatures, power5) -DECLARE_SETTER(PPCFeatures, power5plus) -DECLARE_SETTER(PPCFeatures, cell) -DECLARE_SETTER(PPCFeatures, booke) -DECLARE_SETTER(PPCFeatures, smt) -DECLARE_SETTER(PPCFeatures, icachesnoop) -DECLARE_SETTER(PPCFeatures, arch205) -DECLARE_SETTER(PPCFeatures, pa6t) -DECLARE_SETTER(PPCFeatures, dfp) -DECLARE_SETTER(PPCFeatures, power6ext) -DECLARE_SETTER(PPCFeatures, arch206) -DECLARE_SETTER(PPCFeatures, vsx) -DECLARE_SETTER(PPCFeatures, pseries_perfmon_compat) -DECLARE_SETTER(PPCFeatures, truele) -DECLARE_SETTER(PPCFeatures, ppcle) -DECLARE_SETTER(PPCFeatures, arch207) -DECLARE_SETTER(PPCFeatures, htm) -DECLARE_SETTER(PPCFeatures, dscr) -DECLARE_SETTER(PPCFeatures, ebb) -DECLARE_SETTER(PPCFeatures, isel) -DECLARE_SETTER(PPCFeatures, tar) -DECLARE_SETTER(PPCFeatures, vcrypto) -DECLARE_SETTER(PPCFeatures, htm_nosc) -DECLARE_SETTER(PPCFeatures, arch300) -DECLARE_SETTER(PPCFeatures, ieee128) -DECLARE_SETTER(PPCFeatures, darn) -DECLARE_SETTER(PPCFeatures, scv) -DECLARE_SETTER(PPCFeatures, htm_no_suspend) - -static const CapabilityConfig kConfigs[] = { - {{PPC_FEATURE_32, 0}, "ppc32", &set_ppc32}, - {{PPC_FEATURE_64, 0}, "ppc64", &set_ppc64}, - {{PPC_FEATURE_601_INSTR, 0}, "ppc601", &set_ppc601}, - {{PPC_FEATURE_HAS_ALTIVEC, 0}, "altivec", &set_altivec}, - {{PPC_FEATURE_HAS_FPU, 0}, "fpu", &set_fpu}, - {{PPC_FEATURE_HAS_MMU, 0}, "mmu", &set_mmu}, - {{PPC_FEATURE_HAS_4xxMAC, 0}, "4xxmac", &set_mac_4xx}, - {{PPC_FEATURE_UNIFIED_CACHE, 0}, "ucache", &set_unifiedcache}, - {{PPC_FEATURE_HAS_SPE, 0}, "spe", &set_spe}, - {{PPC_FEATURE_HAS_EFP_SINGLE, 0}, "efpsingle", &set_efpsingle}, - {{PPC_FEATURE_HAS_EFP_DOUBLE, 0}, "efpdouble", &set_efpdouble}, - {{PPC_FEATURE_NO_TB, 0}, "notb", &set_no_tb}, - {{PPC_FEATURE_POWER4, 0}, "power4", &set_power4}, - {{PPC_FEATURE_POWER5, 0}, "power5", &set_power5}, - {{PPC_FEATURE_POWER5_PLUS, 0}, "power5+", &set_power5plus}, - {{PPC_FEATURE_CELL, 0}, "cellbe", &set_cell}, - {{PPC_FEATURE_BOOKE, 0}, "booke", &set_booke}, - {{PPC_FEATURE_SMT, 0}, "smt", &set_smt}, - {{PPC_FEATURE_ICACHE_SNOOP, 0}, "ic_snoop", &set_icachesnoop}, - {{PPC_FEATURE_ARCH_2_05, 0}, "arch_2_05", &set_arch205}, - {{PPC_FEATURE_PA6T, 0}, "pa6t", &set_pa6t}, - {{PPC_FEATURE_HAS_DFP, 0}, "dfp", &set_dfp}, - {{PPC_FEATURE_POWER6_EXT, 0}, "power6x", &set_power6ext}, - {{PPC_FEATURE_ARCH_2_06, 0}, "arch_2_06", &set_arch206}, - {{PPC_FEATURE_HAS_VSX, 0}, "vsx", &set_vsx}, - {{PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0}, - "archpmu", - &set_pseries_perfmon_compat}, - {{PPC_FEATURE_TRUE_LE, 0}, "true_le", &set_truele}, - {{PPC_FEATURE_PPC_LE, 0}, "ppcle", &set_ppcle}, - {{0, PPC_FEATURE2_ARCH_2_07}, "arch_2_07", &set_arch207}, - {{0, PPC_FEATURE2_HTM}, "htm", &set_htm}, - {{0, PPC_FEATURE2_DSCR}, "dscr", &set_dscr}, - {{0, PPC_FEATURE2_EBB}, "ebb", &set_ebb}, - {{0, PPC_FEATURE2_ISEL}, "isel", &set_isel}, - {{0, PPC_FEATURE2_TAR}, "tar", &set_tar}, - {{0, PPC_FEATURE2_VEC_CRYPTO}, "vcrypto", &set_vcrypto}, - {{0, PPC_FEATURE2_HTM_NOSC}, "htm-nosc", &set_htm_nosc}, - {{0, PPC_FEATURE2_ARCH_3_00}, "arch_3_00", &set_arch300}, - {{0, PPC_FEATURE2_HAS_IEEE128}, "ieee128", &set_ieee128}, - {{0, PPC_FEATURE2_DARN}, "darn", &set_darn}, - {{0, PPC_FEATURE2_SCV}, "scv", &set_scv}, - {{0, PPC_FEATURE2_HTM_NO_SUSPEND}, "htm-no-suspend", &set_htm_no_suspend}, -}; -static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); - -static bool HandlePPCLine(const LineResult result, - PPCPlatformStrings* const strings) { - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) { - if (CpuFeatures_StringView_HasWord(key, "platform")) { - CpuFeatures_StringView_CopyString(value, strings->platform, - sizeof(strings->platform)); - } else if (CpuFeatures_StringView_IsEquals(key, str("model"))) { - CpuFeatures_StringView_CopyString(value, strings->model, - sizeof(strings->platform)); - } else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) { - CpuFeatures_StringView_CopyString(value, strings->machine, - sizeof(strings->platform)); - } else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) { - CpuFeatures_StringView_CopyString(value, strings->cpu, - sizeof(strings->platform)); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(PPCPlatformStrings* const strings) { - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) { - if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -static const PPCInfo kEmptyPPCInfo; - -PPCInfo GetPPCInfo(void) { - /* - * On Power feature flags aren't currently in cpuinfo so we only look at - * the auxilary vector. - */ - PPCInfo info = kEmptyPPCInfo; - - CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs, - CpuFeatures_GetHardwareCapabilities(), - &info.features); - return info; -} - -static const PPCPlatformStrings kEmptyPPCPlatformStrings; - -PPCPlatformStrings GetPPCPlatformStrings(void) { - PPCPlatformStrings strings = kEmptyPPCPlatformStrings; - - FillProcCpuInfoData(&strings); - strings.type = CpuFeatures_GetPlatformType(); - return strings; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetPPCFeaturesEnumValue(const PPCFeatures* features, - PPCFeaturesEnum value) { - switch (value) { - case PPC_32: - return features->ppc32; - case PPC_64: - return features->ppc64; - case PPC_601_INSTR: - return features->ppc601; - case PPC_HAS_ALTIVEC: - return features->altivec; - case PPC_HAS_FPU: - return features->fpu; - case PPC_HAS_MMU: - return features->mmu; - case PPC_HAS_4xxMAC: - return features->mac_4xx; - case PPC_UNIFIED_CACHE: - return features->unifiedcache; - case PPC_HAS_SPE: - return features->spe; - case PPC_HAS_EFP_SINGLE: - return features->efpsingle; - case PPC_HAS_EFP_DOUBLE: - return features->efpdouble; - case PPC_NO_TB: - return features->no_tb; - case PPC_POWER4: - return features->power4; - case PPC_POWER5: - return features->power5; - case PPC_POWER5_PLUS: - return features->power5plus; - case PPC_CELL: - return features->cell; - case PPC_BOOKE: - return features->booke; - case PPC_SMT: - return features->smt; - case PPC_ICACHE_SNOOP: - return features->icachesnoop; - case PPC_ARCH_2_05: - return features->arch205; - case PPC_PA6T: - return features->pa6t; - case PPC_HAS_DFP: - return features->dfp; - case PPC_POWER6_EXT: - return features->power6ext; - case PPC_ARCH_2_06: - return features->arch206; - case PPC_HAS_VSX: - return features->vsx; - case PPC_PSERIES_PERFMON_COMPAT: - return features->pseries_perfmon_compat; - case PPC_TRUE_LE: - return features->truele; - case PPC_PPC_LE: - return features->ppcle; - case PPC_ARCH_2_07: - return features->arch207; - case PPC_HTM: - return features->htm; - case PPC_DSCR: - return features->dscr; - case PPC_EBB: - return features->ebb; - case PPC_ISEL: - return features->isel; - case PPC_TAR: - return features->tar; - case PPC_VEC_CRYPTO: - return features->vcrypto; - case PPC_HTM_NOSC: - return features->htm_nosc; - case PPC_ARCH_3_00: - return features->arch300; - case PPC_HAS_IEEE128: - return features->ieee128; - case PPC_DARN: - return features->darn; - case PPC_SCV: - return features->scv; - case PPC_HTM_NO_SUSPEND: - return features->htm_no_suspend; - case PPC_LAST_: - break; - } - return false; -} - -/* Have used the same names as glibc */ -const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) { - switch (value) { - case PPC_32: - return "ppc32"; - case PPC_64: - return "ppc64"; - case PPC_601_INSTR: - return "ppc601"; - case PPC_HAS_ALTIVEC: - return "altivec"; - case PPC_HAS_FPU: - return "fpu"; - case PPC_HAS_MMU: - return "mmu"; - case PPC_HAS_4xxMAC: - return "4xxmac"; - case PPC_UNIFIED_CACHE: - return "ucache"; - case PPC_HAS_SPE: - return "spe"; - case PPC_HAS_EFP_SINGLE: - return "efpsingle"; - case PPC_HAS_EFP_DOUBLE: - return "efpdouble"; - case PPC_NO_TB: - return "notb"; - case PPC_POWER4: - return "power4"; - case PPC_POWER5: - return "power5"; - case PPC_POWER5_PLUS: - return "power5+"; - case PPC_CELL: - return "cellbe"; - case PPC_BOOKE: - return "booke"; - case PPC_SMT: - return "smt"; - case PPC_ICACHE_SNOOP: - return "ic_snoop"; - case PPC_ARCH_2_05: - return "arch_2_05"; - case PPC_PA6T: - return "pa6t"; - case PPC_HAS_DFP: - return "dfp"; - case PPC_POWER6_EXT: - return "power6x"; - case PPC_ARCH_2_06: - return "arch_2_06"; - case PPC_HAS_VSX: - return "vsx"; - case PPC_PSERIES_PERFMON_COMPAT: - return "archpmu"; - case PPC_TRUE_LE: - return "true_le"; - case PPC_PPC_LE: - return "ppcle"; - case PPC_ARCH_2_07: - return "arch_2_07"; - case PPC_HTM: - return "htm"; - case PPC_DSCR: - return "dscr"; - case PPC_EBB: - return "ebb"; - case PPC_ISEL: - return "isel"; - case PPC_TAR: - return "tar"; - case PPC_VEC_CRYPTO: - return "vcrypto"; - case PPC_HTM_NOSC: - return "htm-nosc"; - case PPC_ARCH_3_00: - return "arch_3_00"; - case PPC_HAS_IEEE128: - return "ieee128"; - case PPC_DARN: - return "darn"; - case PPC_SCV: - return "scv"; - case PPC_HTM_NO_SUSPEND: - return "htm-no-suspend"; - case PPC_LAST_: - break; - } - return "unknown_feature"; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c b/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c deleted file mode 100644 index 52f178fbb0b1..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/cpuinfo_x86.c +++ /dev/null @@ -1,518 +0,0 @@ -// 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. - -#include "cpuinfo_x86.h" -#include "internal/bit_utils.h" -#include "internal/cpuid_x86.h" - -#include -#include - -#if !defined(CPU_FEATURES_ARCH_X86) -#error "Cannot compile cpuinfo_x86 on a non x86 platform." -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Definitions for CpuId and GetXCR0Eax. -//////////////////////////////////////////////////////////////////////////////// - -#if defined(CPU_FEATURES_MOCK_CPUID_X86) -// Implementation will be provided by test/cpuinfo_x86_test.cc. -#elif defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) - -#include - -Leaf CpuId(uint32_t leaf_id) { - Leaf leaf; - __cpuid_count(leaf_id, 0, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx); - return leaf; -} - -uint32_t GetXCR0Eax(void) { - uint32_t eax, edx; - /* named form of xgetbv not supported on OSX, so must use byte form, see: - https://github.com/asmjit/asmjit/issues/78 - */ - __asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0)); - return eax; -} - -#elif defined(CPU_FEATURES_COMPILER_MSC) - -#include -#include // For __cpuidex() - -Leaf CpuId(uint32_t leaf_id) { - Leaf leaf; - int data[4]; - __cpuid(data, leaf_id); - leaf.eax = data[0]; - leaf.ebx = data[1]; - leaf.ecx = data[2]; - leaf.edx = data[3]; - return leaf; -} - -uint32_t GetXCR0Eax(void) { return _xgetbv(0); } - -#else -#error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC." -#endif - -static const Leaf kEmptyLeaf; - -static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) { - if (leaf_id <= max_cpuid_leaf) { - return CpuId(leaf_id); - } else { - return kEmptyLeaf; - } -} - -#define MASK_XMM 0x2 -#define MASK_YMM 0x4 -#define MASK_MASKREG 0x20 -#define MASK_ZMM0_15 0x40 -#define MASK_ZMM16_31 0x80 - -static bool HasMask(uint32_t value, uint32_t mask) { - return (value & mask) == mask; -} - -// Checks that operating system saves and restores xmm registers during context -// switches. -static bool HasXmmOsXSave(uint32_t xcr0_eax) { - return HasMask(xcr0_eax, MASK_XMM); -} - -// Checks that operating system saves and restores ymm registers during context -// switches. -static bool HasYmmOsXSave(uint32_t xcr0_eax) { - return HasMask(xcr0_eax, MASK_XMM | MASK_YMM); -} - -// Checks that operating system saves and restores zmm registers during context -// switches. -static bool HasZmmOsXSave(uint32_t xcr0_eax) { - return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 | - MASK_ZMM16_31); -} - -static void SetVendor(const Leaf leaf, char* const vendor) { - *(uint32_t*)(vendor) = leaf.ebx; - *(uint32_t*)(vendor + 4) = leaf.edx; - *(uint32_t*)(vendor + 8) = leaf.ecx; - vendor[12] = '\0'; -} - -static int IsVendor(const Leaf leaf, const char* const name) { - const uint32_t ebx = *(const uint32_t*)(name); - const uint32_t edx = *(const uint32_t*)(name + 4); - const uint32_t ecx = *(const uint32_t*)(name + 8); - return leaf.ebx == ebx && leaf.ecx == ecx && leaf.edx == edx; -} - -// Reference https://en.wikipedia.org/wiki/CPUID. -static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info) { - const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1); - const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7); - - const bool have_xsave = IsBitSet(leaf_1.ecx, 26); - const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); - const uint32_t xcr0_eax = (have_xsave && have_osxsave) ? GetXCR0Eax() : 0; - const bool have_sse_os_support = HasXmmOsXSave(xcr0_eax); - const bool have_avx_os_support = HasYmmOsXSave(xcr0_eax); - const bool have_avx512_os_support = HasZmmOsXSave(xcr0_eax); - - const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); - const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); - const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4); - const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16); - - X86Features* const features = &info->features; - - info->family = extended_family + family; - info->model = (extended_model << 4) + model; - info->stepping = ExtractBitRange(leaf_1.eax, 3, 0); - - features->smx = IsBitSet(leaf_1.ecx, 6); - features->cx16 = IsBitSet(leaf_1.ecx, 13); - features->movbe = IsBitSet(leaf_1.ecx, 22); - features->popcnt = IsBitSet(leaf_1.ecx, 23); - features->aes = IsBitSet(leaf_1.ecx, 25); - features->f16c = IsBitSet(leaf_1.ecx, 29); - features->rdrnd = IsBitSet(leaf_1.ecx, 30); - features->sgx = IsBitSet(leaf_7.ebx, 2); - features->bmi1 = IsBitSet(leaf_7.ebx, 3); - features->bmi2 = IsBitSet(leaf_7.ebx, 8); - features->erms = IsBitSet(leaf_7.ebx, 9); - features->sha = IsBitSet(leaf_7.ebx, 29); - features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); - - if (have_sse_os_support) { - features->ssse3 = IsBitSet(leaf_1.ecx, 9); - features->sse4_1 = IsBitSet(leaf_1.ecx, 19); - features->sse4_2 = IsBitSet(leaf_1.ecx, 20); - } - - if (have_avx_os_support) { - features->fma3 = IsBitSet(leaf_1.ecx, 12); - features->avx = IsBitSet(leaf_1.ecx, 28); - features->avx2 = IsBitSet(leaf_7.ebx, 5); - } - - if (have_avx512_os_support) { - features->avx512f = IsBitSet(leaf_7.ebx, 16); - features->avx512cd = IsBitSet(leaf_7.ebx, 28); - features->avx512er = IsBitSet(leaf_7.ebx, 27); - features->avx512pf = IsBitSet(leaf_7.ebx, 26); - features->avx512bw = IsBitSet(leaf_7.ebx, 30); - features->avx512dq = IsBitSet(leaf_7.ebx, 17); - features->avx512vl = IsBitSet(leaf_7.ebx, 31); - features->avx512ifma = IsBitSet(leaf_7.ebx, 21); - features->avx512vbmi = IsBitSet(leaf_7.ecx, 1); - features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6); - features->avx512vnni = IsBitSet(leaf_7.ecx, 11); - features->avx512bitalg = IsBitSet(leaf_7.ecx, 12); - features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14); - features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2); - features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3); - } -} - -static const X86Info kEmptyX86Info; - -X86Info GetX86Info(void) { - X86Info info = kEmptyX86Info; - const Leaf leaf_0 = CpuId(0); - const uint32_t max_cpuid_leaf = leaf_0.eax; - SetVendor(leaf_0, info.vendor); - if (IsVendor(leaf_0, "GenuineIntel") || IsVendor(leaf_0, "AuthenticAMD")) { - ParseCpuId(max_cpuid_leaf, &info); - } - return info; -} - -#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) - -X86Microarchitecture GetX86Microarchitecture(const X86Info* info) { - if (memcmp(info->vendor, "GenuineIntel", sizeof(info->vendor)) == 0) { - switch (CPUID(info->family, info->model)) { - case CPUID(0x06, 0x35): - case CPUID(0x06, 0x36): - // https://en.wikipedia.org/wiki/Bonnell_(microarchitecture) - return INTEL_ATOM_BNL; - case CPUID(0x06, 0x37): - case CPUID(0x06, 0x4C): - // https://en.wikipedia.org/wiki/Silvermont - return INTEL_ATOM_SMT; - case CPUID(0x06, 0x5C): - // https://en.wikipedia.org/wiki/Goldmont - return INTEL_ATOM_GMT; - case CPUID(0x06, 0x0F): - case CPUID(0x06, 0x16): - // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) - return INTEL_CORE; - case CPUID(0x06, 0x17): - case CPUID(0x06, 0x1D): - // https://en.wikipedia.org/wiki/Penryn_(microarchitecture) - return INTEL_PNR; - case CPUID(0x06, 0x1A): - case CPUID(0x06, 0x1E): - case CPUID(0x06, 0x1F): - case CPUID(0x06, 0x2E): - // https://en.wikipedia.org/wiki/Nehalem_(microarchitecture) - return INTEL_NHM; - case CPUID(0x06, 0x25): - case CPUID(0x06, 0x2C): - case CPUID(0x06, 0x2F): - // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) - return INTEL_WSM; - case CPUID(0x06, 0x2A): - case CPUID(0x06, 0x2D): - // https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings - return INTEL_SNB; - case CPUID(0x06, 0x3A): - case CPUID(0x06, 0x3E): - // https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings - return INTEL_IVB; - case CPUID(0x06, 0x3C): - case CPUID(0x06, 0x3F): - case CPUID(0x06, 0x45): - case CPUID(0x06, 0x46): - // https://en.wikipedia.org/wiki/Haswell_(microarchitecture) - return INTEL_HSW; - case CPUID(0x06, 0x3D): - case CPUID(0x06, 0x47): - case CPUID(0x06, 0x4F): - case CPUID(0x06, 0x56): - // https://en.wikipedia.org/wiki/Broadwell_(microarchitecture) - return INTEL_BDW; - case CPUID(0x06, 0x4E): - case CPUID(0x06, 0x55): - case CPUID(0x06, 0x5E): - // https://en.wikipedia.org/wiki/Skylake_(microarchitecture) - return INTEL_SKL; - case CPUID(0x06, 0x8E): - case CPUID(0x06, 0x9E): - // https://en.wikipedia.org/wiki/Kaby_Lake - return INTEL_KBL; - default: - return X86_UNKNOWN; - } - } - if (memcmp(info->vendor, "AuthenticAMD", sizeof(info->vendor)) == 0) { - switch (info->family) { - // https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures - case 0x0F: - return AMD_HAMMER; - case 0x10: - return AMD_K10; - case 0x14: - return AMD_BOBCAT; - case 0x15: - return AMD_BULLDOZER; - case 0x16: - return AMD_JAGUAR; - case 0x17: - return AMD_ZEN; - default: - return X86_UNKNOWN; - } - } - return X86_UNKNOWN; -} - -static void SetString(const uint32_t max_cpuid_ext_leaf, const uint32_t leaf_id, - char* buffer) { - const Leaf leaf = SafeCpuId(max_cpuid_ext_leaf, leaf_id); - // We allow calling memcpy from SetString which is only called when requesting - // X86BrandString. - memcpy(buffer, &leaf, sizeof(Leaf)); -} - -void FillX86BrandString(char brand_string[49]) { - const Leaf leaf_ext_0 = CpuId(0x80000000); - const uint32_t max_cpuid_leaf_ext = leaf_ext_0.eax; - SetString(max_cpuid_leaf_ext, 0x80000002, brand_string); - SetString(max_cpuid_leaf_ext, 0x80000003, brand_string + 16); - SetString(max_cpuid_leaf_ext, 0x80000004, brand_string + 32); - brand_string[48] = '\0'; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetX86FeaturesEnumValue(const X86Features* features, - X86FeaturesEnum value) { - switch (value) { - case X86_AES: - return features->aes; - case X86_ERMS: - return features->erms; - case X86_F16C: - return features->f16c; - case X86_FMA3: - return features->fma3; - case X86_VPCLMULQDQ: - return features->vpclmulqdq; - case X86_BMI1: - return features->bmi1; - case X86_BMI2: - return features->bmi2; - case X86_SSSE3: - return features->ssse3; - case X86_SSE4_1: - return features->sse4_1; - case X86_SSE4_2: - return features->sse4_2; - case X86_AVX: - return features->avx; - case X86_AVX2: - return features->avx2; - case X86_AVX512F: - return features->avx512f; - case X86_AVX512CD: - return features->avx512cd; - case X86_AVX512ER: - return features->avx512er; - case X86_AVX512PF: - return features->avx512pf; - case X86_AVX512BW: - return features->avx512bw; - case X86_AVX512DQ: - return features->avx512dq; - case X86_AVX512VL: - return features->avx512vl; - case X86_AVX512IFMA: - return features->avx512ifma; - case X86_AVX512VBMI: - return features->avx512vbmi; - case X86_AVX512VBMI2: - return features->avx512vbmi2; - case X86_AVX512VNNI: - return features->avx512vnni; - case X86_AVX512BITALG: - return features->avx512bitalg; - case X86_AVX512VPOPCNTDQ: - return features->avx512vpopcntdq; - case X86_AVX512_4VNNIW: - return features->avx512_4vnniw; - case X86_AVX512_4VBMI2: - return features->avx512_4vbmi2; - case X86_SMX: - return features->smx; - case X86_SGX: - return features->sgx; - case X86_CX16: - return features->cx16; - case X86_SHA: - return features->sha; - case X86_POPCNT: - return features->popcnt; - case X86_MOVBE: - return features->movbe; - case X86_RDRND: - return features->rdrnd; - case X86_LAST_: - break; - } - return false; -} - -const char* GetX86FeaturesEnumName(X86FeaturesEnum value) { - switch (value) { - case X86_AES: - return "aes"; - case X86_ERMS: - return "erms"; - case X86_F16C: - return "f16c"; - case X86_FMA3: - return "fma3"; - case X86_VPCLMULQDQ: - return "vpclmulqdq"; - case X86_BMI1: - return "bmi1"; - case X86_BMI2: - return "bmi2"; - case X86_SSSE3: - return "ssse3"; - case X86_SSE4_1: - return "sse4_1"; - case X86_SSE4_2: - return "sse4_2"; - case X86_AVX: - return "avx"; - case X86_AVX2: - return "avx2"; - case X86_AVX512F: - return "avx512f"; - case X86_AVX512CD: - return "avx512cd"; - case X86_AVX512ER: - return "avx512er"; - case X86_AVX512PF: - return "avx512pf"; - case X86_AVX512BW: - return "avx512bw"; - case X86_AVX512DQ: - return "avx512dq"; - case X86_AVX512VL: - return "avx512vl"; - case X86_AVX512IFMA: - return "avx512ifma"; - case X86_AVX512VBMI: - return "avx512vbmi"; - case X86_AVX512VBMI2: - return "avx512vbmi2"; - case X86_AVX512VNNI: - return "avx512vnni"; - case X86_AVX512BITALG: - return "avx512bitalg"; - case X86_AVX512VPOPCNTDQ: - return "avx512vpopcntdq"; - case X86_AVX512_4VNNIW: - return "avx512_4vnniw"; - case X86_AVX512_4VBMI2: - return "avx512_4vbmi2"; - case X86_SMX: - return "smx"; - case X86_SGX: - return "sgx"; - case X86_CX16: - return "cx16"; - case X86_SHA: - return "sha"; - case X86_POPCNT: - return "popcnt"; - case X86_MOVBE: - return "movbe"; - case X86_RDRND: - return "rdrnd"; - case X86_LAST_: - break; - } - return "unknown_feature"; -} - -const char* GetX86MicroarchitectureName(X86Microarchitecture uarch) { - switch (uarch) { - case X86_UNKNOWN: - return "X86_UNKNOWN"; - case INTEL_CORE: - return "INTEL_CORE"; - case INTEL_PNR: - return "INTEL_PNR"; - case INTEL_NHM: - return "INTEL_NHM"; - case INTEL_ATOM_BNL: - return "INTEL_ATOM_BNL"; - case INTEL_WSM: - return "INTEL_WSM"; - case INTEL_SNB: - return "INTEL_SNB"; - case INTEL_IVB: - return "INTEL_IVB"; - case INTEL_ATOM_SMT: - return "INTEL_ATOM_SMT"; - case INTEL_HSW: - return "INTEL_HSW"; - case INTEL_BDW: - return "INTEL_BDW"; - case INTEL_SKL: - return "INTEL_SKL"; - case INTEL_ATOM_GMT: - return "INTEL_ATOM_GMT"; - case INTEL_KBL: - return "INTEL_KBL"; - case INTEL_CFL: - return "INTEL_CFL"; - case INTEL_CNL: - return "INTEL_CNL"; - case AMD_HAMMER: - return "AMD_HAMMER"; - case AMD_K10: - return "AMD_K10"; - case AMD_BOBCAT: - return "AMD_BOBCAT"; - case AMD_BULLDOZER: - return "AMD_BULLDOZER"; - case AMD_JAGUAR: - return "AMD_JAGUAR"; - case AMD_ZEN: - return "AMD_ZEN"; - } - return "unknown microarchitecture"; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/filesystem.c b/cpp/src/arrow/vendored/cpu_features/src/filesystem.c deleted file mode 100644 index 25444da5d71e..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/filesystem.c +++ /dev/null @@ -1,59 +0,0 @@ -// 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. - -#include "internal/filesystem.h" - -#include -#include -#include -#include - -#if defined(CPU_FEATURES_MOCK_FILESYSTEM) -// Implementation will be provided by test/filesystem_for_testing.cc. -#elif defined(_MSC_VER) -#include -int CpuFeatures_OpenFile(const char* filename) { - return _open(filename, _O_RDONLY); -} - -void CpuFeatures_CloseFile(int file_descriptor) { _close(file_descriptor); } - -int CpuFeatures_ReadFile(int file_descriptor, void* buffer, - size_t buffer_size) { - return _read(file_descriptor, buffer, buffer_size); -} - -#else -#include - -int CpuFeatures_OpenFile(const char* filename) { - int result; - do { - result = open(filename, O_RDONLY); - } while (result == -1L && errno == EINTR); - return result; -} - -void CpuFeatures_CloseFile(int file_descriptor) { close(file_descriptor); } - -int CpuFeatures_ReadFile(int file_descriptor, void* buffer, - size_t buffer_size) { - int result; - do { - result = read(file_descriptor, buffer, buffer_size); - } while (result == -1L && errno == EINTR); - return result; -} - -#endif diff --git a/cpp/src/arrow/vendored/cpu_features/src/hwcaps.c b/cpp/src/arrow/vendored/cpu_features/src/hwcaps.c deleted file mode 100644 index 815e5c185c7d..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/hwcaps.c +++ /dev/null @@ -1,162 +0,0 @@ -// 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. - -#include -#include - -#include "cpu_features_macros.h" -#include "internal/filesystem.h" -#include "internal/hwcaps.h" -#include "internal/string_view.h" - -#if defined(NDEBUG) -#define D(...) -#else -#include -#define D(...) \ - do { \ - printf(__VA_ARGS__); \ - fflush(stdout); \ - } while (0) -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Implementation of GetElfHwcapFromGetauxval -//////////////////////////////////////////////////////////////////////////////// - -#if defined(CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL) -// Implementation will be provided by test/hwcaps_for_testing.cc. -#elif defined(HAVE_STRONG_GETAUXVAL) -#include -static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) { - return getauxval(hwcap_type); -} -#elif defined(HAVE_DLFCN_H) -// On Android we probe the system's C library for a 'getauxval' function and -// call it if it exits, or return 0 for failure. This function is available -// since API level 20. -// -// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge -// case where some NDK developers use headers for a platform that is newer than -// the one really targetted by their application. This is typically done to use -// newer native APIs only when running on more recent Android versions, and -// requires careful symbol management. -// -// Note that getauxval() can't really be re-implemented here, because its -// implementation does not parse /proc/self/auxv. Instead it depends on values -// that are passed by the kernel at process-init time to the C runtime -// initialization layer. - -#include -#define AT_HWCAP 16 -#define AT_HWCAP2 26 -#define AT_PLATFORM 15 -#define AT_BASE_PLATFORM 24 - -typedef unsigned long getauxval_func_t(unsigned long); - -static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type) { - uint32_t ret = 0; - void* libc_handle = NULL; - getauxval_func_t* func = NULL; - - dlerror(); // Cleaning error state before calling dlopen. - libc_handle = dlopen("libc.so", RTLD_NOW); - if (!libc_handle) { - D("Could not dlopen() C library: %s\n", dlerror()); - return 0; - } - func = (getauxval_func_t*)dlsym(libc_handle, "getauxval"); - if (!func) { - D("Could not find getauxval() in C library\n"); - } else { - // Note: getauxval() returns 0 on failure. Doesn't touch errno. - ret = (uint32_t)(*func)(hwcap_type); - } - dlclose(libc_handle); - return ret; -} -#else -#error "This platform does not provide hardware capabilities." -#endif - -// Implementation of GetHardwareCapabilities for OS that provide -// GetElfHwcapFromGetauxval(). - -// Fallback when getauxval is not available, retrieves hwcaps from -// "/proc/self/auxv". -static uint32_t GetElfHwcapFromProcSelfAuxv(uint32_t hwcap_type) { - struct { - uint32_t tag; - uint32_t value; - } entry; - uint32_t result = 0; - const char filepath[] = "/proc/self/auxv"; - const int fd = CpuFeatures_OpenFile(filepath); - if (fd < 0) { - D("Could not open %s\n", filepath); - return 0; - } - for (;;) { - const int ret = CpuFeatures_ReadFile(fd, (char*)&entry, sizeof entry); - if (ret < 0) { - D("Error while reading %s\n", filepath); - break; - } - // Detect end of list. - if (ret == 0 || (entry.tag == 0 && entry.value == 0)) { - break; - } - if (entry.tag == hwcap_type) { - result = entry.value; - break; - } - } - CpuFeatures_CloseFile(fd); - return result; -} - -// Retrieves hardware capabilities by first trying to call getauxval, if not -// available falls back to reading "/proc/self/auxv". -static unsigned long GetHardwareCapabilitiesFor(uint32_t type) { - unsigned long hwcaps = GetElfHwcapFromGetauxval(type); - if (!hwcaps) { - D("Parsing /proc/self/auxv to extract ELF hwcaps!\n"); - hwcaps = GetElfHwcapFromProcSelfAuxv(type); - } - return hwcaps; -} - -HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) { - HardwareCapabilities capabilities; - capabilities.hwcaps = GetHardwareCapabilitiesFor(AT_HWCAP); - capabilities.hwcaps2 = GetHardwareCapabilitiesFor(AT_HWCAP2); - return capabilities; -} - -PlatformType kEmptyPlatformType; - -PlatformType CpuFeatures_GetPlatformType(void) { - PlatformType type = kEmptyPlatformType; - char *platform = (char *)GetHardwareCapabilitiesFor(AT_PLATFORM); - char *base_platform = (char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM); - - if (platform != NULL) - CpuFeatures_StringView_CopyString(str(platform), type.platform, - sizeof(type.platform)); - if (base_platform != NULL) - CpuFeatures_StringView_CopyString(str(base_platform), type.base_platform, - sizeof(type.base_platform)); - return type; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c b/cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c deleted file mode 100644 index b2c48ba6df30..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/stack_line_reader.c +++ /dev/null @@ -1,131 +0,0 @@ -// 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. - -#include "internal/stack_line_reader.h" -#include "internal/filesystem.h" - -#include -#include -#include - -void StackLineReader_Initialize(StackLineReader* reader, int fd) { - reader->view.ptr = reader->buffer; - reader->view.size = 0; - reader->skip_mode = false; - reader->fd = fd; -} - -// Replaces the content of buffer with bytes from the file. -static int LoadFullBuffer(StackLineReader* reader) { - const int read = CpuFeatures_ReadFile(reader->fd, reader->buffer, - STACK_LINE_READER_BUFFER_SIZE); - assert(read >= 0); - reader->view.ptr = reader->buffer; - reader->view.size = read; - return read; -} - -// Appends with bytes from the file to buffer, filling the remaining space. -static int LoadMore(StackLineReader* reader) { - char* const ptr = reader->buffer + reader->view.size; - const size_t size_to_read = STACK_LINE_READER_BUFFER_SIZE - reader->view.size; - const int read = CpuFeatures_ReadFile(reader->fd, ptr, size_to_read); - assert(read >= 0); - assert(read <= (int)size_to_read); - reader->view.size += read; - return read; -} - -static int IndexOfEol(StackLineReader* reader) { - return CpuFeatures_StringView_IndexOfChar(reader->view, '\n'); -} - -// Relocate buffer's pending bytes at the beginning of the array and fills the -// remaining space with bytes from the file. -static int BringToFrontAndLoadMore(StackLineReader* reader) { - if (reader->view.size && reader->view.ptr != reader->buffer) { - memmove(reader->buffer, reader->view.ptr, reader->view.size); - } - reader->view.ptr = reader->buffer; - return LoadMore(reader); -} - -// Loads chunks of buffer size from disks until it contains a newline character -// or end of file. -static void SkipToNextLine(StackLineReader* reader) { - for (;;) { - const int read = LoadFullBuffer(reader); - if (read == 0) { - break; - } else { - const int eol_index = IndexOfEol(reader); - if (eol_index >= 0) { - reader->view = - CpuFeatures_StringView_PopFront(reader->view, eol_index + 1); - break; - } - } - } -} - -static LineResult CreateLineResult(bool eof, bool full_line, StringView view) { - LineResult result; - result.eof = eof; - result.full_line = full_line; - result.line = view; - return result; -} - -// Helper methods to provide clearer semantic in StackLineReader_NextLine. -static LineResult CreateEOFLineResult(StringView view) { - return CreateLineResult(true, true, view); -} - -static LineResult CreateTruncatedLineResult(StringView view) { - return CreateLineResult(false, false, view); -} - -static LineResult CreateValidLineResult(StringView view) { - return CreateLineResult(false, true, view); -} - -LineResult StackLineReader_NextLine(StackLineReader* reader) { - if (reader->skip_mode) { - SkipToNextLine(reader); - reader->skip_mode = false; - } - { - const bool can_load_more = - reader->view.size < STACK_LINE_READER_BUFFER_SIZE; - int eol_index = IndexOfEol(reader); - if (eol_index < 0 && can_load_more) { - const int read = BringToFrontAndLoadMore(reader); - if (read == 0) { - return CreateEOFLineResult(reader->view); - } - eol_index = IndexOfEol(reader); - } - if (eol_index < 0) { - reader->skip_mode = true; - return CreateTruncatedLineResult(reader->view); - } - { - StringView line = - CpuFeatures_StringView_KeepFront(reader->view, eol_index); - reader->view = - CpuFeatures_StringView_PopFront(reader->view, eol_index + 1); - return CreateValidLineResult(line); - } - } -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/string_view.c b/cpp/src/arrow/vendored/cpu_features/src/string_view.c deleted file mode 100644 index 856731c3470c..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/string_view.c +++ /dev/null @@ -1,182 +0,0 @@ -// 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. - -#include "internal/string_view.h" - -#include -#include -#include - -int CpuFeatures_StringView_IndexOfChar(const StringView view, char c) { - if (view.ptr && view.size) { - const char* const found = (const char*)memchr(view.ptr, c, view.size); - if (found) { - return (int)(found - view.ptr); - } - } - return -1; -} - -int CpuFeatures_StringView_IndexOf(const StringView view, - const StringView sub_view) { - if (sub_view.size) { - StringView remainder = view; - while (remainder.size >= sub_view.size) { - const int found_index = - CpuFeatures_StringView_IndexOfChar(remainder, sub_view.ptr[0]); - if (found_index < 0) break; - remainder = CpuFeatures_StringView_PopFront(remainder, found_index); - if (CpuFeatures_StringView_StartsWith(remainder, sub_view)) { - return (int)(remainder.ptr - view.ptr); - } - remainder = CpuFeatures_StringView_PopFront(remainder, 1); - } - } - return -1; -} - -bool CpuFeatures_StringView_IsEquals(const StringView a, const StringView b) { - if (a.size == b.size) { - return a.ptr == b.ptr || memcmp(a.ptr, b.ptr, b.size) == 0; - } - return false; -} - -bool CpuFeatures_StringView_StartsWith(const StringView a, const StringView b) { - return a.ptr && b.ptr && b.size && a.size >= b.size - ? memcmp(a.ptr, b.ptr, b.size) == 0 - : false; -} - -StringView CpuFeatures_StringView_PopFront(const StringView str_view, - size_t count) { - if (count > str_view.size) { - return kEmptyStringView; - } - return view(str_view.ptr + count, str_view.size - count); -} - -StringView CpuFeatures_StringView_PopBack(const StringView str_view, - size_t count) { - if (count > str_view.size) { - return kEmptyStringView; - } - return view(str_view.ptr, str_view.size - count); -} - -StringView CpuFeatures_StringView_KeepFront(const StringView str_view, - size_t count) { - return count <= str_view.size ? view(str_view.ptr, count) : str_view; -} - -char CpuFeatures_StringView_Front(const StringView view) { - assert(view.size); - assert(view.ptr); - return view.ptr[0]; -} - -char CpuFeatures_StringView_Back(const StringView view) { - assert(view.size); - return view.ptr[view.size - 1]; -} - -StringView CpuFeatures_StringView_TrimWhitespace(StringView view) { - while (view.size && isspace(CpuFeatures_StringView_Front(view))) - view = CpuFeatures_StringView_PopFront(view, 1); - while (view.size && isspace(CpuFeatures_StringView_Back(view))) - view = CpuFeatures_StringView_PopBack(view, 1); - return view; -} - -static int HexValue(const char c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - return -1; -} - -// Returns -1 if view contains non digits. -static int ParsePositiveNumberWithBase(const StringView view, int base) { - int result = 0; - StringView remainder = view; - for (; remainder.size; - remainder = CpuFeatures_StringView_PopFront(remainder, 1)) { - const int value = HexValue(CpuFeatures_StringView_Front(remainder)); - if (value < 0 || value >= base) return -1; - result = (result * base) + value; - } - return result; -} - -int CpuFeatures_StringView_ParsePositiveNumber(const StringView view) { - if (view.size) { - const StringView hex_prefix = str("0x"); - if (CpuFeatures_StringView_StartsWith(view, hex_prefix)) { - const StringView span_no_prefix = - CpuFeatures_StringView_PopFront(view, hex_prefix.size); - return ParsePositiveNumberWithBase(span_no_prefix, 16); - } - return ParsePositiveNumberWithBase(view, 10); - } - return -1; -} - -void CpuFeatures_StringView_CopyString(const StringView src, char* dst, - size_t dst_size) { - if (dst_size > 0) { - const size_t max_copy_size = dst_size - 1; - const size_t copy_size = - src.size > max_copy_size ? max_copy_size : src.size; - memcpy(dst, src.ptr, copy_size); - dst[copy_size] = '\0'; - } -} - -bool CpuFeatures_StringView_HasWord(const StringView line, - const char* const word_str) { - const StringView word = str(word_str); - StringView remainder = line; - for (;;) { - const int index_of_word = CpuFeatures_StringView_IndexOf(remainder, word); - if (index_of_word < 0) { - return false; - } else { - const StringView before = - CpuFeatures_StringView_KeepFront(line, index_of_word); - const StringView after = - CpuFeatures_StringView_PopFront(line, index_of_word + word.size); - const bool valid_before = - before.size == 0 || CpuFeatures_StringView_Back(before) == ' '; - const bool valid_after = - after.size == 0 || CpuFeatures_StringView_Front(after) == ' '; - if (valid_before && valid_after) return true; - remainder = - CpuFeatures_StringView_PopFront(remainder, index_of_word + word.size); - } - } - return false; -} - -bool CpuFeatures_StringView_GetAttributeKeyValue(const StringView line, - StringView* key, - StringView* value) { - const StringView sep = str(": "); - const int index_of_separator = CpuFeatures_StringView_IndexOf(line, sep); - if (index_of_separator < 0) return false; - *value = CpuFeatures_StringView_TrimWhitespace( - CpuFeatures_StringView_PopFront(line, index_of_separator + sep.size)); - *key = CpuFeatures_StringView_TrimWhitespace( - CpuFeatures_StringView_KeepFront(line, index_of_separator)); - return true; -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c b/cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c deleted file mode 100644 index 1b43a362ac2e..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/unix_features_aggregator.c +++ /dev/null @@ -1,52 +0,0 @@ -// 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. - -#include "internal/unix_features_aggregator.h" -#include "internal/string_view.h" - -void CpuFeatures_SetFromFlags(const size_t configs_size, - const CapabilityConfig* configs, - const StringView flags_line, - void* const features) { - size_t i = 0; - for (; i < configs_size; ++i) { - const CapabilityConfig config = configs[i]; - config.set_bit(features, CpuFeatures_StringView_HasWord( - flags_line, config.proc_cpuinfo_flag)); - } -} - -static bool IsSet(const uint32_t mask, const uint32_t value) { - if (mask == 0) return false; - return (value & mask) == mask; -} - -static bool IsHwCapsSet(const HardwareCapabilities hwcaps_mask, - const HardwareCapabilities hwcaps) { - return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) || - IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2); -} - -void CpuFeatures_OverrideFromHwCaps(const size_t configs_size, - const CapabilityConfig* configs, - const HardwareCapabilities hwcaps, - void* const features) { - size_t i = 0; - for (; i < configs_size; ++i) { - const CapabilityConfig* config = &configs[i]; - if (IsHwCapsSet(config->hwcaps_mask, hwcaps)) { - config->set_bit(features, true); - } - } -} diff --git a/cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c b/cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c deleted file mode 100644 index a9ff82908256..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/src/utils/list_cpu_features.c +++ /dev/null @@ -1,246 +0,0 @@ -// 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. - -#include -#include -#include - -#include "cpu_features_macros.h" - -#if defined(CPU_FEATURES_ARCH_X86) -#include "cpuinfo_x86.h" -#elif defined(CPU_FEATURES_ARCH_ARM) -#include "cpuinfo_arm.h" -#elif defined(CPU_FEATURES_ARCH_AARCH64) -#include "cpuinfo_aarch64.h" -#elif defined(CPU_FEATURES_ARCH_MIPS) -#include "cpuinfo_mips.h" -#elif defined(CPU_FEATURES_ARCH_PPC) -#include "cpuinfo_ppc.h" -#endif - -static void PrintEscapedAscii(const char* str) { - putchar('"'); - for (; str && *str; ++str) { - switch (*str) { - case '\"': - case '\\': - case '/': - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - putchar('\\'); - } - putchar(*str); - } - putchar('"'); -} - -static void PrintVoid(void) {} -static void PrintComma(void) { putchar(','); } -static void PrintLineFeed(void) { putchar('\n'); } -static void PrintOpenBrace(void) { putchar('{'); } -static void PrintCloseBrace(void) { putchar('}'); } -static void PrintOpenBracket(void) { putchar('['); } -static void PrintCloseBracket(void) { putchar(']'); } -static void PrintString(const char* field) { printf("%s", field); } -static void PrintAlignedHeader(const char* field) { printf("%-15s : ", field); } -static void PrintIntValue(int value) { printf("%d", value); } -static void PrintDecHexValue(int value) { - printf("%3d (0x%02X)", value, value); -} -static void PrintJsonHeader(const char* field) { - PrintEscapedAscii(field); - putchar(':'); -} - -typedef struct { - void (*Start)(void); - void (*ArrayStart)(void); - void (*ArraySeparator)(void); - void (*ArrayEnd)(void); - void (*PrintString)(const char* value); - void (*PrintValue)(int value); - void (*EndField)(void); - void (*StartField)(const char* field); - void (*End)(void); -} Printer; - -static Printer getJsonPrinter(void) { - return (Printer){ - .Start = &PrintOpenBrace, - .ArrayStart = &PrintOpenBracket, - .ArraySeparator = &PrintComma, - .ArrayEnd = &PrintCloseBracket, - .PrintString = &PrintEscapedAscii, - .PrintValue = &PrintIntValue, - .EndField = &PrintComma, - .StartField = &PrintJsonHeader, - .End = &PrintCloseBrace, - }; -} - -static Printer getTextPrinter(void) { - return (Printer){ - .Start = &PrintVoid, - .ArrayStart = &PrintVoid, - .ArraySeparator = &PrintComma, - .ArrayEnd = &PrintVoid, - .PrintString = &PrintString, - .PrintValue = &PrintDecHexValue, - .EndField = &PrintLineFeed, - .StartField = &PrintAlignedHeader, - .End = &PrintVoid, - }; -} - -// Prints a named numeric value in both decimal and hexadecimal. -static void PrintN(const Printer p, const char* field, int value) { - p.StartField(field); - p.PrintValue(value); - p.EndField(); -} - -// Prints a named string. -static void PrintS(const Printer p, const char* field, const char* value) { - p.StartField(field); - p.PrintString(value); - p.EndField(); -} - -static int cmp(const void* p1, const void* p2) { - return strcmp(*(const char* const*)p1, *(const char* const*)p2); -} - -#define DEFINE_PRINT_FLAGS(HasFeature, FeatureName, FeatureType, LastEnum) \ - static void PrintFlags(const Printer p, const FeatureType* features) { \ - size_t i; \ - const char* ptrs[LastEnum] = {0}; \ - size_t count = 0; \ - for (i = 0; i < LastEnum; ++i) { \ - if (HasFeature(features, i)) { \ - ptrs[count] = FeatureName(i); \ - ++count; \ - } \ - } \ - qsort(ptrs, count, sizeof(char*), cmp); \ - p.StartField("flags"); \ - p.ArrayStart(); \ - for (i = 0; i < count; ++i) { \ - if (i > 0) p.ArraySeparator(); \ - p.PrintString(ptrs[i]); \ - } \ - p.ArrayEnd(); \ - } - -#if defined(CPU_FEATURES_ARCH_X86) -DEFINE_PRINT_FLAGS(GetX86FeaturesEnumValue, GetX86FeaturesEnumName, X86Features, - X86_LAST_) -#elif defined(CPU_FEATURES_ARCH_ARM) -DEFINE_PRINT_FLAGS(GetArmFeaturesEnumValue, GetArmFeaturesEnumName, ArmFeatures, - ARM_LAST_) -#elif defined(CPU_FEATURES_ARCH_AARCH64) -DEFINE_PRINT_FLAGS(GetAarch64FeaturesEnumValue, GetAarch64FeaturesEnumName, - Aarch64Features, AARCH64_LAST_) -#elif defined(CPU_FEATURES_ARCH_MIPS) -DEFINE_PRINT_FLAGS(GetMipsFeaturesEnumValue, GetMipsFeaturesEnumName, - MipsFeatures, MIPS_LAST_) -#elif defined(CPU_FEATURES_ARCH_PPC) -DEFINE_PRINT_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures, - PPC_LAST_) -#endif - -static void PrintFeatures(const Printer printer) { -#if defined(CPU_FEATURES_ARCH_X86) - char brand_string[49]; - const X86Info info = GetX86Info(); - FillX86BrandString(brand_string); - PrintS(printer, "arch", "x86"); - PrintS(printer, "brand", brand_string); - PrintN(printer, "family", info.family); - PrintN(printer, "model", info.model); - PrintN(printer, "stepping", info.stepping); - PrintS(printer, "uarch", - GetX86MicroarchitectureName(GetX86Microarchitecture(&info))); - PrintFlags(printer, &info.features); -#elif defined(CPU_FEATURES_ARCH_ARM) - const ArmInfo info = GetArmInfo(); - PrintS(printer, "arch", "ARM"); - PrintN(printer, "implementer", info.implementer); - PrintN(printer, "architecture", info.architecture); - PrintN(printer, "variant", info.variant); - PrintN(printer, "part", info.part); - PrintN(printer, "revision", info.revision); - PrintFlags(printer, &info.features); -#elif defined(CPU_FEATURES_ARCH_AARCH64) - const Aarch64Info info = GetAarch64Info(); - PrintS(printer, "arch", "aarch64"); - PrintN(printer, "implementer", info.implementer); - PrintN(printer, "variant", info.variant); - PrintN(printer, "part", info.part); - PrintN(printer, "revision", info.revision); - PrintFlags(printer, &info.features); -#elif defined(CPU_FEATURES_ARCH_MIPS) - (void)&PrintN; // Remove unused function warning. - const MipsInfo info = GetMipsInfo(); - PrintS(printer, "arch", "mips"); - PrintFlags(printer, &info.features); -#elif defined(CPU_FEATURES_ARCH_PPC) - (void)&PrintN; // Remove unused function warning. - const PPCInfo info = GetPPCInfo(); - const PPCPlatformStrings strings = GetPPCPlatformStrings(); - PrintS(printer, "arch", "ppc"); - PrintS(printer, "platform", strings.platform); - PrintS(printer, "model", strings.model); - PrintS(printer, "machine", strings.machine); - PrintS(printer, "cpu", strings.cpu); - PrintS(printer, "instruction set", strings.type.platform); - PrintS(printer, "microarchitecture", strings.type.base_platform); - PrintFlags(printer, &info.features); -#endif -} - -static void showUsage(const char* name) { - printf( - "\n" - "Usage: %s [options]\n" - " Options:\n" - " -h | --help Show help message.\n" - " -j | --json Format output as json instead of plain text.\n" - "\n", - name); -} - -int main(int argc, char** argv) { - Printer printer = getTextPrinter(); - int i = 1; - for (; i < argc; ++i) { - const char* arg = argv[i]; - if (strcmp(arg, "-j") == 0 || strcmp(arg, "--json") == 0) { - printer = getJsonPrinter(); - } else { - showUsage(argv[0]); - if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) - return EXIT_SUCCESS; - return EXIT_FAILURE; - } - } - printer.Start(); - PrintFeatures(printer); - printer.End(); - PrintLineFeed(); - return EXIT_SUCCESS; -} diff --git a/cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt b/cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt deleted file mode 100644 index a744ee98bfee..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/CMakeLists.txt +++ /dev/null @@ -1,92 +0,0 @@ -# -# libraries for tests -# - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) # prefer use of -std11 instead of -gnustd11 - -include_directories(../include) -add_definitions(-DCPU_FEATURES_TEST) - -##------------------------------------------------------------------------------ -add_library(string_view ../src/string_view.c) -##------------------------------------------------------------------------------ -add_library(filesystem_for_testing filesystem_for_testing.cc) -target_compile_definitions(filesystem_for_testing PUBLIC CPU_FEATURES_MOCK_FILESYSTEM) -##------------------------------------------------------------------------------ -add_library(hwcaps_for_testing hwcaps_for_testing.cc) -target_compile_definitions(hwcaps_for_testing PUBLIC CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL) -target_link_libraries(hwcaps_for_testing filesystem_for_testing) -##------------------------------------------------------------------------------ -add_library(stack_line_reader ../src/stack_line_reader.c) -target_compile_definitions(stack_line_reader PUBLIC STACK_LINE_READER_BUFFER_SIZE=1024) -target_link_libraries(stack_line_reader string_view) -##------------------------------------------------------------------------------ -add_library(stack_line_reader_for_test ../src/stack_line_reader.c) -target_compile_definitions(stack_line_reader_for_test PUBLIC STACK_LINE_READER_BUFFER_SIZE=16) -target_link_libraries(stack_line_reader_for_test string_view filesystem_for_testing) -##------------------------------------------------------------------------------ -add_library(all_libraries ../src/stack_line_reader.c ../src/unix_features_aggregator.c) -target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view) - -# -# tests -# -link_libraries(gtest gmock_main) - -## bit_utils_test -add_executable(bit_utils_test bit_utils_test.cc) -target_link_libraries(bit_utils_test) -add_test(NAME bit_utils_test COMMAND bit_utils_test) -##------------------------------------------------------------------------------ -## string_view_test -add_executable(string_view_test string_view_test.cc ../src/string_view.c) -target_link_libraries(string_view_test string_view) -add_test(NAME string_view_test COMMAND string_view_test) -##------------------------------------------------------------------------------ -## stack_line_reader_test -add_executable(stack_line_reader_test stack_line_reader_test.cc) -target_link_libraries(stack_line_reader_test stack_line_reader_for_test) -add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test) -##------------------------------------------------------------------------------ -## unix_features_aggregator_test -add_executable(unix_features_aggregator_test unix_features_aggregator_test.cc) -target_link_libraries(unix_features_aggregator_test all_libraries) -add_test(NAME unix_features_aggregator_test COMMAND unix_features_aggregator_test) -##------------------------------------------------------------------------------ -## cpuinfo_x86_test -if(PROCESSOR_IS_X86) - add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c) - target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86) - target_link_libraries(cpuinfo_x86_test all_libraries) - add_test(NAME cpuinfo_x86_test COMMAND cpuinfo_x86_test) -endif() -##------------------------------------------------------------------------------ -## cpuinfo_arm_test -if(PROCESSOR_IS_ARM) - add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c) - target_link_libraries(cpuinfo_arm_test all_libraries) - add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test) -endif() -##------------------------------------------------------------------------------ -## cpuinfo_aarch64_test -if(PROCESSOR_IS_AARCH64) - add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c) - target_link_libraries(cpuinfo_aarch64_test all_libraries) - add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) -endif() -##------------------------------------------------------------------------------ -## cpuinfo_mips_test -if(PROCESSOR_IS_MIPS) - add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/cpuinfo_mips.c) - target_link_libraries(cpuinfo_mips_test all_libraries) - add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test) -endif() -##------------------------------------------------------------------------------ -## cpuinfo_ppc_test -if(PROCESSOR_IS_POWER) - add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/cpuinfo_ppc.c) - target_link_libraries(cpuinfo_ppc_test all_libraries) - add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test) -endif() diff --git a/cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc b/cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc deleted file mode 100644 index 8937cbc2e617..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/bit_utils_test.cc +++ /dev/null @@ -1,53 +0,0 @@ -// 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. - -#include "internal/bit_utils.h" - -#include "gtest/gtest.h" - -namespace cpu_features { -namespace { - -TEST(UtilsTest, IsBitSet) { - for (size_t bit_set = 0; bit_set < 32; ++bit_set) { - const uint32_t value = 1UL << bit_set; - for (size_t i = 0; i < 32; ++i) { - EXPECT_EQ(IsBitSet(value, i), i == bit_set); - } - } - - // testing 0, all bits should be 0. - for (size_t i = 0; i < 32; ++i) { - EXPECT_FALSE(IsBitSet(0, i)); - } - - // testing ~0, all bits should be 1. - for (size_t i = 0; i < 32; ++i) { - EXPECT_TRUE(IsBitSet(-1, i)); - } -} - -TEST(UtilsTest, ExtractBitRange) { - // Extracting all bits gives the same number. - EXPECT_EQ(ExtractBitRange(123, 31, 0), 123); - // Extracting 1 bit gives parity. - EXPECT_EQ(ExtractBitRange(123, 0, 0), 1); - EXPECT_EQ(ExtractBitRange(122, 0, 0), 0); - - EXPECT_EQ(ExtractBitRange(0xF0, 7, 4), 0xF); - EXPECT_EQ(ExtractBitRange(0x42 << 2, 10, 2), 0x42); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc deleted file mode 100644 index bdb4d17c65e3..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_aarch64_test.cc +++ /dev/null @@ -1,74 +0,0 @@ -// 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. - -#include "cpuinfo_aarch64.h" -#include "filesystem_for_testing.h" -#include "hwcaps_for_testing.h" - -#include "gtest/gtest.h" - -namespace cpu_features { -namespace { - -void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } - -TEST(CpuinfoAarch64Test, FromHardwareCap) { - SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0); - GetEmptyFilesystem(); // disabling /proc/cpuinfo - const auto info = GetAarch64Info(); - EXPECT_TRUE(info.features.fp); - EXPECT_FALSE(info.features.asimd); - EXPECT_TRUE(info.features.aes); - EXPECT_FALSE(info.features.pmull); - EXPECT_FALSE(info.features.sha1); - EXPECT_FALSE(info.features.sha2); - EXPECT_FALSE(info.features.crc32); -} - -TEST(CpuinfoAarch64Test, ARMCortexA53) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(Processor : AArch64 Processor rev 3 (aarch64) -processor : 0 -processor : 1 -processor : 2 -processor : 3 -processor : 4 -processor : 5 -processor : 6 -processor : 7 -Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: AArch64 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 3)"); - const auto info = GetAarch64Info(); - EXPECT_EQ(info.implementer, 0x41); - EXPECT_EQ(info.variant, 0x0); - EXPECT_EQ(info.part, 0xd03); - EXPECT_EQ(info.revision, 3); - - EXPECT_TRUE(info.features.fp); - EXPECT_TRUE(info.features.asimd); - EXPECT_TRUE(info.features.aes); - EXPECT_TRUE(info.features.pmull); - EXPECT_TRUE(info.features.sha1); - EXPECT_TRUE(info.features.sha2); - EXPECT_TRUE(info.features.crc32); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc deleted file mode 100644 index 34c755169d62..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_arm_test.cc +++ /dev/null @@ -1,186 +0,0 @@ -// 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. - -#include "cpuinfo_arm.h" -#include "filesystem_for_testing.h" -#include "hwcaps_for_testing.h" - -#include "gtest/gtest.h" - -namespace cpu_features { -namespace { - -void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } - -TEST(CpuinfoArmTest, FromHardwareCap) { - SetHardwareCapabilities(ARM_HWCAP_NEON, ARM_HWCAP2_AES | ARM_HWCAP2_CRC32); - GetEmptyFilesystem(); // disabling /proc/cpuinfo - const auto info = GetArmInfo(); - EXPECT_TRUE(info.features.vfp); // triggered by vfpv3 - EXPECT_TRUE(info.features.vfpv3); // triggered by neon - EXPECT_TRUE(info.features.neon); - EXPECT_TRUE(info.features.aes); - EXPECT_TRUE(info.features.crc32); - - EXPECT_FALSE(info.features.vfpv4); - EXPECT_FALSE(info.features.iwmmxt); - EXPECT_FALSE(info.features.vfpv3d16); - EXPECT_FALSE(info.features.idiva); - EXPECT_FALSE(info.features.idivt); - EXPECT_FALSE(info.features.pmull); - EXPECT_FALSE(info.features.sha1); - EXPECT_FALSE(info.features.sha2); -} - -TEST(CpuinfoArmTest, ODroidFromCpuInfo) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", R"(processor : 0 -model name : ARMv7 Processor rev 3 (v71) -BogoMIPS : 120.00 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x2 -CPU part : 0xc0f -CPU revision : 3)"); - const auto info = GetArmInfo(); - EXPECT_EQ(info.implementer, 0x41); - EXPECT_EQ(info.variant, 0x2); - EXPECT_EQ(info.part, 0xc0f); - EXPECT_EQ(info.revision, 3); - EXPECT_EQ(info.architecture, 7); - - EXPECT_TRUE(info.features.vfp); - EXPECT_FALSE(info.features.iwmmxt); - EXPECT_TRUE(info.features.neon); - EXPECT_TRUE(info.features.vfpv3); - EXPECT_FALSE(info.features.vfpv3d16); - EXPECT_TRUE(info.features.vfpv4); - EXPECT_TRUE(info.features.idiva); - EXPECT_TRUE(info.features.idivt); - EXPECT_FALSE(info.features.aes); - EXPECT_FALSE(info.features.pmull); - EXPECT_FALSE(info.features.sha1); - EXPECT_FALSE(info.features.sha2); - EXPECT_FALSE(info.features.crc32); -} - -// http://code.google.com/p/android/issues/detail?id=10812 -TEST(CpuinfoArmTest, InvalidArmv7) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(Processor : ARMv6-compatible processor rev 6 (v6l) -BogoMIPS : 199.47 -Features : swp half thumb fastmult vfp edsp java -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xb76 -CPU revision : 6 - -Hardware : SPICA -Revision : 0020 -Serial : 33323613546d00ec )"); - const auto info = GetArmInfo(); - EXPECT_EQ(info.architecture, 6); -} - -// https://crbug.com/341598. -TEST(CpuinfoArmTest, InvalidNeon) { - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(Processor: ARMv7 Processory rev 0 (v71) -processor: 0 -BogoMIPS: 13.50 - -Processor: 1 -BogoMIPS: 13.50 - -Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt -CPU implementer : 0x51 -CPU architecture: 7 -CPU variant: 0x1 -CPU part: 0x04d -CPU revision: 0 - -Hardware: SAMSUNG M2 -Revision: 0010 -Serial: 00001e030000354e)"); - const auto info = GetArmInfo(); - EXPECT_FALSE(info.features.neon); -} - -// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV -// support. -TEST(CpuinfoArmTest, Nexus4_0x510006f2) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(CPU implementer : 0x51 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0x6f -CPU revision : 2)"); - const auto info = GetArmInfo(); - EXPECT_TRUE(info.features.idiva); - EXPECT_TRUE(info.features.idivt); - - EXPECT_EQ(GetArmCpuId(&info), 0x510006f2); -} - -// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV -// support. -TEST(CpuinfoArmTest, Nexus4_0x510006f3) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(CPU implementer : 0x51 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0x6f -CPU revision : 3)"); - const auto info = GetArmInfo(); - EXPECT_TRUE(info.features.idiva); - EXPECT_TRUE(info.features.idivt); - - EXPECT_EQ(GetArmCpuId(&info), 0x510006f3); -} - -// The emulator-specific Android 4.2 kernel fails to report support for the -// 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual -// CPU implemented by the emulator. -TEST(CpuinfoArmTest, EmulatorSpecificIdiv) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(Processor : ARMv7 Processor rev 0 (v7l) -BogoMIPS : 629.14 -Features : swp half thumb fastmult vfp edsp neon vfpv3 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xc08 -CPU revision : 0 - -Hardware : Goldfish -Revision : 0000 -Serial : 0000000000000000)"); - const auto info = GetArmInfo(); - EXPECT_TRUE(info.features.idiva); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc deleted file mode 100644 index fbec04d59311..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_mips_test.cc +++ /dev/null @@ -1,126 +0,0 @@ -// 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. - -#include "cpuinfo_mips.h" -#include "filesystem_for_testing.h" -#include "hwcaps_for_testing.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" - -#include "gtest/gtest.h" - -namespace cpu_features { - -namespace { - -void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } - -TEST(CpuinfoMipsTest, FromHardwareCapBoth) { - SetHardwareCapabilities(MIPS_HWCAP_MSA | MIPS_HWCAP_R6, 0); - GetEmptyFilesystem(); // disabling /proc/cpuinfo - const auto info = GetMipsInfo(); - EXPECT_TRUE(info.features.msa); - EXPECT_FALSE(info.features.eva); - EXPECT_TRUE(info.features.r6); -} - -TEST(CpuinfoMipsTest, FromHardwareCapOnlyOne) { - SetHardwareCapabilities(MIPS_HWCAP_MSA, 0); - GetEmptyFilesystem(); // disabling /proc/cpuinfo - const auto info = GetMipsInfo(); - EXPECT_TRUE(info.features.msa); - EXPECT_FALSE(info.features.eva); -} - -TEST(CpuinfoMipsTest, Ci40) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", R"(system type : IMG Pistachio SoC (B0) -machine : IMG Marduk – Ci40 with cc2520 -processor : 0 -cpu model : MIPS interAptiv (multi) V2.0 FPU V0.0 -BogoMIPS : 363.72 -wait instruction : yes -microsecond timers : yes -tlb_entries : 64 -extra interrupt vector : yes -hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb] -isa : mips1 mips2 mips32r1 mips32r2 -ASEs implemented : mips16 dsp mt eva -shadow register sets : 1 -kscratch registers : 0 -package : 0 -core : 0 -VCED exceptions : not available -VCEI exceptions : not available -VPE : 0 -)"); - const auto info = GetMipsInfo(); - EXPECT_FALSE(info.features.msa); - EXPECT_TRUE(info.features.eva); -} - -TEST(CpuinfoMipsTest, AR7161) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(system type : Atheros AR7161 rev 2 -machine : NETGEAR WNDR3700/WNDR3800/WNDRMAC -processor : 0 -cpu model : MIPS 24Kc V7.4 -BogoMIPS : 452.19 -wait instruction : yes -microsecond timers : yes -tlb_entries : 16 -extra interrupt vector : yes -hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0f98, 0x0f78, 0x0df8] -ASEs implemented : mips16 -shadow register sets : 1 -kscratch registers : 0 -core : 0 -VCED exceptions : not available -VCEI exceptions : not available -)"); - const auto info = GetMipsInfo(); - EXPECT_FALSE(info.features.msa); - EXPECT_FALSE(info.features.eva); -} - -TEST(CpuinfoMipsTest, Goldfish) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", R"(system type : MIPS-Goldfish -Hardware : goldfish -Revison : 1 -processor : 0 -cpu model : MIPS 24Kc V0.0 FPU V0.0 -BogoMIPS : 1042.02 -wait instruction : yes -microsecond timers : yes -tlb_entries : 16 -extra interrupt vector : yes -hardware watchpoint : yes, count: 1, address/irw mask: [0x0ff8] -ASEs implemented : -shadow register sets : 1 -core : 0 -VCED exceptions : not available -VCEI exceptions : not available -)"); - const auto info = GetMipsInfo(); - EXPECT_FALSE(info.features.msa); - EXPECT_FALSE(info.features.eva); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc deleted file mode 100644 index 5d5e79808710..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_ppc_test.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2018 IBM. -// -// 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. - -#include "cpuinfo_ppc.h" -#include "filesystem_for_testing.h" -#include "hwcaps_for_testing.h" -#include "internal/string_view.h" - -#include "gtest/gtest.h" - -namespace cpu_features { -namespace { - -void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } - -TEST(CpustringsPPCTest, FromHardwareCap) { - SetHardwareCapabilities(PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_VSX, - PPC_FEATURE2_ARCH_3_00); - GetEmptyFilesystem(); // disabling /proc/cpuinfo - const auto info = GetPPCInfo(); - EXPECT_TRUE(info.features.fpu); - EXPECT_FALSE(info.features.mmu); - EXPECT_TRUE(info.features.vsx); - EXPECT_TRUE(info.features.arch300); - EXPECT_FALSE(info.features.power4); - EXPECT_FALSE(info.features.altivec); - EXPECT_FALSE(info.features.vcrypto); - EXPECT_FALSE(info.features.htm); -} - -TEST(CpustringsPPCTest, Blade) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(processor : 14 -cpu : POWER7 (architected), altivec supported -clock : 3000.000000MHz -revision : 2.1 (pvr 003f 0201) - -processor : 15 -cpu : POWER7 (architected), altivec supported -clock : 3000.000000MHz -revision : 2.1 (pvr 003f 0201) - -timebase : 512000000 -platform : pSeries -model : IBM,8406-70Y -machine : CHRP IBM,8406-70Y)"); - SetPlatformTypes("power7", "power8"); - const auto strings = GetPPCPlatformStrings(); - ASSERT_STREQ(strings.platform, "pSeries"); - ASSERT_STREQ(strings.model, "IBM,8406-70Y"); - ASSERT_STREQ(strings.machine, "CHRP IBM,8406-70Y"); - ASSERT_STREQ(strings.cpu, "POWER7 (architected), altivec supported"); - ASSERT_STREQ(strings.type.platform, "power7"); - ASSERT_STREQ(strings.type.base_platform, "power8"); -} - -TEST(CpustringsPPCTest, Firestone) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(processor : 126 -cpu : POWER8 (raw), altivec supported -clock : 2061.000000MHz -revision : 2.0 (pvr 004d 0200) - -processor : 127 -cpu : POWER8 (raw), altivec supported -clock : 2061.000000MHz -revision : 2.0 (pvr 004d 0200) - -timebase : 512000000 -platform : PowerNV -model : 8335-GTA -machine : PowerNV 8335-GTA -firmware : OPAL v3)"); - const auto strings = GetPPCPlatformStrings(); - ASSERT_STREQ(strings.platform, "PowerNV"); - ASSERT_STREQ(strings.model, "8335-GTA"); - ASSERT_STREQ(strings.machine, "PowerNV 8335-GTA"); - ASSERT_STREQ(strings.cpu, "POWER8 (raw), altivec supported"); -} - -TEST(CpustringsPPCTest, w8) { - DisableHardwareCapabilities(); - auto& fs = GetEmptyFilesystem(); - fs.CreateFile("/proc/cpuinfo", - R"(processor : 143 -cpu : POWER9, altivec supported -clock : 2300.000000MHz -revision : 2.2 (pvr 004e 1202) - -timebase : 512000000 -platform : PowerNV -model : 0000000000000000 -machine : PowerNV 0000000000000000 -firmware : OPAL -MMU : Radix)"); - const auto strings = GetPPCPlatformStrings(); - ASSERT_STREQ(strings.platform, "PowerNV"); - ASSERT_STREQ(strings.model, "0000000000000000"); - ASSERT_STREQ(strings.machine, "PowerNV 0000000000000000"); - ASSERT_STREQ(strings.cpu, "POWER9, altivec supported"); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc b/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc deleted file mode 100644 index 2389de9ab548..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/cpuinfo_x86_test.cc +++ /dev/null @@ -1,176 +0,0 @@ -// 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. - -#include -#include -#include - -#include "gtest/gtest.h" - -#include "cpuinfo_x86.h" -#include "internal/cpuid_x86.h" - -namespace cpu_features { - -class FakeCpu { - public: - Leaf CpuId(uint32_t leaf_id) const { - const auto itr = cpuid_leaves_.find(leaf_id); - EXPECT_TRUE(itr != cpuid_leaves_.end()) << "Missing leaf " << leaf_id; - return itr->second; - } - - uint32_t GetXCR0Eax() const { return xcr0_eax_; } - - void SetLeaves(std::map configuration) { - cpuid_leaves_ = std::move(configuration); - } - - void SetOsBackupsExtendedRegisters(bool os_backups_extended_registers) { - xcr0_eax_ = os_backups_extended_registers ? -1 : 0; - } - - private: - std::map cpuid_leaves_; - uint32_t xcr0_eax_; -}; - -auto* g_fake_cpu = new FakeCpu(); - -extern "C" Leaf CpuId(uint32_t leaf_id) { return g_fake_cpu->CpuId(leaf_id); } -extern "C" uint32_t GetXCR0Eax(void) { return g_fake_cpu->GetXCR0Eax(); } - -namespace { - -TEST(CpuidX86Test, SandyBridge) { - g_fake_cpu->SetOsBackupsExtendedRegisters(true); - g_fake_cpu->SetLeaves({ - {0x00000000, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, - {0x00000001, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}}, - {0x00000007, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, - }); - const auto info = GetX86Info(); - EXPECT_STREQ(info.vendor, "GenuineIntel"); - EXPECT_EQ(info.family, 0x06); - EXPECT_EQ(info.model, 0x02A); - EXPECT_EQ(info.stepping, 0x06); - // Leaf 7 is zeroed out so none of the Leaf 7 flags are set. - const auto features = info.features; - EXPECT_FALSE(features.erms); - EXPECT_FALSE(features.avx2); - EXPECT_FALSE(features.avx512f); - EXPECT_FALSE(features.avx512cd); - EXPECT_FALSE(features.avx512er); - EXPECT_FALSE(features.avx512pf); - EXPECT_FALSE(features.avx512bw); - EXPECT_FALSE(features.avx512dq); - EXPECT_FALSE(features.avx512vl); - EXPECT_FALSE(features.avx512ifma); - EXPECT_FALSE(features.avx512vbmi); - EXPECT_FALSE(features.avx512vbmi2); - EXPECT_FALSE(features.avx512vnni); - EXPECT_FALSE(features.avx512bitalg); - EXPECT_FALSE(features.avx512vpopcntdq); - EXPECT_FALSE(features.avx512_4vnniw); - EXPECT_FALSE(features.avx512_4vbmi2); - // All old cpu features should be set. - EXPECT_TRUE(features.aes); - EXPECT_TRUE(features.ssse3); - EXPECT_TRUE(features.sse4_1); - EXPECT_TRUE(features.sse4_2); - EXPECT_TRUE(features.avx); - EXPECT_FALSE(features.sha); - EXPECT_TRUE(features.popcnt); - EXPECT_FALSE(features.movbe); - EXPECT_FALSE(features.rdrnd); -} - -TEST(CpuidX86Test, SandyBridgeTestOsSupport) { - g_fake_cpu->SetLeaves({ - {0x00000000, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, - {0x00000001, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}}, - {0x00000007, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, - }); - // avx is disabled if os does not support backing up ymm registers. - g_fake_cpu->SetOsBackupsExtendedRegisters(false); - EXPECT_FALSE(GetX86Info().features.avx); - // avx is disabled if os does not support backing up ymm registers. - g_fake_cpu->SetOsBackupsExtendedRegisters(true); - EXPECT_TRUE(GetX86Info().features.avx); -} - -TEST(CpuidX86Test, SkyLake) { - g_fake_cpu->SetOsBackupsExtendedRegisters(true); - g_fake_cpu->SetLeaves({ - {0x00000000, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, - {0x00000001, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, - {0x00000007, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}}, - }); - const auto info = GetX86Info(); - EXPECT_STREQ(info.vendor, "GenuineIntel"); - EXPECT_EQ(info.family, 0x06); - EXPECT_EQ(info.model, 0x04E); - EXPECT_EQ(info.stepping, 0x03); - EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL); -} - -TEST(CpuidX86Test, Branding) { - g_fake_cpu->SetLeaves({ - {0x00000000, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, - {0x00000001, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, - {0x00000007, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}}, - {0x80000000, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}}, - {0x80000001, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}}, - {0x80000002, Leaf{0x65746E49, 0x2952286C, 0x726F4320, 0x4D542865}}, - {0x80000003, Leaf{0x37692029, 0x3035362D, 0x43205530, 0x40205550}}, - {0x80000004, Leaf{0x352E3220, 0x7A484730, 0x00000000, 0x00000000}}, - }); - char brand_string[49]; - FillX86BrandString(brand_string); - EXPECT_STREQ(brand_string, "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz"); -} - -// http://users.atw.hu/instlatx64/AuthenticAMD0630F81_K15_Godavari_CPUID.txt -TEST(CpuidX86Test, AMD_K15) { - g_fake_cpu->SetLeaves({ - {0x00000000, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}}, - {0x00000001, Leaf{0x00630F81, 0x00040800, 0x3E98320B, 0x178BFBFF}}, - {0x00000007, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, - {0x80000000, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}}, - {0x80000001, Leaf{0x00630F81, 0x10000000, 0x0FEBBFFF, 0x2FD3FBFF}}, - {0x80000002, Leaf{0x20444D41, 0x372D3841, 0x4B303736, 0x64615220}}, - {0x80000003, Leaf{0x206E6F65, 0x202C3752, 0x43203031, 0x75706D6F}}, - {0x80000004, Leaf{0x43206574, 0x7365726F, 0x2B433420, 0x00204736}}, - {0x80000005, Leaf{0xFF40FF18, 0xFF40FF30, 0x10040140, 0x60030140}}, - }); - const auto info = GetX86Info(); - - EXPECT_STREQ(info.vendor, "AuthenticAMD"); - EXPECT_EQ(info.family, 0x15); - EXPECT_EQ(info.model, 0x38); - EXPECT_EQ(info.stepping, 0x01); - EXPECT_EQ(GetX86Microarchitecture(&info), - X86Microarchitecture::AMD_BULLDOZER); - - char brand_string[49]; - FillX86BrandString(brand_string); - EXPECT_STREQ(brand_string, "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G "); -} - -// TODO(user): test what happens when xsave/osxsave are not present. -// TODO(user): test what happens when xmm/ymm/zmm os support are not -// present. - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc b/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc deleted file mode 100644 index 4554c1f0a0b4..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.cc +++ /dev/null @@ -1,103 +0,0 @@ -// 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. - -#include "filesystem_for_testing.h" - -#include -#include -#include -#include -#include - -namespace cpu_features { - -FakeFile::FakeFile(int file_descriptor, const char* content) - : file_descriptor_(file_descriptor), content_(content) {} - -FakeFile::~FakeFile() { assert(!opened_); } - -void FakeFile::Open() { - assert(!opened_); - opened_ = true; -} - -void FakeFile::Close() { - assert(opened_); - opened_ = false; -} - -int FakeFile::Read(int fd, void* buf, size_t count) { - assert(count < INT_MAX); - assert(fd == file_descriptor_); - const size_t remainder = content_.size() - head_index_; - const size_t read = count > remainder ? remainder : count; - memcpy(buf, content_.data() + head_index_, read); - head_index_ += read; - assert(read < INT_MAX); - return read; -} - -void FakeFilesystem::Reset() { files_.clear(); } - -FakeFile* FakeFilesystem::CreateFile(const std::string& filename, - const char* content) { - auto& file = files_[filename]; - file = - std::unique_ptr(new FakeFile(next_file_descriptor_++, content)); - return file.get(); -} - -FakeFile* FakeFilesystem::FindFileOrNull(const std::string& filename) const { - const auto itr = files_.find(filename); - return itr == files_.end() ? nullptr : itr->second.get(); -} - -FakeFile* FakeFilesystem::FindFileOrDie(const int file_descriptor) const { - for (const auto& filename_file_pair : files_) { - FakeFile* const file_ptr = filename_file_pair.second.get(); - if (file_ptr->GetFileDescriptor() == file_descriptor) { - return file_ptr; - } - } - assert(false); - return nullptr; -} - -static FakeFilesystem* kFilesystem = new FakeFilesystem(); - -FakeFilesystem& GetEmptyFilesystem() { - kFilesystem->Reset(); - return *kFilesystem; -} - -extern "C" int CpuFeatures_OpenFile(const char* filename) { - auto* const file = kFilesystem->FindFileOrNull(filename); - if (file) { - file->Open(); - return file->GetFileDescriptor(); - } - return -1; -} - -extern "C" void CpuFeatures_CloseFile(int file_descriptor) { - kFilesystem->FindFileOrDie(file_descriptor)->Close(); -} - -extern "C" int CpuFeatures_ReadFile(int file_descriptor, void* buffer, - size_t buffer_size) { - return kFilesystem->FindFileOrDie(file_descriptor) - ->Read(file_descriptor, buffer, buffer_size); -} - -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h b/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h deleted file mode 100644 index ca269e523d9c..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/filesystem_for_testing.h +++ /dev/null @@ -1,61 +0,0 @@ -// 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. - -// Implements a fake filesystem, useful for tests. -#ifndef CPU_FEATURES_TEST_FILESYSTEM_FOR_TESTING_H_ -#define CPU_FEATURES_TEST_FILESYSTEM_FOR_TESTING_H_ - -#include -#include -#include - -#include "internal/filesystem.h" - -namespace cpu_features { - -class FakeFile { - public: - explicit FakeFile(int file_descriptor, const char* content); - ~FakeFile(); - - void Open(); - void Close(); - int Read(int fd, void* buf, size_t count); - - int GetFileDescriptor() const { return file_descriptor_; } - - private: - const int file_descriptor_; - const std::string content_; - bool opened_ = false; - size_t head_index_ = 0; -}; - -class FakeFilesystem { - public: - void Reset(); - FakeFile* CreateFile(const std::string& filename, const char* content); - FakeFile* FindFileOrDie(const int file_descriptor) const; - FakeFile* FindFileOrNull(const std::string& filename) const; - - private: - size_t next_file_descriptor_ = 0; - std::unordered_map> files_; -}; - -FakeFilesystem& GetEmptyFilesystem(); - -} // namespace cpu_features - -#endif // CPU_FEATURES_TEST_FILESYSTEM_FOR_TESTING_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc b/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc deleted file mode 100644 index 07f68e8a3ec3..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.cc +++ /dev/null @@ -1,45 +0,0 @@ -// 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. - -#include - -#include "hwcaps_for_testing.h" -#include "internal/string_view.h" - -namespace cpu_features { - -namespace { -static auto* const g_hardware_capabilities = new HardwareCapabilities(); -static auto* const g_platform_types = new PlatformType(); -} // namespace - -void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2) { - g_hardware_capabilities->hwcaps = hwcaps; - g_hardware_capabilities->hwcaps2 = hwcaps2; -} - -HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void) { - return *g_hardware_capabilities; -} - -void SetPlatformTypes(const char* platform, const char* base_platform) { - CpuFeatures_StringView_CopyString(str(platform), g_platform_types->platform, - sizeof(g_platform_types->platform)); - CpuFeatures_StringView_CopyString(str(base_platform), - g_platform_types->base_platform, - sizeof(g_platform_types->base_platform)); -} - -PlatformType CpuFeatures_GetPlatformType(void) { return *g_platform_types; } -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h b/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h deleted file mode 100644 index 0d0377727718..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/hwcaps_for_testing.h +++ /dev/null @@ -1,27 +0,0 @@ -// 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 CPU_FEATURES_TEST_HWCAPS_FOR_TESTING_H_ -#define CPU_FEATURES_TEST_HWCAPS_FOR_TESTING_H_ - -#include "internal/hwcaps.h" - -namespace cpu_features { - -void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2); -void SetPlatformTypes(const char *platform, const char *base_platform); - -} // namespace cpu_features - -#endif // CPU_FEATURES_TEST_HWCAPS_FOR_TESTING_H_ diff --git a/cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc b/cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc deleted file mode 100644 index c8f9691006a9..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/stack_line_reader_test.cc +++ /dev/null @@ -1,132 +0,0 @@ -// 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. - -#include "internal/stack_line_reader.h" -#include "filesystem_for_testing.h" - -#include "gtest/gtest.h" - -namespace cpu_features { - -bool operator==(const StringView& a, const StringView& b) { - return CpuFeatures_StringView_IsEquals(a, b); -} - -namespace { - -std::string ToString(StringView view) { return {view.ptr, view.size}; } - -TEST(StackLineReaderTest, Empty) { - auto& fs = GetEmptyFilesystem(); - auto* file = fs.CreateFile("/proc/cpuinfo", ""); - StackLineReader reader; - StackLineReader_Initialize(&reader, file->GetFileDescriptor()); - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_TRUE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("")); - } -} - -TEST(StackLineReaderTest, ManySmallLines) { - auto& fs = GetEmptyFilesystem(); - auto* file = fs.CreateFile("/proc/cpuinfo", "a\nb\nc"); - - StackLineReader reader; - StackLineReader_Initialize(&reader, file->GetFileDescriptor()); - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("a")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("b")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_TRUE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("c")); - } -} - -TEST(StackLineReaderTest, TruncatedLine) { - auto& fs = GetEmptyFilesystem(); - auto* file = fs.CreateFile("/proc/cpuinfo", R"(First -Second -More than 16 characters, this will be truncated. -last)"); - - StackLineReader reader; - StackLineReader_Initialize(&reader, file->GetFileDescriptor()); - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("First")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("Second")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_FALSE(result.full_line); - EXPECT_EQ(result.line, str("More than 16 cha")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_TRUE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("last")); - } -} - -TEST(StackLineReaderTest, TruncatedLines) { - auto& fs = GetEmptyFilesystem(); - auto* file = fs.CreateFile("/proc/cpuinfo", R"(More than 16 characters -Another line that is too long)"); - - StackLineReader reader; - StackLineReader_Initialize(&reader, file->GetFileDescriptor()); - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_FALSE(result.full_line); - EXPECT_EQ(result.line, str("More than 16 cha")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_FALSE(result.eof); - EXPECT_FALSE(result.full_line); - EXPECT_EQ(result.line, str("Another line tha")); - } - { - const auto result = StackLineReader_NextLine(&reader); - EXPECT_TRUE(result.eof); - EXPECT_TRUE(result.full_line); - EXPECT_EQ(result.line, str("")); - } -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc b/cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc deleted file mode 100644 index abfcc2cdffcf..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/string_view_test.cc +++ /dev/null @@ -1,144 +0,0 @@ -// 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. - -#include "internal/string_view.h" - -#include "gtest/gtest.h" - -namespace cpu_features { - -bool operator==(const StringView& a, const StringView& b) { - return CpuFeatures_StringView_IsEquals(a, b); -} - -namespace { - -TEST(StringViewTest, Empty) { - EXPECT_EQ(kEmptyStringView.ptr, nullptr); - EXPECT_EQ(kEmptyStringView.size, 0); -} - -TEST(StringViewTest, Build) { - const auto view = str("test"); - EXPECT_EQ(view.ptr[0], 't'); - EXPECT_EQ(view.size, 4); -} - -TEST(StringViewTest, CpuFeatures_StringView_IndexOfChar) { - // Found. - EXPECT_EQ(CpuFeatures_StringView_IndexOfChar(str("test"), 'e'), 1); - // Not found. - EXPECT_EQ(CpuFeatures_StringView_IndexOfChar(str("test"), 'z'), -1); - // Empty. - EXPECT_EQ(CpuFeatures_StringView_IndexOfChar(kEmptyStringView, 'z'), -1); -} - -TEST(StringViewTest, CpuFeatures_StringView_IndexOf) { - // Found. - EXPECT_EQ(CpuFeatures_StringView_IndexOf(str("test"), str("es")), 1); - // Not found. - EXPECT_EQ(CpuFeatures_StringView_IndexOf(str("test"), str("aa")), -1); - // Empty. - EXPECT_EQ(CpuFeatures_StringView_IndexOf(kEmptyStringView, str("aa")), -1); - EXPECT_EQ(CpuFeatures_StringView_IndexOf(str("aa"), kEmptyStringView), -1); -} - -TEST(StringViewTest, CpuFeatures_StringView_StartsWith) { - EXPECT_TRUE(CpuFeatures_StringView_StartsWith(str("test"), str("te"))); - EXPECT_FALSE(CpuFeatures_StringView_StartsWith(str("test"), str(""))); - EXPECT_FALSE( - CpuFeatures_StringView_StartsWith(str("test"), kEmptyStringView)); - EXPECT_FALSE( - CpuFeatures_StringView_StartsWith(kEmptyStringView, str("test"))); -} - -TEST(StringViewTest, CpuFeatures_StringView_IsEquals) { - EXPECT_TRUE( - CpuFeatures_StringView_IsEquals(kEmptyStringView, kEmptyStringView)); - EXPECT_TRUE(CpuFeatures_StringView_IsEquals(kEmptyStringView, str(""))); - EXPECT_TRUE(CpuFeatures_StringView_IsEquals(str(""), kEmptyStringView)); - EXPECT_TRUE(CpuFeatures_StringView_IsEquals(str("a"), str("a"))); - EXPECT_FALSE(CpuFeatures_StringView_IsEquals(str("a"), str("b"))); - EXPECT_FALSE(CpuFeatures_StringView_IsEquals(str("a"), kEmptyStringView)); - EXPECT_FALSE(CpuFeatures_StringView_IsEquals(kEmptyStringView, str("a"))); -} - -TEST(StringViewTest, CpuFeatures_StringView_PopFront) { - EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 2), str("st")); - EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 0), str("test")); - EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 4), str("")); - EXPECT_EQ(CpuFeatures_StringView_PopFront(str("test"), 100), str("")); -} - -TEST(StringViewTest, CpuFeatures_StringView_ParsePositiveNumber) { - EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("42")), 42); - EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2a")), 42); - EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2A")), 42); - - EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("-0x2A")), -1); - EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("abc")), -1); - EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("")), -1); -} - -TEST(StringViewTest, CpuFeatures_StringView_CopyString) { - char buf[4]; - buf[0] = 'X'; - - // Empty - CpuFeatures_StringView_CopyString(str(""), buf, sizeof(buf)); - EXPECT_STREQ(buf, ""); - - // Less - CpuFeatures_StringView_CopyString(str("a"), buf, sizeof(buf)); - EXPECT_STREQ(buf, "a"); - - // exact - CpuFeatures_StringView_CopyString(str("abc"), buf, sizeof(buf)); - EXPECT_STREQ(buf, "abc"); - - // More - CpuFeatures_StringView_CopyString(str("abcd"), buf, sizeof(buf)); - EXPECT_STREQ(buf, "abc"); -} - -TEST(StringViewTest, CpuFeatures_StringView_HasWord) { - // Find flags at beginning, middle and end. - EXPECT_TRUE( - CpuFeatures_StringView_HasWord(str("first middle last"), "first")); - EXPECT_TRUE( - CpuFeatures_StringView_HasWord(str("first middle last"), "middle")); - EXPECT_TRUE(CpuFeatures_StringView_HasWord(str("first middle last"), "last")); - // Do not match partial flags - EXPECT_FALSE( - CpuFeatures_StringView_HasWord(str("first middle last"), "irst")); - EXPECT_FALSE(CpuFeatures_StringView_HasWord(str("first middle last"), "mid")); - EXPECT_FALSE(CpuFeatures_StringView_HasWord(str("first middle last"), "las")); -} - -TEST(StringViewTest, CpuFeatures_StringView_GetAttributeKeyValue) { - const StringView line = str(" key : first middle last "); - StringView key, value; - EXPECT_TRUE(CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)); - EXPECT_EQ(key, str("key")); - EXPECT_EQ(value, str("first middle last")); -} - -TEST(StringViewTest, FailingGetAttributeKeyValue) { - const StringView line = str("key first middle last"); - StringView key, value; - EXPECT_FALSE(CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc b/cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc deleted file mode 100644 index dd491f25a2e3..000000000000 --- a/cpp/src/arrow/vendored/cpu_features/test/unix_features_aggregator_test.cc +++ /dev/null @@ -1,95 +0,0 @@ -// 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. - -#include - -#include "internal/unix_features_aggregator.h" - -#include "gtest/gtest.h" - -namespace cpu_features { - -namespace { - -struct Features { - bool a = false; - bool b = false; - bool c = false; -}; - -DECLARE_SETTER(Features, a) -DECLARE_SETTER(Features, b) -DECLARE_SETTER(Features, c) - -class LinuxFeatureAggregatorTest : public testing::Test { - public: - const std::array kConfigs = { - {{{0b0001, 0b0000}, "a", &set_a}, - {{0b0010, 0b0000}, "b", &set_b}, - {{0b0000, 0b1100}, "c", &set_c}}}; -}; - -TEST_F(LinuxFeatureAggregatorTest, FromFlagsEmpty) { - Features features; - CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str(""), - &features); - EXPECT_FALSE(features.a); - EXPECT_FALSE(features.b); - EXPECT_FALSE(features.c); -} - -TEST_F(LinuxFeatureAggregatorTest, FromFlagsAllSet) { - Features features; - CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str("a c b"), - &features); - EXPECT_TRUE(features.a); - EXPECT_TRUE(features.b); - EXPECT_TRUE(features.c); -} - -TEST_F(LinuxFeatureAggregatorTest, FromFlagsOnlyA) { - Features features; - CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str("a"), - &features); - EXPECT_TRUE(features.a); - EXPECT_FALSE(features.b); - EXPECT_FALSE(features.c); -} - -TEST_F(LinuxFeatureAggregatorTest, FromHwcapsNone) { - HardwareCapabilities capability; - capability.hwcaps = 0; // matches none - capability.hwcaps2 = 0; // matches none - Features features; - CpuFeatures_OverrideFromHwCaps(kConfigs.size(), kConfigs.data(), capability, - &features); - EXPECT_FALSE(features.a); - EXPECT_FALSE(features.b); - EXPECT_FALSE(features.c); -} - -TEST_F(LinuxFeatureAggregatorTest, FromHwcapsSet) { - HardwareCapabilities capability; - capability.hwcaps = 0b0010; // matches b but not a - capability.hwcaps2 = 0b1111; // matches c - Features features; - CpuFeatures_OverrideFromHwCaps(kConfigs.size(), kConfigs.data(), capability, - &features); - EXPECT_FALSE(features.a); - EXPECT_TRUE(features.b); - EXPECT_TRUE(features.c); -} - -} // namespace -} // namespace cpu_features diff --git a/cpp/thirdparty/versions.txt b/cpp/thirdparty/versions.txt index d960cb0d0076..d3d5d4aa79bb 100644 --- a/cpp/thirdparty/versions.txt +++ b/cpp/thirdparty/versions.txt @@ -49,6 +49,7 @@ THRIFT_MD5_CHECKSUM=3deebbb4d1ca77dd9c9e009a1ea02183 URIPARSER_VERSION=0.9.2 ZLIB_VERSION=1.2.11 ZSTD_VERSION=v1.4.0 +CPU_FEATURES_VERSION=v0.4.1 # The first field is the name of the environment variable expected by cmake. # This _must_ match what is defined. The second field is the name of the diff --git a/dev/tasks/conda-recipes/arrow-cpp/meta.yaml b/dev/tasks/conda-recipes/arrow-cpp/meta.yaml index 4638980f1287..6083d5ae4f5e 100644 --- a/dev/tasks/conda-recipes/arrow-cpp/meta.yaml +++ b/dev/tasks/conda-recipes/arrow-cpp/meta.yaml @@ -23,6 +23,7 @@ requirements: - boost-cpp - brotli - c-ares + - cpu_features - double-conversion - flatbuffers - gflags @@ -48,6 +49,7 @@ requirements: - boost-cpp - brotli - c-ares + - cpu_features - double-conversion - gflags - glog