https://github.com/chelcassanova created https://github.com/llvm/llvm-project/pull/81319
Per discussions from https://github.com/llvm/llvm-project/pull/81026, it was decided that having a class that manages a map of progress reports would be beneficial in order to categorize them. This class is a part of the overall `Progress` class and utilizes a map that keeps a count of how many times a progress report category has been sent. This would be used with the new debugger broadcast bit added in https://github.com/llvm/llvm-project/pull/81169 so that a user listening with that bit will receive grouped progress reports. >From 27d85391e9e65fc20a8e247b60a1ef6f2f1e40a6 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova <chelsea_cassan...@apple.com> Date: Thu, 8 Feb 2024 15:31:33 -0800 Subject: [PATCH] [lldb][progress] Add progress manager class Per discussions from https://github.com/llvm/llvm-project/pull/81026, it was decided that having a class that manages a map of progress reports would be beneficial in order to categorize them. This class is a part of the overall `Progress` class and utilizes a map that keeps a count of how many times a progress report category has been sent. This would be used with the new debugger broadcast bit added in https://github.com/llvm/llvm-project/pull/81169 so that a user listening with that bit will receive grouped progress reports. --- lldb/include/lldb/Core/Progress.h | 27 +++++++++++++++++++ lldb/source/Core/Progress.cpp | 44 +++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h index 5d882910246054..7ac6881857445f 100644 --- a/lldb/include/lldb/Core/Progress.h +++ b/lldb/include/lldb/Core/Progress.h @@ -11,6 +11,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/lldb-types.h" +#include "llvm/ADT/StringMap.h" #include <atomic> #include <mutex> #include <optional> @@ -119,6 +120,32 @@ class Progress { bool m_complete = false; }; +/// A class used to group progress reports by category. This is done by using a +/// map that maintains a refcount of each category of progress reports that have +/// come in. Keeping track of progress reports this way will be done if a +/// debugger is listening to the eBroadcastBitProgressByCategory broadcast bit. +class ProgressManager { +public: + ProgressManager(); + ~ProgressManager(); + + static void Initialize(); + static void Terminate(); + // Control the refcount of the progress report category as needed + void Increment(std::string); + void Decrement(std::string); + + // Public accessor for the class instance + static ProgressManager &Instance(); + +private: + // Manage the class instance internally using a std::optional + static std::optional<ProgressManager> &InstanceImpl(); + + llvm::StringMap<uint64_t> m_progress_map; + std::mutex m_progress_map_mutex; +}; + } // namespace lldb_private #endif // LLDB_CORE_PROGRESS_H diff --git a/lldb/source/Core/Progress.cpp b/lldb/source/Core/Progress.cpp index 732efbc342b450..4eb1ea7b8cad4d 100644 --- a/lldb/source/Core/Progress.cpp +++ b/lldb/source/Core/Progress.cpp @@ -66,3 +66,47 @@ void Progress::ReportProgress() { m_debugger_id); } } + +void ProgressManager::Initialize() { + lldbassert(!InstanceImpl() && "A progress report manager already exists."); + InstanceImpl().emplace(); +} + +void ProgressManager::Terminate() { + lldbassert(InstanceImpl() && + "A progress report manager has already been terminated."); + InstanceImpl().reset(); +} + +std::optional<ProgressManager> &ProgressManager::InstanceImpl() { + static std::optional<ProgressManager> g_progress_manager; + return g_progress_manager; +} + +ProgressManager::ProgressManager() : m_progress_map() {} + +ProgressManager::~ProgressManager() {} + +ProgressManager &ProgressManager::Instance() { return *InstanceImpl(); } + +void ProgressManager::Increment(std::string title) { + std::lock_guard<std::mutex> lock(m_progress_map_mutex); + auto pair = m_progress_map.insert(std::pair(title, 1)); + + // If pair.first is not empty after insertion it means that that + // category was entered for the first time and should not be incremented + if (!pair.first->first().empty()) + ++pair.first->second; +} + +void ProgressManager::Decrement(std::string title) { + std::lock_guard<std::mutex> lock(m_progress_map_mutex); + auto pos = m_progress_map.find(title); + + if (pos == m_progress_map.end()) + return; + + // Remove the category from the map if the refcount reaches 0 + if (--pos->second == 0) + m_progress_map.erase(title); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits