[Lldb-commits] [lldb] Add settings and code that limits the number of progress events. (PR #75769)

Chelsea Cassanova via lldb-commits lldb-commits at lists.llvm.org
Tue Jan 9 22:56:12 PST 2024


================
@@ -1430,6 +1445,279 @@ void Debugger::SetDestroyCallback(
   m_destroy_callback_baton = baton;
 }
 
+
+  /// Notify the progress thread that there is new progress data.
+void Debugger::NotifyProgress(std::unique_ptr<ProgressEventData> &data_up) {
+  // Start the progress thread if it isn't already running.
+  if (!m_progress_thread.IsJoinable())
+    StartProgressThread();
+  // Scope to let the lock unlock before calling notify_one() to avoid
+  // the thread waking up an extra time.
+  {
+    std::unique_lock lock(m_progress_mutex);
+    Log *log = GetLog(LLDBLog::Progress);
+    if (log) {
+      if (data_up->GetCompleted() == 0)
+        LLDB_LOG(log, "NotifyProgress id = {1}, title = \"{2}\", type = start",
+                 data_up.get(), data_up->GetID(), data_up->GetTitle(),
+                 data_up->GetDetails());
+      else if (data_up->IsDone())
+        LLDB_LOG(log, "NotifyProgress id = {1}, title = \"{2}\", type = end",
+                 data_up.get(), data_up->GetID(), data_up->GetTitle(),
+                 data_up->GetDetails());
+      else if (data_up->GetDetails().empty())
+        LLDB_LOG(log, "NotifyProgress id = {1}, title = \"{2}\" {3}/{4}",
+                 data_up.get(), data_up->GetID(), data_up->GetTitle(),
+                 data_up->GetCompleted(), data_up->GetTotal());
+      else
+        LLDB_LOG(log, "NotifyProgress id = {1}, title = \"{2}\", "
+                 "detail = \"{3}\" {4}/{5}", data_up.get(), data_up->GetID(),
+                 data_up->GetTitle(), data_up->GetDetails(),
+                 data_up->GetCompleted(), data_up->GetTotal());
+    }
+
+    const uint64_t progress_id = data_up->GetID();
+    auto pos = m_progress_map.find(progress_id);
+    if (pos != m_progress_map.end()) {
+      // We have a progress info tracking this progress already. If we haven't
+      // sent any events yet, then keep the initial progress data as it
+      // signifies the start progress notification which we might send if the
+      // progress doesn't finish too quickly.
+      ProgressInfo &info = pos->second;
+      bool replace_data = false;
+      if (info.last_notification_time) {
+        LLDB_LOG(log, "NotifyProgress id = {0} replace_data = 1 (event sent "
+                 "already)", progress_id);
+        // We have sent an event for this already, always replace the progress
+        // data as this means we already sent a progress start event so we
+        // always want to send the most up to date information.
+        replace_data = true;
+      } else {
+        LLDB_LOG(log, "NotifyProgress id = {0} no event sent yet",
+                 progress_id);
+        // We haven't sent any notifications yet for this progress.
+        if (info.data_up) {
+          // If we are done already, then set the data so we don't send any
+          // events for this progress. But if we aren't done, we need to leave
+          // the original start progress notification in the progress info in
+          // case we send it.
+          replace_data = data_up->IsDone();
+          LLDB_LOG(log, "NotifyProgress id = {0} replace_data = {1} (only "
+                   "true if done)", progress_id, replace_data);
+        } else {
+          // There is no data in the ProgressInfo as it was sent in an event
+          // and the unique pointer was reset, so set the data.
+          LLDB_LOG(log, "NotifyProgress id = {0} replace_data = 1 ("
+                   "ProgressEventData is NULL)", progress_id, replace_data);
+          replace_data = true;
+        }
+      }
+      // Replace the data
+      if (replace_data)
+        pos->second.data_up.reset(data_up.release());
+    } else {
+      m_progress_map.emplace(
+          progress_id,
+          ProgressInfo(data_up.release(), GetProgressMinDuration()));
+    }
+    // Bump the progress update ID so the progress thread can wake up.
+    ++m_progress_update_id;
+  }
+  // After the scoped locker has unlocked the progress mutex, notify the
+  // progress condition variable. This avoids the progress thread from waking up
+  // multuple times.
+  m_progress_condition.notify_one();
+}
+
+lldb::thread_result_t Debugger::ProgressThread() {
----------------
chelcassanova wrote:

Per your suggestion from the RFC this could be combined with a potential `Debugger::eBroadcastBitProgressByCategory` broadcast bit for grouping events by categories while having the original broadcast bit provide the current progress reporting behaviour.

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


More information about the lldb-commits mailing list