LLDB mainline
Progress.h
Go to the documentation of this file.
1//===-- Progress.h ----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_CORE_PROGRESS_H
10#define LLDB_CORE_PROGRESS_H
11
13#include "lldb/lldb-forward.h"
14#include "lldb/lldb-types.h"
15#include "llvm/ADT/StringMap.h"
16#include <atomic>
17#include <cstdint>
18#include <mutex>
19#include <optional>
20#include <string>
21
22namespace lldb_private {
23
24/// A Progress indicator helper class.
25///
26/// Any potentially long running sections of code in LLDB should report
27/// progress so that clients are aware of delays that might appear during
28/// debugging. Delays commonly include indexing debug information, parsing
29/// symbol tables for object files, downloading symbols from remote
30/// repositories, and many more things.
31///
32/// The Progress class helps make sure that progress is correctly reported
33/// and will always send an initial progress update, updates when
34/// Progress::Increment() is called, and also will make sure that a progress
35/// completed update is reported even if the user doesn't explicitly cause one
36/// to be sent.
37///
38/// The progress is reported via a callback whose type is ProgressCallback:
39///
40/// typedef void (*ProgressCallback)(uint64_t progress_id,
41/// const char *message,
42/// uint64_t completed,
43/// uint64_t total,
44/// void *baton);
45///
46/// This callback will always initially be called with \a completed set to zero
47/// and \a total set to the total amount specified in the constructor. This is
48/// considered the progress start event. As Progress::Increment() is called,
49/// the callback will be called as long as the Progress::m_completed has not
50/// yet exceeded the Progress::m_total. When the callback is called with
51/// Progress::m_completed == Progress::m_total, that is considered a progress
52/// completed event. If Progress::m_completed is non-zero and less than
53/// Progress::m_total, then this is considered a progress update event.
54///
55/// This callback will be called in the destructor if Progress::m_completed is
56/// not equal to Progress::m_total with the \a completed set to
57/// Progress::m_total. This ensures we always send a progress completed update
58/// even if the user does not.
59
60class Progress {
61public:
62 /// Enum to indicate the origin of a progress event, internal or external.
63 enum class Origin : uint8_t {
66 };
67
68 /// Construct a progress object that will report information.
69 ///
70 /// The constructor will create a unique progress reporting object and
71 /// immediately send out a progress update by calling the installed callback
72 /// with \a completed set to zero out of the specified total.
73 ///
74 /// @param [in] title The title of this progress activity.
75 ///
76 /// @param [in] details Specific information about what the progress report
77 /// is currently working on. Although not required, if the progress report is
78 /// updated with Progress::Increment() then this field will be overwritten
79 /// with the new set of details passed into that function, and the details
80 /// passed initially will act as an "item 0" for the total set of
81 /// items being reported on.
82 ///
83 /// @param [in] total The total units of work to be done if specified, if
84 /// set to std::nullopt then an indeterminate progress indicator should be
85 /// displayed.
86 ///
87 /// @param [in] debugger An optional debugger pointer to specify that this
88 /// progress is to be reported only to specific debuggers.
89 Progress(std::string title, std::string details = {},
90 std::optional<uint64_t> total = std::nullopt,
91 lldb_private::Debugger *debugger = nullptr,
92 Timeout<std::nano> minimum_report_time = std::nullopt,
93 Origin origin = Origin::eInternal);
94
95 /// Destroy the progress object.
96 ///
97 /// If the progress has not yet sent a completion update, the destructor
98 /// will send out a notification where the \a completed == m_total. This
99 /// ensures that we always send out a progress complete notification.
100 ~Progress();
101
102 /// Increment the progress and send a notification to the installed callback.
103 ///
104 /// If incrementing ends up exceeding m_total, m_completed will be updated
105 /// to match m_total and no subsequent progress notifications will be sent.
106 /// If no total was specified in the constructor, this function will not do
107 /// anything nor send any progress updates.
108 ///
109 /// @param [in] amount The amount to increment m_completed by.
110 ///
111 /// @param [in] an optional message associated with this update.
112 void Increment(uint64_t amount = 1,
113 std::optional<std::string> updated_detail = {});
114
115 /// Used to indicate a non-deterministic progress report
116 static constexpr uint64_t kNonDeterministicTotal = UINT64_MAX;
117
118 /// The default report time for high frequency progress reports.
119 static constexpr std::chrono::milliseconds kDefaultHighFrequencyReportTime =
120 std::chrono::milliseconds(20);
121
122private:
123 void ReportProgress();
124 static std::atomic<uint64_t> g_id;
125
126 /// Total amount of work, use a std::nullopt in the constructor for non
127 /// deterministic progress.
128 const uint64_t m_total;
129
130 // Minimum amount of time between two progress reports.
132
133 /// The title of the progress activity, also used as a category.
134 const std::string m_title;
135
136 /// A unique integer identifier for progress reporting.
137 const uint64_t m_progress_id;
138
139 /// The optional debugger ID to report progress to. If this has no value
140 /// then all debuggers will receive this event.
141 const std::optional<lldb::user_id_t> m_debugger_id;
142
143 /// The origin of the progress event, whether it is internal or external.
145
146 /// How much work ([0...m_total]) that has been completed.
147 std::atomic<uint64_t> m_completed = 0;
148
149 /// Time (in nanoseconds since epoch) of the last progress report.
150 std::atomic<uint64_t> m_last_report_time_ns;
151
152 /// Guards non-const non-atomic members of the class.
153 std::mutex m_mutex;
154
155 /// More specific information about the current file being displayed in the
156 /// report.
157 std::string m_details;
158
159 /// The "completed" value of the last reported event.
160 std::optional<uint64_t> m_prev_completed;
161};
162
163} // namespace lldb_private
164
165#endif // LLDB_CORE_PROGRESS_H
A class to manage flag bits.
Definition Debugger.h:80
const Timeout< std::nano > m_minimum_report_time
Definition Progress.h:131
const std::optional< lldb::user_id_t > m_debugger_id
The optional debugger ID to report progress to.
Definition Progress.h:141
const std::string m_title
The title of the progress activity, also used as a category.
Definition Progress.h:134
void Increment(uint64_t amount=1, std::optional< std::string > updated_detail={})
Increment the progress and send a notification to the installed callback.
Definition Progress.cpp:62
static std::atomic< uint64_t > g_id
Definition Progress.h:124
static constexpr std::chrono::milliseconds kDefaultHighFrequencyReportTime
The default report time for high frequency progress reports.
Definition Progress.h:119
const Origin m_origin
The origin of the progress event, whether it is internal or external.
Definition Progress.h:144
std::atomic< uint64_t > m_last_report_time_ns
Time (in nanoseconds since epoch) of the last progress report.
Definition Progress.h:150
std::string m_details
More specific information about the current file being displayed in the report.
Definition Progress.h:157
Origin
Enum to indicate the origin of a progress event, internal or external.
Definition Progress.h:63
static constexpr uint64_t kNonDeterministicTotal
Used to indicate a non-deterministic progress report.
Definition Progress.h:116
std::mutex m_mutex
Guards non-const non-atomic members of the class.
Definition Progress.h:153
const uint64_t m_progress_id
A unique integer identifier for progress reporting.
Definition Progress.h:137
std::atomic< uint64_t > m_completed
How much work ([0...m_total]) that has been completed.
Definition Progress.h:147
std::optional< uint64_t > m_prev_completed
The "completed" value of the last reported event.
Definition Progress.h:160
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, Origin origin=Origin::eInternal)
Construct a progress object that will report information.
Definition Progress.cpp:28
~Progress()
Destroy the progress object.
Definition Progress.cpp:51
const uint64_t m_total
Total amount of work, use a std::nullopt in the constructor for non deterministic progress.
Definition Progress.h:128
#define UINT64_MAX
A class that represents a running process on the host machine.