aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-02-23 14:30:10 +0100
committerGitHub <noreply@github.com>2021-02-23 14:30:10 +0100
commita878c448d84f087ee1dfdde95a51614187aa170c (patch)
tree0265fc3349f3239ef1c27d781799c0c499f859b0 /src
parent35205e2e922952fc0654260a07fc3191c5afc2cc (diff)
parent2de232d2b301b2f0854b9fa715ab085612c85e00 (diff)
Merge pull request #4551 from danieldk/system-features-compute-level
Add x86_64 compute levels as system features
Diffstat (limited to 'src')
-rw-r--r--src/libstore/globals.cc24
-rw-r--r--src/libutil/compute-levels.cc80
-rw-r--r--src/libutil/compute-levels.hh7
-rw-r--r--src/libutil/local.mk4
4 files changed, 106 insertions, 9 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 0531aad9f..df07aee9b 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -3,6 +3,7 @@
#include "archive.hh"
#include "args.hh"
#include "abstract-setting-to-json.hh"
+#include "compute-levels.hh"
#include <algorithm>
#include <map>
@@ -133,24 +134,29 @@ StringSet Settings::getDefaultSystemFeatures()
StringSet Settings::getDefaultExtraPlatforms()
{
+ StringSet extraPlatforms;
+
if (std::string{SYSTEM} == "x86_64-linux" && !isWSL1())
- return StringSet{"i686-linux"};
-#if __APPLE__
+ extraPlatforms.insert("i686-linux");
+
+#if __linux__
+ StringSet levels = computeLevels();
+ for (auto iter = levels.begin(); iter != levels.end(); ++iter)
+ extraPlatforms.insert(*iter + "-linux");
+#elif __APPLE__
// Rosetta 2 emulation layer can run x86_64 binaries on aarch64
// machines. Note that we can’t force processes from executing
// x86_64 in aarch64 environments or vice versa since they can
// always exec with their own binary preferences.
- else if (pathExists("/Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist")) {
+ if (pathExists("/Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist")) {
if (std::string{SYSTEM} == "x86_64-darwin")
- return StringSet{"aarch64-darwin"};
+ extraPlatforms.insert("aarch64-darwin");
else if (std::string{SYSTEM} == "aarch64-darwin")
- return StringSet{"x86_64-darwin"};
- else
- return StringSet{};
+ extraPlatforms.insert("x86_64-darwin");
}
#endif
- else
- return StringSet{};
+
+ return extraPlatforms;
}
bool Settings::isExperimentalFeatureEnabled(const std::string & name)
diff --git a/src/libutil/compute-levels.cc b/src/libutil/compute-levels.cc
new file mode 100644
index 000000000..19eaedfa8
--- /dev/null
+++ b/src/libutil/compute-levels.cc
@@ -0,0 +1,80 @@
+#include "types.hh"
+
+#if HAVE_LIBCPUID
+#include <libcpuid/libcpuid.h>
+#endif
+
+namespace nix {
+
+#if HAVE_LIBCPUID
+
+StringSet computeLevels() {
+ StringSet levels;
+
+ if (!cpuid_present())
+ return levels;
+
+ cpu_raw_data_t raw;
+ cpu_id_t data;
+
+ if (cpuid_get_raw_data(&raw) < 0)
+ return levels;
+
+ if (cpu_identify(&raw, &data) < 0)
+ return levels;
+
+ if (!(data.flags[CPU_FEATURE_CMOV] &&
+ data.flags[CPU_FEATURE_CX8] &&
+ data.flags[CPU_FEATURE_FPU] &&
+ data.flags[CPU_FEATURE_FXSR] &&
+ data.flags[CPU_FEATURE_MMX] &&
+ data.flags[CPU_FEATURE_SSE] &&
+ data.flags[CPU_FEATURE_SSE2]))
+ return levels;
+
+ levels.insert("x86_64-v1");
+
+ if (!(data.flags[CPU_FEATURE_CX16] &&
+ data.flags[CPU_FEATURE_LAHF_LM] &&
+ data.flags[CPU_FEATURE_POPCNT] &&
+ // SSE3
+ data.flags[CPU_FEATURE_PNI] &&
+ data.flags[CPU_FEATURE_SSSE3] &&
+ data.flags[CPU_FEATURE_SSE4_1] &&
+ data.flags[CPU_FEATURE_SSE4_2]))
+ return levels;
+
+ levels.insert("x86_64-v2");
+
+ if (!(data.flags[CPU_FEATURE_AVX] &&
+ data.flags[CPU_FEATURE_AVX2] &&
+ data.flags[CPU_FEATURE_F16C] &&
+ data.flags[CPU_FEATURE_FMA3] &&
+ // LZCNT
+ data.flags[CPU_FEATURE_ABM] &&
+ data.flags[CPU_FEATURE_MOVBE]))
+ return levels;
+
+ levels.insert("x86_64-v3");
+
+ if (!(data.flags[CPU_FEATURE_AVX512F] &&
+ data.flags[CPU_FEATURE_AVX512BW] &&
+ data.flags[CPU_FEATURE_AVX512CD] &&
+ data.flags[CPU_FEATURE_AVX512DQ] &&
+ data.flags[CPU_FEATURE_AVX512VL]))
+ return levels;
+
+ levels.insert("x86_64-v4");
+
+ return levels;
+}
+
+#else
+
+StringSet computeLevels() {
+ return StringSet{};
+}
+
+#endif // HAVE_LIBCPUID
+
+}
diff --git a/src/libutil/compute-levels.hh b/src/libutil/compute-levels.hh
new file mode 100644
index 000000000..8ded295f9
--- /dev/null
+++ b/src/libutil/compute-levels.hh
@@ -0,0 +1,7 @@
+#include "types.hh"
+
+namespace nix {
+
+StringSet computeLevels();
+
+}
diff --git a/src/libutil/local.mk b/src/libutil/local.mk
index ae7eb67ad..5341c58e6 100644
--- a/src/libutil/local.mk
+++ b/src/libutil/local.mk
@@ -7,3 +7,7 @@ libutil_DIR := $(d)
libutil_SOURCES := $(wildcard $(d)/*.cc)
libutil_LDFLAGS = $(LIBLZMA_LIBS) -lbz2 -pthread $(OPENSSL_LIBS) $(LIBBROTLI_LIBS) $(LIBARCHIVE_LIBS) $(BOOST_LDFLAGS) -lboost_context
+
+ifeq ($(HAVE_LIBCPUID), 1)
+ libutil_LDFLAGS += -lcpuid
+endif