aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/globals.cc50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 0f2ca4b15..48df839fa 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -11,6 +11,11 @@
#include <dlfcn.h>
#include <sys/utsname.h>
+#if __linux__
+#include <mntent.h>
+#include <cmath>
+#endif
+
#include <nlohmann/json.hpp>
@@ -114,7 +119,50 @@ std::vector<Path> getUserConfigFiles()
unsigned int Settings::getDefaultCores()
{
- return std::max(1U, std::thread::hardware_concurrency());
+ unsigned int concurrency = std::max(1U, std::thread::hardware_concurrency());
+
+ #if __linux__
+ FILE *fp = fopen("/proc/mounts", "r");
+ if (!fp)
+ return concurrency;
+
+ Strings cgPathParts;
+
+ struct mntent *ent;
+ while ((ent = getmntent(fp))) {
+ std::string mountType, mountPath;
+
+ mountType = ent->mnt_type;
+ mountPath = ent->mnt_dir;
+
+ if (mountType == "cgroup2") {
+ cgPathParts.push_back(mountPath);
+ break;
+ }
+ }
+
+ fclose(fp);
+
+ if (cgPathParts.size() > 0 && pathExists("/proc/self/cgroup")) {
+ std::string currentCgroup = readFile("/proc/self/cgroup");
+ Strings cgValues = tokenizeString<Strings>(currentCgroup, ":");
+ cgPathParts.push_back(trim(cgValues.back(), "\n"));
+ cgPathParts.push_back("cpu.max");
+ std::string fullCgPath = canonPath(concatStringsSep("/", cgPathParts));
+
+ if (pathExists(fullCgPath)) {
+ std::string cpuMax = readFile(fullCgPath);
+ std::vector<std::string> cpuMaxParts = tokenizeString<std::vector<std::string>>(cpuMax, " ");
+ std::string quota = cpuMaxParts[0];
+ std::string period = trim(cpuMaxParts[1], "\n");
+
+ if (quota != "max")
+ concurrency = std::ceil(std::stoi(quota) / std::stof(period));
+ }
+ }
+ #endif
+
+ return concurrency;
}
StringSet Settings::getDefaultSystemFeatures()