From 4b5dfcecac43e14e57f76993f2431bae5f1866f3 Mon Sep 17 00:00:00 2001 From: Klaus Aehlig Date: Wed, 20 Apr 2022 17:33:53 +0200 Subject: Progress reporting: include origins of running actions For a user, an important information is to know which actions are currently running and, more importantly, the target that caused them. To do so, we need a bit of infrastructure. - We have to keep track of begin and end of running actions, as well as the order in which they were started. That has to happen efficiently and in a thread-safe way. - We have to compute and keep the origin map for actions, even if we don't serialize the action graph. --- src/buildtool/progress_reporting/progress.hpp | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/buildtool/progress_reporting/progress.hpp (limited to 'src/buildtool/progress_reporting/progress.hpp') diff --git a/src/buildtool/progress_reporting/progress.hpp b/src/buildtool/progress_reporting/progress.hpp new file mode 100644 index 00000000..5940c880 --- /dev/null +++ b/src/buildtool/progress_reporting/progress.hpp @@ -0,0 +1,71 @@ +#ifndef INCLUDED_SRC_BUILDTOOL_PROGRESS_REPORTING_PROGRESS_HPP +#define INCLUDED_SRC_BUILDTOOL_PROGRESS_REPORTING_PROGRESS_HPP + +#include +#include +#include +#include +#include +#include + +#include "src/buildtool/build_engine/target_map/configured_target.hpp" +#include "src/buildtool/logging/logger.hpp" + +class Progress { + public: + [[nodiscard]] static auto Instance() noexcept -> Progress& { + static Progress instance{}; + return instance; + } + + void Start(const std::string& id) noexcept { + std::unique_lock lock(m_); + ++prio_; + try { + running_.emplace(id, prio_); + } catch (...) { + Logger::Log(LogLevel::Warning, + "Internal error in progress tracking; progress reports " + "might be incorrect."); + } + } + void Stop(const std::string& id) noexcept { + std::unique_lock lock(m_); + running_.erase(id); + } + + auto Sample() -> std::string { + std::unique_lock lock(m_); + std::string result; + uint64_t started = prio_ + 1; + for (auto const& it : running_) { + if (it.second < started) { + result = it.first; + started = it.second; + } + } + return result; + } + + // Return a reference to the origin map. It is the responsibility + // of the caller to ensure that access happens only happens in a + // single-threaded context. + auto OriginMap() -> std::unordered_map< + std::string, + std::vector< + std::pair>>& { + return origin_map_; + } + + private: + uint64_t prio_{}; + std::mutex m_{}; + std::unordered_map running_{}; + std::unordered_map< + std::string, + std::vector< + std::pair>> + origin_map_; +}; + +#endif -- cgit v1.2.3