forked from lix-project/lix
Merge pull request #8895 from hercules-ci/gc-before-stats
eval: Run a full GC before printing stats
(cherry picked from commit aeea49609be014b1928c95b7ec28dbedeb4f032a)
Change-Id: I47a23d3a7a47ea61d9a2b5727b638f879f3aaf1e
This commit is contained in:
parent
fd1299cef3
commit
6feba52008
6 changed files with 141 additions and 99 deletions
|
@ -98,7 +98,7 @@ EvalCommand::EvalCommand()
|
|||
EvalCommand::~EvalCommand()
|
||||
{
|
||||
if (evalState)
|
||||
evalState->printStats();
|
||||
evalState->maybePrintStats();
|
||||
}
|
||||
|
||||
ref<Store> EvalCommand::getEvalStore()
|
||||
|
|
|
@ -2477,10 +2477,37 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
|||
}
|
||||
}
|
||||
|
||||
void EvalState::printStats()
|
||||
bool EvalState::fullGC() {
|
||||
#if HAVE_BOEHMGC
|
||||
GC_gcollect();
|
||||
// Check that it ran. We might replace this with a version that uses more
|
||||
// of the boehm API to get this reliably, at a maintenance cost.
|
||||
// We use a 1K margin because technically this has a race condtion, but we
|
||||
// probably won't encounter it in practice, because the CLI isn't concurrent
|
||||
// like that.
|
||||
return GC_get_bytes_since_gc() < 1024;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void EvalState::maybePrintStats()
|
||||
{
|
||||
bool showStats = getEnv("NIX_SHOW_STATS").value_or("0") != "0";
|
||||
|
||||
if (showStats) {
|
||||
// Make the final heap size more deterministic.
|
||||
#if HAVE_BOEHMGC
|
||||
if (!fullGC()) {
|
||||
warn("failed to perform a full GC before reporting stats");
|
||||
}
|
||||
#endif
|
||||
printStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
void EvalState::printStatistics()
|
||||
{
|
||||
struct rusage buf;
|
||||
getrusage(RUSAGE_SELF, &buf);
|
||||
float cpuTime = buf.ru_utime.tv_sec + ((float) buf.ru_utime.tv_usec / 1000000);
|
||||
|
@ -2494,7 +2521,7 @@ void EvalState::printStats()
|
|||
GC_word heapSize, totalBytes;
|
||||
GC_get_heap_usage_safe(&heapSize, 0, 0, 0, &totalBytes);
|
||||
#endif
|
||||
if (showStats) {
|
||||
|
||||
auto outPath = getEnv("NIX_SHOW_STATS_PATH").value_or("-");
|
||||
std::fstream fs;
|
||||
if (outPath != "-")
|
||||
|
@ -2594,7 +2621,6 @@ void EvalState::printStats()
|
|||
fs << topObj.dump(2) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ExternalValueBase::coerceToString(const Pos & pos, NixStringContext & context, bool copyMore, bool copyToStore) const
|
||||
|
|
|
@ -709,9 +709,25 @@ public:
|
|||
void concatLists(Value & v, size_t nrLists, Value * * lists, const PosIdx pos, std::string_view errorCtx);
|
||||
|
||||
/**
|
||||
* Print statistics.
|
||||
* Print statistics, if enabled.
|
||||
*
|
||||
* Performs a full memory GC before printing the statistics, so that the
|
||||
* GC statistics are more accurate.
|
||||
*/
|
||||
void printStats();
|
||||
void maybePrintStats();
|
||||
|
||||
/**
|
||||
* Print statistics, unconditionally, cheaply, without performing a GC first.
|
||||
*/
|
||||
void printStatistics();
|
||||
|
||||
/**
|
||||
* Perform a full memory garbage collection - not incremental.
|
||||
*
|
||||
* @return true if Nix was built with GC and a GC was performed, false if not.
|
||||
* The return value is currently not thread safe - just the return value.
|
||||
*/
|
||||
bool fullGC();
|
||||
|
||||
/**
|
||||
* Realise the given context, and return a mapping from the placeholders
|
||||
|
|
|
@ -344,7 +344,7 @@ static void main_nix_build(int argc, char * * argv)
|
|||
}
|
||||
}
|
||||
|
||||
state->printStats();
|
||||
state->maybePrintStats();
|
||||
|
||||
auto buildPaths = [&](const std::vector<DerivedPath> & paths) {
|
||||
/* Note: we do this even when !printMissing to efficiently
|
||||
|
|
|
@ -1531,7 +1531,7 @@ static int main_nix_env(int argc, char * * argv)
|
|||
|
||||
op(globals, std::move(opFlags), std::move(opArgs));
|
||||
|
||||
globals.state->printStats();
|
||||
globals.state->maybePrintStats();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
|||
evalOnly, outputKind, xmlOutputSourceLocation, e);
|
||||
}
|
||||
|
||||
state->printStats();
|
||||
state->maybePrintStats();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue