1 //===-- SlowOperationInformer.cpp - Keep the user informed ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the SlowOperationInformer class for the LLVM debugger.
12 //===----------------------------------------------------------------------===//
14 #include "Support/SlowOperationInformer.h"
15 #include "Config/config.h" // Get the signal handler return type
23 /// OperationCancelled - This flag is set by the SIGINT signal handler if the
24 /// user presses CTRL-C.
25 static volatile bool OperationCancelled;
27 /// ShouldShowStatus - This flag gets set if the operation takes a long time.
29 static volatile bool ShouldShowStatus;
31 /// NestedSOI - Sanity check. SlowOperationInformers cannot be nested or run in
32 /// parallel. This ensures that they never do.
33 static bool NestedSOI = false;
35 static RETSIGTYPE SigIntHandler(int Sig) {
36 OperationCancelled = true;
37 signal(SIGINT, SigIntHandler);
40 static RETSIGTYPE SigAlarmHandler(int Sig) {
41 ShouldShowStatus = true;
44 static void (*OldSigIntHandler) (int);
47 SlowOperationInformer::SlowOperationInformer(const std::string &Name)
48 : OperationName(Name), LastPrintAmount(0) {
49 assert(!NestedSOI && "SlowerOperationInformer objects cannot be nested!");
52 OperationCancelled = 0;
55 signal(SIGALRM, SigAlarmHandler);
56 OldSigIntHandler = signal(SIGINT, SigIntHandler);
60 SlowOperationInformer::~SlowOperationInformer() {
62 if (LastPrintAmount) {
63 // If we have printed something, make _sure_ we print the 100% amount, and
64 // also print a newline.
65 std::cout << std::string(LastPrintAmount, '\b') << "Progress "
66 << OperationName << ": 100% \n";
70 signal(SIGALRM, SIG_DFL);
71 signal(SIGINT, OldSigIntHandler);
74 /// progress - Clients should periodically call this method when they are in
75 /// an exception-safe state. The Amount variable should indicate how far
76 /// along the operation is, given in 1/10ths of a percent (in other words,
77 /// Amount should range from 0 to 1000).
78 void SlowOperationInformer::progress(unsigned Amount) {
79 if (OperationCancelled) {
82 throw "While " + OperationName + ", operation cancelled.";
85 // If we haven't spent enough time in this operation to warrant displaying the
86 // progress bar, don't do so yet.
87 if (!ShouldShowStatus)
90 // Delete whatever we printed last time.
91 std::string ToPrint = std::string(LastPrintAmount, '\b');
93 std::ostringstream OS;
94 OS << "Progress " << OperationName << ": " << Amount/10;
95 if (unsigned Rem = Amount % 10)
96 OS << "." << Rem << "%";
100 LastPrintAmount = OS.str().size();
101 std::cout << ToPrint+OS.str() << std::flush;