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 sighandler_t OldSigIntHandler;
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() {
66 signal(SIGALRM, SIG_DFL);
67 signal(SIGINT, OldSigIntHandler);
70 /// progress - Clients should periodically call this method when they are in
71 /// an exception-safe state. The Amount variable should indicate how far
72 /// along the operation is, given in 1/10ths of a percent (in other words,
73 /// Amount should range from 0 to 1000).
74 void SlowOperationInformer::progress(unsigned Amount) {
75 if (OperationCancelled) {
78 throw "While " + OperationName + ", operation cancelled.";
81 // If we haven't spent enough time in this operation to warrant displaying the
82 // progress bar, don't do so yet.
83 if (!ShouldShowStatus)
86 // Delete whatever we printed last time.
87 std::string ToPrint = std::string(LastPrintAmount, '\b');
89 std::ostringstream OS;
90 OS << "Progress " << OperationName << ": " << Amount/10 << "." << Amount % 10
93 LastPrintAmount = OS.str().size();
94 std::cout << ToPrint+OS.str() << std::flush;