diff --git a/src/metrics.cpp b/src/metrics.cpp index b63fd16ea..f54d6e243 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -17,6 +17,45 @@ #include #include +void AtomicTimer::start() +{ + std::unique_lock lock(mtx); + if (threads < 1) { + start_time = GetTime(); + } + ++threads; +} + +void AtomicTimer::stop() +{ + std::unique_lock lock(mtx); + // Ignore excess calls to stop() + if (threads > 0) { + --threads; + if (threads < 1) { + int64_t time_span = GetTime() - start_time; + total_time += time_span; + } + } +} + +bool AtomicTimer::running() +{ + std::unique_lock lock(mtx); + return threads > 0; +} + +double AtomicTimer::rate(const AtomicCounter& count) +{ + std::unique_lock lock(mtx); + int64_t duration = total_time; + if (threads > 0) { + // Timer is running, so get the latest count + duration += GetTime() - start_time; + } + return duration > 0 ? (double)count.get() / duration : 0; +} + CCriticalSection cs_metrics; boost::synchronized_value nNodeStartTime; diff --git a/src/metrics.h b/src/metrics.h index 57264a7b5..ff1138b99 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -5,6 +5,7 @@ #include "uint256.h" #include +#include #include struct AtomicCounter { @@ -20,11 +21,37 @@ struct AtomicCounter { --value; } - int get(){ + int get() const { return value.load(); } }; +class AtomicTimer { +private: + std::mutex mtx; + uint64_t threads; + int64_t start_time; + int64_t total_time; + +public: + AtomicTimer() : threads(0), start_time(0), total_time(0) {} + + /** + * Starts timing on first call, and counts the number of calls. + */ + void start(); + + /** + * Counts number of calls, and stops timing after it has been called as + * many times as start(). + */ + void stop(); + + bool running(); + + double rate(const AtomicCounter& count); +}; + extern AtomicCounter transactionsValidated; extern AtomicCounter ehSolverRuns; extern AtomicCounter solutionTargetChecks;