[Lldb-commits] [lldb] [lldb] Implement coalescing of disjoint progress events (PR #84854)

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 12 13:11:23 PDT 2024


================
@@ -75,45 +81,86 @@ void Progress::ReportProgress() {
   }
 }
 
-ProgressManager::ProgressManager() : m_progress_category_map() {}
+ProgressManager::ProgressManager()
+    : m_alarm(std::chrono::milliseconds(100)), m_entries() {}
 
 ProgressManager::~ProgressManager() {}
 
+void ProgressManager::Initialize() {
+  assert(!InstanceImpl() && "Already initialized.");
+  InstanceImpl().emplace();
+}
+
+void ProgressManager::Terminate() {
+  assert(InstanceImpl() && "Already terminated.");
+  InstanceImpl().reset();
+}
+
+bool ProgressManager::Enabled() { return InstanceImpl().operator bool(); }
+
 ProgressManager &ProgressManager::Instance() {
-  static std::once_flag g_once_flag;
-  static ProgressManager *g_progress_manager = nullptr;
-  std::call_once(g_once_flag, []() {
-    // NOTE: known leak to avoid global destructor chain issues.
-    g_progress_manager = new ProgressManager();
-  });
-  return *g_progress_manager;
+  assert(InstanceImpl() && "ProgressManager must be initialized");
+  return *InstanceImpl();
+}
+
+std::optional<ProgressManager> &ProgressManager::InstanceImpl() {
+  static std::optional<ProgressManager> g_progress_manager;
+  return g_progress_manager;
 }
 
 void ProgressManager::Increment(const Progress::ProgressData &progress_data) {
-  std::lock_guard<std::mutex> lock(m_progress_map_mutex);
-  // If the current category exists in the map then it is not an initial report,
-  // therefore don't broadcast to the category bit. Also, store the current
-  // progress data in the map so that we have a note of the ID used for the
-  // initial progress report.
-  if (!m_progress_category_map.contains(progress_data.title)) {
-    m_progress_category_map[progress_data.title].second = progress_data;
+  std::lock_guard<std::mutex> lock(m_entries_mutex);
+  llvm::StringRef key = progress_data.title;
+
+  // This is a new progress event.
+  if (!m_entries.contains(key)) {
     ReportProgress(progress_data, EventType::Begin);
+    Entry &entry = m_entries[key];
+    entry.data = progress_data;
+    entry.refcount = 1;
+    return;
+  }
+
+  // This is an existing progress event.
+  Entry &entry = m_entries[key];
----------------
clayborg wrote:

Since we are always calling `m_entries[key]` anyway, this code could be a bit simpler:
```
Entry &entry = m_entries[key];
if (entry.refcount == 0) {
  // This is a new progress event.
  entry.data = progress_data;
  entry.refcount = 1;
  return;
}
// This is an existing progress event.
```
I assume that accessing a non existent key in the string map will return an default constructed object right?

https://github.com/llvm/llvm-project/pull/84854


More information about the lldb-commits mailing list