Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "nix/fetchers/fetch-to-store.hh"
#include "nix/fetchers/tarball.hh"
#include "nix/fetchers/input-cache.hh"
#include "nix/util/current-process.hh"

#include "parser-tab.hh"

Expand All @@ -37,10 +38,6 @@
#include <nlohmann/json.hpp>
#include <boost/container/small_vector.hpp>

#ifndef _WIN32 // TODO use portable implementation
# include <sys/resource.h>
#endif

#include "nix/util/strings-inline.hh"

using json = nlohmann::json;
Expand Down Expand Up @@ -2888,11 +2885,8 @@ void EvalState::maybePrintStats()

void EvalState::printStatistics()
{
#ifndef _WIN32 // TODO use portable implementation
struct rusage buf;
getrusage(RUSAGE_SELF, &buf);
float cpuTime = buf.ru_utime.tv_sec + ((float) buf.ru_utime.tv_usec / 1000000);
#endif
std::chrono::microseconds cpuTimeDuration = getCpuUserTime();
float cpuTime = std::chrono::duration_cast<std::chrono::duration<float>>(cpuTimeDuration).count();

uint64_t bEnvs = nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *);
uint64_t bLists = nrListElems * sizeof(Value *);
Expand All @@ -2914,18 +2908,12 @@ void EvalState::printStatistics()
if (outPath != "-")
fs.open(outPath, std::fstream::out);
json topObj = json::object();
#ifndef _WIN32 // TODO implement
topObj["cpuTime"] = cpuTime;
#endif
topObj["time"] = {
#ifndef _WIN32 // TODO implement
{"cpu", cpuTime},
#endif
#if NIX_USE_BOEHMGC
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
# ifndef _WIN32 // TODO implement
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
# endif
#endif
};
topObj["envs"] = {
Expand Down
6 changes: 6 additions & 0 deletions src/libutil/include/nix/util/current-process.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
///@file

#include <optional>
#include <chrono>

#ifndef _WIN32
# include <sys/resource.h>
Expand All @@ -11,6 +12,11 @@

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 unavailable or if cpu.max is set to "max", return 0.
Expand Down
23 changes: 23 additions & 0 deletions src/libutil/unix/current-process.cc
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions src/libutil/unix/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ config_unix_priv_h = configure_file(
sources += config_unix_priv_h

sources += files(
'current-process.cc',
'environment-variables.cc',
'file-descriptor.cc',
'file-path.cc',
Expand Down
35 changes: 35 additions & 0 deletions src/libutil/windows/current-process.cc
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions src/libutil/windows/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
sources += files(
'current-process.cc',
'environment-variables.cc',
'file-descriptor.cc',
'file-path.cc',
Expand Down
Loading