diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-04-20 17:33:53 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-04-25 15:46:01 +0200 |
commit | 4b5dfcecac43e14e57f76993f2431bae5f1866f3 (patch) | |
tree | 9ec4608fc1dd9023a00a595b41a5c70850441553 /src/buildtool/progress_reporting/progress.hpp | |
parent | 830380a20f15c6c6d2f91213279c98de9f7cb399 (diff) | |
download | justbuild-4b5dfcecac43e14e57f76993f2431bae5f1866f3.tar.gz |
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.
Diffstat (limited to 'src/buildtool/progress_reporting/progress.hpp')
-rw-r--r-- | src/buildtool/progress_reporting/progress.hpp | 71 |
1 files changed, 71 insertions, 0 deletions
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 <cstdint> +#include <mutex> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +#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<BuildMaps::Target::ConfiguredTarget, std::size_t>>>& { + return origin_map_; + } + + private: + uint64_t prio_{}; + std::mutex m_{}; + std::unordered_map<std::string, uint64_t> running_{}; + std::unordered_map< + std::string, + std::vector< + std::pair<BuildMaps::Target::ConfiguredTarget, std::size_t>>> + origin_map_; +}; + +#endif |