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-types.h"
14#include "llvm/ADT/StringMap.h"
15#include <atomic>
16#include <mutex>
17#include <optional>
18
19namespace lldb_private {
20
21/// A Progress indicator helper class.
22///
23/// Any potentially long running sections of code in LLDB should report
24/// progress so that clients are aware of delays that might appear during
25/// debugging. Delays commonly include indexing debug information, parsing
26/// symbol tables for object files, downloading symbols from remote
27/// repositories, and many more things.
28///
29/// The Progress class helps make sure that progress is correctly reported
30/// and will always send an initial progress update, updates when
31/// Progress::Increment() is called, and also will make sure that a progress
32/// completed update is reported even if the user doesn't explicitly cause one
33/// to be sent.
34///
35/// The progress is reported via a callback whose type is ProgressCallback:
36///
37/// typedef void (*ProgressCallback)(uint64_t progress_id,
38/// const char *message,
39/// uint64_t completed,
40/// uint64_t total,
41/// void *baton);
42///
43/// This callback will always initially be called with "completed" set to zero
44/// and "total" set to the total amount specified in the contructor. This is
45/// considered the progress start event. As Progress::Increment() is called,
46/// the callback will be called as long as the Progress::m_completed has not
47/// yet exceeded the Progress::m_total. When the callback is called with
48/// Progress::m_completed == Progress::m_total, that is considered a progress
49/// completed event. If Progress::m_completed is non-zero and less than
50/// Progress::m_total, then this is considered a progress update event.
51///
52/// This callback will be called in the destructor if Progress::m_completed is
53/// not equal to Progress::m_total with the "completed" set to
54/// Progress::m_total. This ensures we always send a progress completed update
55/// even if the user does not.
56
57class Progress {
58public:
59 /// Construct a progress object that will report information.
60 ///
61 /// The constructor will create a unique progress reporting object and
62 /// immediately send out a progress update by calling the installed callback
63 /// with completed set to zero out of the specified total.
64 ///
65 /// @param [in] title The title of this progress activity.
66 ///
67 /// @param [in] total The total units of work to be done if specified, if
68 /// set to std::nullopt then an indeterminate progress indicator should be
69 /// displayed.
70 ///
71 /// @param [in] debugger An optional debugger pointer to specify that this
72 /// progress is to be reported only to specific debuggers.
73 Progress(std::string title, std::string details = {},
74 std::optional<uint64_t> total = std::nullopt,
75 lldb_private::Debugger *debugger = nullptr);
76
77 /// Destroy the progress object.
78 ///
79 /// If the progress has not yet sent a completion update, the destructor
80 /// will send out a notification where the completed == m_total. This ensures
81 /// that we always send out a progress complete notification.
82 ~Progress();
83
84 /// Increment the progress and send a notification to the intalled callback.
85 ///
86 /// If incrementing ends up exceeding m_total, m_completed will be updated
87 /// to match m_total and no subsequent progress notifications will be sent.
88 /// If no total was specified in the constructor, this function will not do
89 /// anything nor send any progress updates.
90 ///
91 /// @param [in] amount The amount to increment m_completed by.
92 ///
93 /// @param [in] an optional message associated with this update.
94 void Increment(uint64_t amount = 1,
95 std::optional<std::string> updated_detail = {});
96
97 /// Used to indicate a non-deterministic progress report
98 static constexpr uint64_t kNonDeterministicTotal = UINT64_MAX;
99
100private:
101 void ReportProgress();
102 static std::atomic<uint64_t> g_id;
103 /// The title of the progress activity.
104 std::string m_title;
105 std::string m_details;
106 std::mutex m_mutex;
107 /// A unique integer identifier for progress reporting.
108 const uint64_t m_id;
109 /// How much work ([0...m_total]) that has been completed.
110 uint64_t m_completed;
111 /// Total amount of work, use a std::nullopt in the constructor for non
112 /// deterministic progress.
113 uint64_t m_total;
114 /// The optional debugger ID to report progress to. If this has no value then
115 /// all debuggers will receive this event.
116 std::optional<lldb::user_id_t> m_debugger_id;
117 /// Set to true when progress has been reported where m_completed == m_total
118 /// to ensure that we don't send progress updates after progress has
119 /// completed.
120 bool m_complete = false;
121};
122
123/// A class used to group progress reports by category. This is done by using a
124/// map that maintains a refcount of each category of progress reports that have
125/// come in. Keeping track of progress reports this way will be done if a
126/// debugger is listening to the eBroadcastBitProgressByCategory broadcast bit.
128public:
131
132 /// Control the refcount of the progress report category as needed.
133 void Increment(std::string category);
134 void Decrement(std::string category);
135
136 static ProgressManager &Instance();
137
138private:
139 llvm::StringMap<uint64_t> m_progress_category_map;
141};
142
143} // namespace lldb_private
144
145#endif // LLDB_CORE_PROGRESS_H
A class to manage flag bits.
Definition: Debugger.h:79
A class used to group progress reports by category.
Definition: Progress.h:127
void Increment(std::string category)
Control the refcount of the progress report category as needed.
Definition: Progress.cpp:85
static ProgressManager & Instance()
Definition: Progress.cpp:75
llvm::StringMap< uint64_t > m_progress_category_map
Definition: Progress.h:139
void Decrement(std::string category)
Definition: Progress.cpp:90
A Progress indicator helper class.
Definition: Progress.h:57
bool m_complete
Set to true when progress has been reported where m_completed == m_total to ensure that we don't send...
Definition: Progress.h:120
void Increment(uint64_t amount=1, std::optional< std::string > updated_detail={})
Increment the progress and send a notification to the intalled callback.
Definition: Progress.cpp:45
uint64_t m_completed
How much work ([0...m_total]) that has been completed.
Definition: Progress.h:110
static std::atomic< uint64_t > g_id
Definition: Progress.h:102
std::optional< lldb::user_id_t > m_debugger_id
The optional debugger ID to report progress to.
Definition: Progress.h:116
std::string m_details
Definition: Progress.h:105
std::string m_title
The title of the progress activity.
Definition: Progress.h:104
static constexpr uint64_t kNonDeterministicTotal
Used to indicate a non-deterministic progress report.
Definition: Progress.h:98
std::mutex m_mutex
Definition: Progress.h:106
uint64_t m_total
Total amount of work, use a std::nullopt in the constructor for non deterministic progress.
Definition: Progress.h:113
~Progress()
Destroy the progress object.
Definition: Progress.cpp:36
const uint64_t m_id
A unique integer identifier for progress reporting.
Definition: Progress.h:108
#define UINT64_MAX
Definition: lldb-defines.h:23
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14