
Consider the following example as motivation. Say you have to load symbols for 3 dynamic libraries: `libFoo`, `libBar` and `libBaz`. Currently, there are two ways to report process for this operation: 1. As 3 separate progress instances. In this case you create a progress instance with the message "Loading symbols: libFoo", "Loading symbols: libBar", and "Loading symbols: libBaz" respectively. Each progress event gets a unique ID and therefore cannot be correlated by the consumer. 2. As 1 progress instance with 3 units of work. The title would be "Loading symbols" and you call Progress::Increment for each of the libraries. The 3 progress events share the same ID and can easily be correlated, however, in the current design, there's no way to include the name of the libraries. The second approach is preferred when the amount of work is known in advance, because determinate progress can be reported (i.e. x out of y operations completed). An additional benefit is that the progress consumer can decide to ignore certain progress updates by their ID if they are deemed to noisy, which isn't trivial for the first approach due to the use of different progress IDs. This patch adds the ability to add a message (detail) to a progress event update. For the example described above, progress can now be displayed as shown: [1/3] Loading symbols: libFoo [2/3] Loading symbols: libBar [3/3] Loading symbols: libBaz Differential revision: https://reviews.llvm.org/D143690
61 lines
1.9 KiB
C++
61 lines
1.9 KiB
C++
//===-- Progress.cpp ------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Core/Progress.h"
|
|
|
|
#include "lldb/Core/Debugger.h"
|
|
#include "lldb/Utility/StreamString.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
std::atomic<uint64_t> Progress::g_id(0);
|
|
|
|
Progress::Progress(std::string title, uint64_t total,
|
|
lldb_private::Debugger *debugger)
|
|
: m_title(title), m_id(++g_id), m_completed(0), m_total(total) {
|
|
assert(total > 0);
|
|
if (debugger)
|
|
m_debugger_id = debugger->GetID();
|
|
std::lock_guard<std::mutex> guard(m_mutex);
|
|
ReportProgress();
|
|
}
|
|
|
|
Progress::~Progress() {
|
|
// Make sure to always report progress completed when this object is
|
|
// destructed so it indicates the progress dialog/activity should go away.
|
|
std::lock_guard<std::mutex> guard(m_mutex);
|
|
if (!m_completed) {
|
|
m_completed = m_total;
|
|
ReportProgress();
|
|
}
|
|
}
|
|
|
|
void Progress::Increment(uint64_t amount, std::string update) {
|
|
if (amount > 0) {
|
|
std::lock_guard<std::mutex> guard(m_mutex);
|
|
// Watch out for unsigned overflow and make sure we don't increment too
|
|
// much and exceed m_total.
|
|
if (amount > (m_total - m_completed))
|
|
m_completed = m_total;
|
|
else
|
|
m_completed += amount;
|
|
ReportProgress(update);
|
|
}
|
|
}
|
|
|
|
void Progress::ReportProgress(std::string update) {
|
|
if (!m_complete) {
|
|
// Make sure we only send one notification that indicates the progress is
|
|
// complete.
|
|
m_complete = m_completed == m_total;
|
|
Debugger::ReportProgress(m_id, m_title, std::move(update), m_completed,
|
|
m_total, m_debugger_id);
|
|
}
|
|
}
|