1*e122877fSGreg Clayton //===-- Progress.cpp ------------------------------------------------------===//
2*e122877fSGreg Clayton //
3*e122877fSGreg Clayton // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e122877fSGreg Clayton // See https://llvm.org/LICENSE.txt for license information.
5*e122877fSGreg Clayton // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e122877fSGreg Clayton //
7*e122877fSGreg Clayton //===----------------------------------------------------------------------===//
8*e122877fSGreg Clayton
9*e122877fSGreg Clayton #include "lldb/Core/Progress.h"
10*e122877fSGreg Clayton
11*e122877fSGreg Clayton #include "lldb/Core/Debugger.h"
12*e122877fSGreg Clayton #include "lldb/Utility/StreamString.h"
13*e122877fSGreg Clayton
14*e122877fSGreg Clayton using namespace lldb;
15*e122877fSGreg Clayton using namespace lldb_private;
16*e122877fSGreg Clayton
17*e122877fSGreg Clayton std::atomic<uint64_t> Progress::g_id(0);
18*e122877fSGreg Clayton
Progress(std::string title,uint64_t total,lldb_private::Debugger * debugger)19*e122877fSGreg Clayton Progress::Progress(std::string title, uint64_t total,
20*e122877fSGreg Clayton lldb_private::Debugger *debugger)
21*e122877fSGreg Clayton : m_title(title), m_id(++g_id), m_completed(0), m_total(total) {
22*e122877fSGreg Clayton assert(total > 0);
23*e122877fSGreg Clayton if (debugger)
24*e122877fSGreg Clayton m_debugger_id = debugger->GetID();
25*e122877fSGreg Clayton std::lock_guard<std::mutex> guard(m_mutex);
26*e122877fSGreg Clayton ReportProgress();
27*e122877fSGreg Clayton }
28*e122877fSGreg Clayton
~Progress()29*e122877fSGreg Clayton Progress::~Progress() {
30*e122877fSGreg Clayton // Make sure to always report progress completed when this object is
31*e122877fSGreg Clayton // destructed so it indicates the progress dialog/activity should go away.
32*e122877fSGreg Clayton std::lock_guard<std::mutex> guard(m_mutex);
33*e122877fSGreg Clayton if (!m_completed) {
34*e122877fSGreg Clayton m_completed = m_total;
35*e122877fSGreg Clayton ReportProgress();
36*e122877fSGreg Clayton }
37*e122877fSGreg Clayton }
38*e122877fSGreg Clayton
Increment(uint64_t amount)39*e122877fSGreg Clayton void Progress::Increment(uint64_t amount) {
40*e122877fSGreg Clayton if (amount > 0) {
41*e122877fSGreg Clayton std::lock_guard<std::mutex> guard(m_mutex);
42*e122877fSGreg Clayton // Watch out for unsigned overflow and make sure we don't increment too
43*e122877fSGreg Clayton // much and exceed m_total.
44*e122877fSGreg Clayton if (amount > (m_total - m_completed))
45*e122877fSGreg Clayton m_completed = m_total;
46*e122877fSGreg Clayton else
47*e122877fSGreg Clayton m_completed += amount;
48*e122877fSGreg Clayton ReportProgress();
49*e122877fSGreg Clayton }
50*e122877fSGreg Clayton }
51*e122877fSGreg Clayton
ReportProgress()52*e122877fSGreg Clayton void Progress::ReportProgress() {
53*e122877fSGreg Clayton if (!m_complete) {
54*e122877fSGreg Clayton // Make sure we only send one notification that indicates the progress is
55*e122877fSGreg Clayton // complete.
56*e122877fSGreg Clayton m_complete = m_completed == m_total;
57*e122877fSGreg Clayton Debugger::ReportProgress(m_id, m_title, m_completed, m_total,
58*e122877fSGreg Clayton m_debugger_id);
59*e122877fSGreg Clayton }
60*e122877fSGreg Clayton }
61