Skip to content

Commit 27d8539

Browse files
committed
[lldb][progress] Add progress manager class
Per discussions from llvm#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 llvm#81169 so that a user listening with that bit will receive grouped progress reports.
1 parent ab4a793 commit 27d8539

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

lldb/include/lldb/Core/Progress.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "lldb/Utility/ConstString.h"
1313
#include "lldb/lldb-types.h"
14+
#include "llvm/ADT/StringMap.h"
1415
#include <atomic>
1516
#include <mutex>
1617
#include <optional>
@@ -119,6 +120,32 @@ class Progress {
119120
bool m_complete = false;
120121
};
121122

123+
/// A class used to group progress reports by category. This is done by using a
124+
/// map that maintains a refcount of each category of progress reports that have
125+
/// come in. Keeping track of progress reports this way will be done if a
126+
/// debugger is listening to the eBroadcastBitProgressByCategory broadcast bit.
127+
class ProgressManager {
128+
public:
129+
ProgressManager();
130+
~ProgressManager();
131+
132+
static void Initialize();
133+
static void Terminate();
134+
// Control the refcount of the progress report category as needed
135+
void Increment(std::string);
136+
void Decrement(std::string);
137+
138+
// Public accessor for the class instance
139+
static ProgressManager &Instance();
140+
141+
private:
142+
// Manage the class instance internally using a std::optional
143+
static std::optional<ProgressManager> &InstanceImpl();
144+
145+
llvm::StringMap<uint64_t> m_progress_map;
146+
std::mutex m_progress_map_mutex;
147+
};
148+
122149
} // namespace lldb_private
123150

124151
#endif // LLDB_CORE_PROGRESS_H

lldb/source/Core/Progress.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,47 @@ void Progress::ReportProgress() {
6666
m_debugger_id);
6767
}
6868
}
69+
70+
void ProgressManager::Initialize() {
71+
lldbassert(!InstanceImpl() && "A progress report manager already exists.");
72+
InstanceImpl().emplace();
73+
}
74+
75+
void ProgressManager::Terminate() {
76+
lldbassert(InstanceImpl() &&
77+
"A progress report manager has already been terminated.");
78+
InstanceImpl().reset();
79+
}
80+
81+
std::optional<ProgressManager> &ProgressManager::InstanceImpl() {
82+
static std::optional<ProgressManager> g_progress_manager;
83+
return g_progress_manager;
84+
}
85+
86+
ProgressManager::ProgressManager() : m_progress_map() {}
87+
88+
ProgressManager::~ProgressManager() {}
89+
90+
ProgressManager &ProgressManager::Instance() { return *InstanceImpl(); }
91+
92+
void ProgressManager::Increment(std::string title) {
93+
std::lock_guard<std::mutex> lock(m_progress_map_mutex);
94+
auto pair = m_progress_map.insert(std::pair(title, 1));
95+
96+
// If pair.first is not empty after insertion it means that that
97+
// category was entered for the first time and should not be incremented
98+
if (!pair.first->first().empty())
99+
++pair.first->second;
100+
}
101+
102+
void ProgressManager::Decrement(std::string title) {
103+
std::lock_guard<std::mutex> lock(m_progress_map_mutex);
104+
auto pos = m_progress_map.find(title);
105+
106+
if (pos == m_progress_map.end())
107+
return;
108+
109+
// Remove the category from the map if the refcount reaches 0
110+
if (--pos->second == 0)
111+
m_progress_map.erase(title);
112+
}

0 commit comments

Comments
 (0)