Skip to content

Commit 7b8ceb5

Browse files
ethanavatarxokdvium
andcommitted
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 <[email protected]> Update src/libutil/unix/current-process.cc Prefer C++ type casts Co-authored-by: Sergei Zimmerman <[email protected]> Update src/libutil/windows/current-process.cc Prefer C++ type casts Co-authored-by: Sergei Zimmerman <[email protected]> Update src/libutil/unix/current-process.cc Don't allocate exception Co-authored-by: Sergei Zimmerman <[email protected]>
1 parent ffe5c1e commit 7b8ceb5

File tree

6 files changed

+69
-15
lines changed

6 files changed

+69
-15
lines changed

src/libexpr/eval.cc

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "nix/fetchers/fetch-to-store.hh"
2222
#include "nix/fetchers/tarball.hh"
2323
#include "nix/fetchers/input-cache.hh"
24+
#include "nix/util/current-process.hh"
2425

2526
#include "parser-tab.hh"
2627

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

40-
#ifndef _WIN32 // TODO use portable implementation
41-
# include <sys/resource.h>
42-
#endif
43-
4441
#include "nix/util/strings-inline.hh"
4542

4643
using json = nlohmann::json;
@@ -2888,11 +2885,8 @@ void EvalState::maybePrintStats()
28882885

28892886
void EvalState::printStatistics()
28902887
{
2891-
#ifndef _WIN32 // TODO use portable implementation
2892-
struct rusage buf;
2893-
getrusage(RUSAGE_SELF, &buf);
2894-
float cpuTime = buf.ru_utime.tv_sec + ((float) buf.ru_utime.tv_usec / 1000000);
2895-
#endif
2888+
std::chrono::microseconds cpuTimeDuration = getCpuUserTime();
2889+
float cpuTime = std::chrono::duration_cast<std::chrono::duration<float>>(cpuTimeDuration).count();
28962890

28972891
uint64_t bEnvs = nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *);
28982892
uint64_t bLists = nrListElems * sizeof(Value *);
@@ -2914,18 +2908,12 @@ void EvalState::printStatistics()
29142908
if (outPath != "-")
29152909
fs.open(outPath, std::fstream::out);
29162910
json topObj = json::object();
2917-
#ifndef _WIN32 // TODO implement
29182911
topObj["cpuTime"] = cpuTime;
2919-
#endif
29202912
topObj["time"] = {
2921-
#ifndef _WIN32 // TODO implement
29222913
{"cpu", cpuTime},
2923-
#endif
29242914
#if NIX_USE_BOEHMGC
29252915
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
2926-
# ifndef _WIN32 // TODO implement
29272916
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
2928-
# endif
29292917
#endif
29302918
};
29312919
topObj["envs"] = {

src/libutil/include/nix/util/current-process.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
///@file
33

44
#include <optional>
5+
#include <chrono>
56

67
#ifndef _WIN32
78
# include <sys/resource.h>
@@ -11,6 +12,11 @@
1112

1213
namespace nix {
1314

15+
/**
16+
* Get the current process's user space CPU time.
17+
*/
18+
std::chrono::microseconds getCpuUserTime();
19+
1420
/**
1521
* If cgroups are active, attempt to calculate the number of CPUs available.
1622
* If cgroups are unavailable or if cpu.max is set to "max", return 0.

src/libutil/unix/current-process.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "nix/util/current-process.hh"
2+
#include "nix/util/error.hh"
3+
#include <cmath>
4+
5+
#include <sys/resource.h>
6+
7+
namespace nix {
8+
9+
std::chrono::microseconds getCpuUserTime()
10+
{
11+
struct rusage buf;
12+
13+
if (getrusage(RUSAGE_SELF, &buf) != 0) {
14+
throw SysError("failed to get CPU time");
15+
}
16+
17+
std::chrono::seconds seconds(buf.ru_utime.tv_sec);
18+
std::chrono::microseconds microseconds(buf.ru_utime.tv_usec);
19+
20+
return seconds + microseconds;
21+
}
22+
23+
} // namespace nix

src/libutil/unix/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ config_unix_priv_h = configure_file(
4949
sources += config_unix_priv_h
5050

5151
sources += files(
52+
'current-process.cc',
5253
'environment-variables.cc',
5354
'file-descriptor.cc',
5455
'file-path.cc',
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "nix/util/current-process.hh"
2+
#include "nix/util/windows-error.hh"
3+
#include <cmath>
4+
5+
#ifdef _WIN32
6+
# define WIN32_LEAN_AND_MEAN
7+
# include <windows.h>
8+
9+
namespace nix {
10+
11+
std::chrono::microseconds getCpuUserTime()
12+
{
13+
FILETIME creationTime;
14+
FILETIME exitTime;
15+
FILETIME kernelTime;
16+
FILETIME userTime;
17+
18+
if (!GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime)) {
19+
auto lastError = GetLastError();
20+
throw windows::WinError(lastError, "failed to get CPU time");
21+
}
22+
23+
ULARGE_INTEGER uLargeInt;
24+
uLargeInt.LowPart = userTime.dwLowDateTime;
25+
uLargeInt.HighPart = userTime.dwHighDateTime;
26+
27+
// FILETIME stores units of 100 nanoseconds.
28+
// Dividing by 10 gives microseconds.
29+
std::chrono::microseconds microseconds(uLargeInt.QuadPart / 10);
30+
31+
return microseconds;
32+
}
33+
34+
} // namespace nix
35+
#endif // ifdef _WIN32

src/libutil/windows/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
sources += files(
2+
'current-process.cc',
23
'environment-variables.cc',
34
'file-descriptor.cc',
45
'file-path.cc',

0 commit comments

Comments
 (0)