mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
libutil, libexpr: #10542 abstract over getrusage for getting cpuTime stat and implement windows version
Update src/libutil/windows/current-process.cc Prefer `nullptr` over `NULL` Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo> Update src/libutil/unix/current-process.cc Prefer C++ type casts Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo> Update src/libutil/windows/current-process.cc Prefer C++ type casts Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo> Update src/libutil/unix/current-process.cc Don't allocate exception Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
This commit is contained in:
parent
ffe5c1ecb4
commit
7b8ceb5d2d
6 changed files with 69 additions and 15 deletions
|
|
@ -21,6 +21,7 @@
|
||||||
#include "nix/fetchers/fetch-to-store.hh"
|
#include "nix/fetchers/fetch-to-store.hh"
|
||||||
#include "nix/fetchers/tarball.hh"
|
#include "nix/fetchers/tarball.hh"
|
||||||
#include "nix/fetchers/input-cache.hh"
|
#include "nix/fetchers/input-cache.hh"
|
||||||
|
#include "nix/util/current-process.hh"
|
||||||
|
|
||||||
#include "parser-tab.hh"
|
#include "parser-tab.hh"
|
||||||
|
|
||||||
|
|
@ -37,10 +38,6 @@
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
#ifndef _WIN32 // TODO use portable implementation
|
|
||||||
# include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nix/util/strings-inline.hh"
|
#include "nix/util/strings-inline.hh"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
@ -2888,11 +2885,8 @@ void EvalState::maybePrintStats()
|
||||||
|
|
||||||
void EvalState::printStatistics()
|
void EvalState::printStatistics()
|
||||||
{
|
{
|
||||||
#ifndef _WIN32 // TODO use portable implementation
|
std::chrono::microseconds cpuTimeDuration = getCpuUserTime();
|
||||||
struct rusage buf;
|
float cpuTime = std::chrono::duration_cast<std::chrono::duration<float>>(cpuTimeDuration).count();
|
||||||
getrusage(RUSAGE_SELF, &buf);
|
|
||||||
float cpuTime = buf.ru_utime.tv_sec + ((float) buf.ru_utime.tv_usec / 1000000);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t bEnvs = nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *);
|
uint64_t bEnvs = nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *);
|
||||||
uint64_t bLists = nrListElems * sizeof(Value *);
|
uint64_t bLists = nrListElems * sizeof(Value *);
|
||||||
|
|
@ -2914,18 +2908,12 @@ void EvalState::printStatistics()
|
||||||
if (outPath != "-")
|
if (outPath != "-")
|
||||||
fs.open(outPath, std::fstream::out);
|
fs.open(outPath, std::fstream::out);
|
||||||
json topObj = json::object();
|
json topObj = json::object();
|
||||||
#ifndef _WIN32 // TODO implement
|
|
||||||
topObj["cpuTime"] = cpuTime;
|
topObj["cpuTime"] = cpuTime;
|
||||||
#endif
|
|
||||||
topObj["time"] = {
|
topObj["time"] = {
|
||||||
#ifndef _WIN32 // TODO implement
|
|
||||||
{"cpu", cpuTime},
|
{"cpu", cpuTime},
|
||||||
#endif
|
|
||||||
#if NIX_USE_BOEHMGC
|
#if NIX_USE_BOEHMGC
|
||||||
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
|
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
|
||||||
# ifndef _WIN32 // TODO implement
|
|
||||||
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
|
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
topObj["envs"] = {
|
topObj["envs"] = {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <sys/resource.h>
|
# include <sys/resource.h>
|
||||||
|
|
@ -11,6 +12,11 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current process's user space CPU time.
|
||||||
|
*/
|
||||||
|
std::chrono::microseconds getCpuUserTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If cgroups are active, attempt to calculate the number of CPUs available.
|
* If cgroups are active, attempt to calculate the number of CPUs available.
|
||||||
* If cgroups are unavailable or if cpu.max is set to "max", return 0.
|
* If cgroups are unavailable or if cpu.max is set to "max", return 0.
|
||||||
|
|
|
||||||
23
src/libutil/unix/current-process.cc
Normal file
23
src/libutil/unix/current-process.cc
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "nix/util/current-process.hh"
|
||||||
|
#include "nix/util/error.hh"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
std::chrono::microseconds getCpuUserTime()
|
||||||
|
{
|
||||||
|
struct rusage buf;
|
||||||
|
|
||||||
|
if (getrusage(RUSAGE_SELF, &buf) != 0) {
|
||||||
|
throw SysError("failed to get CPU time");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::seconds seconds(buf.ru_utime.tv_sec);
|
||||||
|
std::chrono::microseconds microseconds(buf.ru_utime.tv_usec);
|
||||||
|
|
||||||
|
return seconds + microseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
|
@ -49,6 +49,7 @@ config_unix_priv_h = configure_file(
|
||||||
sources += config_unix_priv_h
|
sources += config_unix_priv_h
|
||||||
|
|
||||||
sources += files(
|
sources += files(
|
||||||
|
'current-process.cc',
|
||||||
'environment-variables.cc',
|
'environment-variables.cc',
|
||||||
'file-descriptor.cc',
|
'file-descriptor.cc',
|
||||||
'file-path.cc',
|
'file-path.cc',
|
||||||
|
|
|
||||||
35
src/libutil/windows/current-process.cc
Normal file
35
src/libutil/windows/current-process.cc
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include "nix/util/current-process.hh"
|
||||||
|
#include "nix/util/windows-error.hh"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# include <windows.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
std::chrono::microseconds getCpuUserTime()
|
||||||
|
{
|
||||||
|
FILETIME creationTime;
|
||||||
|
FILETIME exitTime;
|
||||||
|
FILETIME kernelTime;
|
||||||
|
FILETIME userTime;
|
||||||
|
|
||||||
|
if (!GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime)) {
|
||||||
|
auto lastError = GetLastError();
|
||||||
|
throw windows::WinError(lastError, "failed to get CPU time");
|
||||||
|
}
|
||||||
|
|
||||||
|
ULARGE_INTEGER uLargeInt;
|
||||||
|
uLargeInt.LowPart = userTime.dwLowDateTime;
|
||||||
|
uLargeInt.HighPart = userTime.dwHighDateTime;
|
||||||
|
|
||||||
|
// FILETIME stores units of 100 nanoseconds.
|
||||||
|
// Dividing by 10 gives microseconds.
|
||||||
|
std::chrono::microseconds microseconds(uLargeInt.QuadPart / 10);
|
||||||
|
|
||||||
|
return microseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
#endif // ifdef _WIN32
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
sources += files(
|
sources += files(
|
||||||
|
'current-process.cc',
|
||||||
'environment-variables.cc',
|
'environment-variables.cc',
|
||||||
'file-descriptor.cc',
|
'file-descriptor.cc',
|
||||||
'file-path.cc',
|
'file-path.cc',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue