summaryrefslogtreecommitdiffstats
path: root/third_party/highway/cmake/FindAtomics.cmake
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/highway/cmake/FindAtomics.cmake56
1 files changed, 56 insertions, 0 deletions
diff --git a/third_party/highway/cmake/FindAtomics.cmake b/third_party/highway/cmake/FindAtomics.cmake
new file mode 100644
index 0000000000..e866b73fac
--- /dev/null
+++ b/third_party/highway/cmake/FindAtomics.cmake
@@ -0,0 +1,56 @@
+# Original issue:
+# * https://gitlab.kitware.com/cmake/cmake/-/issues/23021#note_1098733
+#
+# For reference:
+# * https://gcc.gnu.org/wiki/Atomic/GCCMM
+#
+# riscv64 specific:
+# * https://lists.debian.org/debian-riscv/2022/01/msg00009.html
+#
+# ATOMICS_FOUND - system has c++ atomics
+# ATOMICS_LIBRARIES - libraries needed to use c++ atomics
+
+include(CheckCXXSourceCompiles)
+
+# RISC-V only has 32-bit and 64-bit atomic instructions. GCC is supposed
+# to convert smaller atomics to those larger ones via masking and
+# shifting like LLVM, but it’s a known bug that it does not. This means
+# anything that wants to use atomics on 1-byte or 2-byte types needs
+# -latomic, but not 4-byte or 8-byte (though it does no harm).
+set(atomic_code
+ "
+ #include <atomic>
+ #include <cstdint>
+ std::atomic<uint8_t> n8 (0); // riscv64
+ std::atomic<uint64_t> n64 (0); // armel, mipsel, powerpc
+ int main() {
+ ++n8;
+ ++n64;
+ return 0;
+ }")
+
+# https://gitlab.kitware.com/cmake/cmake/-/issues/24063
+set(CMAKE_CXX_STANDARD 11)
+check_cxx_source_compiles("${atomic_code}" ATOMICS_LOCK_FREE_INSTRUCTIONS)
+
+if(ATOMICS_LOCK_FREE_INSTRUCTIONS)
+ set(ATOMICS_FOUND TRUE)
+ set(ATOMICS_LIBRARIES)
+else()
+ set(CMAKE_REQUIRED_LIBRARIES "-latomic")
+ check_cxx_source_compiles("${atomic_code}" ATOMICS_IN_LIBRARY)
+ set(CMAKE_REQUIRED_LIBRARIES)
+ if(ATOMICS_IN_LIBRARY)
+ set(ATOMICS_LIBRARY atomic)
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Atomics DEFAULT_MSG ATOMICS_LIBRARY)
+ set(ATOMICS_LIBRARIES ${ATOMICS_LIBRARY})
+ unset(ATOMICS_LIBRARY)
+ else()
+ if(Atomics_FIND_REQUIRED)
+ message(FATAL_ERROR "Neither lock free instructions nor -latomic found.")
+ endif()
+ endif()
+endif()
+unset(atomic_code)
+unset(CMAKE_CXX_STANDARD)