diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-11-18 13:40:59 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2022-11-18 13:40:59 +0100 |
commit | fa68eb367e79297bb1c0451cd92ad18a06edce96 (patch) | |
tree | fb466b3f1fe55c0db748075232022aa02e6a51c6 /src/libstore/cgroup.cc | |
parent | 20f66c6889aa9d907feee4946702d655b6bd796f (diff) |
Get CPU stats from the cgroup
Diffstat (limited to 'src/libstore/cgroup.cc')
-rw-r--r-- | src/libstore/cgroup.cc | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/libstore/cgroup.cc b/src/libstore/cgroup.cc index 56e980be3..2a485f0f9 100644 --- a/src/libstore/cgroup.cc +++ b/src/libstore/cgroup.cc @@ -31,13 +31,16 @@ std::map<std::string, std::string> getCgroups(const Path & cgroupFile) return cgroups; } -void destroyCgroup(const Path & cgroup) +static CgroupStats destroyCgroup(const Path & cgroup, bool returnStats) { - if (!pathExists(cgroup)) return; + if (!pathExists(cgroup)) return {}; + + if (!pathExists(cgroup + "/cgroup.procs")) + throw Error("'%s' is not a cgroup", cgroup); for (auto & entry : readDirectory(cgroup)) { if (entry.type != DT_DIR) continue; - destroyCgroup(cgroup + "/" + entry.name); + destroyCgroup(cgroup + "/" + entry.name, false); } int round = 1; @@ -79,8 +82,38 @@ void destroyCgroup(const Path & cgroup) round++; } + CgroupStats stats; + + if (returnStats) { + auto cpustatPath = cgroup + "/cpu.stat"; + + if (pathExists(cpustatPath)) { + for (auto & line : tokenizeString<std::vector<std::string>>(readFile(cpustatPath), "\n")) { + std::string_view userPrefix = "user_usec "; + if (hasPrefix(line, userPrefix)) { + auto n = string2Int<uint64_t>(line.substr(userPrefix.size())); + if (n) stats.cpuUser = std::chrono::microseconds(*n); + } + + std::string_view systemPrefix = "system_usec "; + if (hasPrefix(line, systemPrefix)) { + auto n = string2Int<uint64_t>(line.substr(systemPrefix.size())); + if (n) stats.cpuSystem = std::chrono::microseconds(*n); + } + } + } + + } + if (rmdir(cgroup.c_str()) == -1) throw SysError("deleting cgroup '%s'", cgroup); + + return stats; +} + +CgroupStats destroyCgroup(const Path & cgroup) +{ + return destroyCgroup(cgroup, true); } } |