[Lldb-commits] [lldb] 774c226 - [LLDB] Add external progress bit category (#120171)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Jan 6 12:49:18 PST 2025
Author: Jacob Lalonde
Date: 2025-01-06T12:49:15-08:00
New Revision: 774c22686330f3ca43e48a1b8076eb30ae03dbd8
URL: https://github.com/llvm/llvm-project/commit/774c22686330f3ca43e48a1b8076eb30ae03dbd8
DIFF: https://github.com/llvm/llvm-project/commit/774c22686330f3ca43e48a1b8076eb30ae03dbd8.diff
LOG: [LLDB] Add external progress bit category (#120171)
As feedback on #119052, it was recommended I add a new bit to delineate
internal and external progress events. This patch adds this new
category, and sets up Progress.h to support external events via
SBProgress.
Added:
Modified:
lldb/include/lldb/Core/Progress.h
lldb/include/lldb/lldb-enumerations.h
lldb/source/Core/Progress.cpp
lldb/unittests/Core/ProgressReportTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h
index f6cea282842e1c..5876eae717e96f 100644
--- a/lldb/include/lldb/Core/Progress.h
+++ b/lldb/include/lldb/Core/Progress.h
@@ -59,6 +59,12 @@ namespace lldb_private {
class Progress {
public:
+ /// Enum to indicate the origin of a progress event, internal or external.
+ enum class Origin : uint8_t {
+ eInternal = 0,
+ eExternal = 1,
+ };
+
/// Construct a progress object that will report information.
///
/// The constructor will create a unique progress reporting object and
@@ -83,7 +89,8 @@ class Progress {
Progress(std::string title, std::string details = {},
std::optional<uint64_t> total = std::nullopt,
lldb_private::Debugger *debugger = nullptr,
- Timeout<std::nano> minimum_report_time = std::nullopt);
+ Timeout<std::nano> minimum_report_time = std::nullopt,
+ Origin origin = Origin::eInternal);
/// Destroy the progress object.
///
@@ -118,6 +125,9 @@ class Progress {
/// The optional debugger ID to report progress to. If this has no value
/// then all debuggers will receive this event.
std::optional<lldb::user_id_t> debugger_id;
+
+ /// The origin of the progress event, wheter it is internal or external.
+ Origin origin;
};
private:
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 0094fcd596fdf7..50d2233509de6f 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -1357,6 +1357,8 @@ enum DebuggerBroadcastBit {
eBroadcastBitError = (1 << 2),
eBroadcastSymbolChange = (1 << 3),
eBroadcastBitProgressCategory = (1 << 4),
+ eBroadcastBitExternalProgress = (1 << 5),
+ eBroadcastBitExternalProgressCategory = (1 << 6),
};
/// Used for expressing severity in logs and diagnostics.
diff --git a/lldb/source/Core/Progress.cpp b/lldb/source/Core/Progress.cpp
index ed8dfb85639b71..63f98043208094 100644
--- a/lldb/source/Core/Progress.cpp
+++ b/lldb/source/Core/Progress.cpp
@@ -28,12 +28,14 @@ static llvm::ManagedStatic<llvm::SignpostEmitter> g_progress_signposts;
Progress::Progress(std::string title, std::string details,
std::optional<uint64_t> total,
lldb_private::Debugger *debugger,
- Timeout<std::nano> minimum_report_time)
+ Timeout<std::nano> minimum_report_time,
+ Progress::Origin origin)
: m_total(total.value_or(Progress::kNonDeterministicTotal)),
m_minimum_report_time(minimum_report_time),
m_progress_data{title, ++g_id,
debugger ? std::optional<user_id_t>(debugger->GetID())
- : std::nullopt},
+ : std::nullopt,
+ origin},
m_last_report_time_ns(
std::chrono::nanoseconds(
std::chrono::steady_clock::now().time_since_epoch())
@@ -106,9 +108,15 @@ void Progress::ReportProgress() {
if (completed < m_prev_completed)
return; // An overflow in the m_completed counter. Just ignore these events.
+ // Change the category bit if we're an internal or external progress.
+ uint32_t progress_category_bit =
+ m_progress_data.origin == Progress::Origin::eExternal
+ ? lldb::eBroadcastBitExternalProgress
+ : lldb::eBroadcastBitProgress;
+
Debugger::ReportProgress(m_progress_data.progress_id, m_progress_data.title,
m_details, completed, m_total,
- m_progress_data.debugger_id);
+ m_progress_data.debugger_id, progress_category_bit);
m_prev_completed = completed;
}
@@ -201,10 +209,13 @@ void ProgressManager::ReportProgress(
// broadcasting to it since that bit doesn't need that information.
const uint64_t completed =
(type == EventType::Begin) ? 0 : Progress::kNonDeterministicTotal;
+ const uint32_t progress_category_bit =
+ progress_data.origin == Progress::Origin::eExternal
+ ? lldb::eBroadcastBitExternalProgressCategory
+ : lldb::eBroadcastBitProgressCategory;
Debugger::ReportProgress(progress_data.progress_id, progress_data.title, "",
completed, Progress::kNonDeterministicTotal,
- progress_data.debugger_id,
- lldb::eBroadcastBitProgressCategory);
+ progress_data.debugger_id, progress_category_bit);
}
void ProgressManager::Expire(llvm::StringRef key) {
diff --git a/lldb/unittests/Core/ProgressReportTest.cpp b/lldb/unittests/Core/ProgressReportTest.cpp
index 20324e92523874..0943d7b990809a 100644
--- a/lldb/unittests/Core/ProgressReportTest.cpp
+++ b/lldb/unittests/Core/ProgressReportTest.cpp
@@ -425,3 +425,104 @@ TEST_F(ProgressReportTest, TestProgressManagerDisjointReports) {
ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
}
+
+TEST_F(ProgressReportTest, TestExternalReportCreation) {
+ ListenerSP listener_sp =
+ CreateListenerFor(lldb::eBroadcastBitExternalProgress);
+ EventSP event_sp;
+ const ProgressEventData *data;
+
+ // Scope this for RAII on the progress objects.
+ // Create progress reports and check that their respective events for having
+ // started and ended are broadcasted.
+ {
+ Progress progress1("Progress report 1", "Starting report 1",
+ /*total=*/std::nullopt, /*debugger=*/nullptr,
+ /*minimum_report_time=*/std::chrono::seconds(0),
+ Progress::Origin::eExternal);
+ Progress progress2("Progress report 2", "Starting report 2",
+ /*total=*/std::nullopt, /*debugger=*/nullptr,
+ /*minimum_report_time=*/std::chrono::seconds(0),
+ Progress::Origin::eExternal);
+ Progress progress3("Progress report 3", "Starting report 3",
+ /*total=*/std::nullopt, /*debugger=*/nullptr,
+ /*minimum_report_time=*/std::chrono::seconds(0),
+ Progress::Origin::eExternal);
+ }
+
+ // Start popping events from the queue, they should have been recevied
+ // in this order:
+ // Starting progress: 1, 2, 3
+ // Ending progress: 3, 2, 1
+ ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
+ data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
+
+ EXPECT_EQ(data->GetDetails(), "Starting report 1");
+ EXPECT_FALSE(data->IsFinite());
+ EXPECT_FALSE(data->GetCompleted());
+ EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
+ EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
+
+ ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
+ data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
+
+ EXPECT_EQ(data->GetDetails(), "Starting report 2");
+ EXPECT_FALSE(data->IsFinite());
+ EXPECT_FALSE(data->GetCompleted());
+ EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
+ EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");
+
+ ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
+ data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
+
+ EXPECT_EQ(data->GetDetails(), "Starting report 3");
+ EXPECT_FALSE(data->IsFinite());
+ EXPECT_FALSE(data->GetCompleted());
+ EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal);
+ EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");
+
+ // Progress report objects should be destroyed at this point so
+ // get each report from the queue and check that they've been
+ // destroyed in reverse order.
+ ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
+ data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
+
+ EXPECT_EQ(data->GetTitle(), "Progress report 3");
+ EXPECT_TRUE(data->GetCompleted());
+ EXPECT_FALSE(data->IsFinite());
+ EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3");
+
+ ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
+ data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
+
+ EXPECT_EQ(data->GetTitle(), "Progress report 2");
+ EXPECT_TRUE(data->GetCompleted());
+ EXPECT_FALSE(data->IsFinite());
+ EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2");
+
+ ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT));
+ data = ProgressEventData::GetEventDataFromEvent(event_sp.get());
+
+ EXPECT_EQ(data->GetTitle(), "Progress report 1");
+ EXPECT_TRUE(data->GetCompleted());
+ EXPECT_FALSE(data->IsFinite());
+ EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1");
+}
+
+TEST_F(ProgressReportTest, TestExternalReportNotReceived) {
+ ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress);
+ EventSP event_sp;
+
+ // Scope this for RAII on the progress objects.
+ // Create progress reports and check that their respective events for having
+ // started and ended are broadcasted.
+ {
+ Progress progress1("External Progress report 1",
+ "Starting external report 1",
+ /*total=*/std::nullopt, /*debugger=*/nullptr,
+ /*minimum_report_time=*/std::chrono::seconds(0),
+ Progress::Origin::eExternal);
+ }
+
+ ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT));
+}
More information about the lldb-commits
mailing list