summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2015-12-22 17:36:17 +0000
committerVedant Kumar <vsk@apple.com>2015-12-22 17:36:17 +0000
commitd167586a2849c18631c13f37bb2d6ccd14a069cb (patch)
tree9843884dcb62bf54a07bef4efa44bdc857fb0777
parente4beddce5543fb41ce328d9368ae502e59de059f (diff)
downloadbcm5719-llvm-d167586a2849c18631c13f37bb2d6ccd14a069cb.tar.gz
bcm5719-llvm-d167586a2849c18631c13f37bb2d6ccd14a069cb.zip
[Support] Allow multiple paired calls to {start,stop}Timer()
Differential Revision: http://reviews.llvm.org/D15619 Reviewed-by: rafael llvm-svn: 256258
-rw-r--r--llvm/include/llvm/Support/Timer.h29
-rw-r--r--llvm/lib/Support/Timer.cpp32
-rw-r--r--llvm/unittests/Support/CMakeLists.txt1
-rw-r--r--llvm/unittests/Support/TimerTest.cpp49
4 files changed, 83 insertions, 28 deletions
diff --git a/llvm/include/llvm/Support/Timer.h b/llvm/include/llvm/Support/Timer.h
index 2d9b0e24841..499fe7b7e70 100644
--- a/llvm/include/llvm/Support/Timer.h
+++ b/llvm/include/llvm/Support/Timer.h
@@ -62,8 +62,8 @@ public:
MemUsed -= RHS.MemUsed;
}
- /// print - Print the current timer to standard error, and reset the "Started"
- /// flag.
+ /// Print the current time record to \p OS, with a breakdown showing
+ /// contributions to the \p Total time record.
void print(const TimeRecord &Total, raw_ostream &OS) const;
};
@@ -76,9 +76,11 @@ public:
/// if they are never started.
///
class Timer {
- TimeRecord Time;
+ TimeRecord Time; // The total time captured
+ TimeRecord StartTime; // The time startTimer() was last called
std::string Name; // The name of this time variable.
- bool Started; // Has this time variable ever been started?
+ bool Running; // Is the timer currently running?
+ bool Triggered; // Has the timer ever been triggered?
TimerGroup *TG; // The TimerGroup this Timer is in.
Timer **Prev, *Next; // Doubly linked list of timers in the group.
@@ -102,16 +104,23 @@ public:
const std::string &getName() const { return Name; }
bool isInitialized() const { return TG != nullptr; }
- /// startTimer - Start the timer running. Time between calls to
- /// startTimer/stopTimer is counted by the Timer class. Note that these calls
- /// must be correctly paired.
- ///
+ /// Check if startTimer() has ever been called on this timer.
+ bool hasTriggered() const { return Triggered; }
+
+ /// Start the timer running. Time between calls to startTimer/stopTimer is
+ /// counted by the Timer class. Note that these calls must be correctly
+ /// paired.
void startTimer();
- /// stopTimer - Stop the timer.
- ///
+ /// Stop the timer.
void stopTimer();
+ /// Clear the timer state.
+ void clear();
+
+ /// Return the duration for which this timer has been running.
+ TimeRecord getTotalTime() const { return Time; }
+
private:
friend class TimerGroup;
};
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index f8ab214bfbf..414f559f8f0 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -102,7 +102,7 @@ void Timer::init(StringRef N) {
void Timer::init(StringRef N, TimerGroup &tg) {
assert(!TG && "Timer already initialized");
Name.assign(N.begin(), N.end());
- Started = false;
+ Running = Triggered = false;
TG = &tg;
TG->addTimer(*this);
}
@@ -135,25 +135,22 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
return Result;
}
-static ManagedStatic<std::vector<Timer*> > ActiveTimers;
-
void Timer::startTimer() {
- Started = true;
- ActiveTimers->push_back(this);
- Time -= TimeRecord::getCurrentTime(true);
+ assert(!Running && "Cannot start a running timer");
+ Running = Triggered = true;
+ StartTime = TimeRecord::getCurrentTime(true);
}
void Timer::stopTimer() {
+ assert(Running && "Cannot stop a paused timer");
+ Running = false;
Time += TimeRecord::getCurrentTime(false);
+ Time -= StartTime;
+}
- if (ActiveTimers->back() == this) {
- ActiveTimers->pop_back();
- } else {
- std::vector<Timer*>::iterator I =
- std::find(ActiveTimers->begin(), ActiveTimers->end(), this);
- assert(I != ActiveTimers->end() && "stop but no startTimer?");
- ActiveTimers->erase(I);
- }
+void Timer::clear() {
+ Running = Triggered = false;
+ Time = StartTime = TimeRecord();
}
static void printVal(double Val, double Total, raw_ostream &OS) {
@@ -271,7 +268,7 @@ void TimerGroup::removeTimer(Timer &T) {
sys::SmartScopedLock<true> L(*TimerLock);
// If the timer was started, move its data to TimersToPrint.
- if (T.Started)
+ if (T.hasTriggered())
TimersToPrint.emplace_back(T.Time, T.Name);
T.TG = nullptr;
@@ -357,12 +354,11 @@ void TimerGroup::print(raw_ostream &OS) {
// See if any of our timers were started, if so add them to TimersToPrint and
// reset them.
for (Timer *T = FirstTimer; T; T = T->Next) {
- if (!T->Started) continue;
+ if (!T->hasTriggered()) continue;
TimersToPrint.emplace_back(T->Time, T->Name);
// Clear out the time.
- T->Started = 0;
- T->Time = TimeRecord();
+ T->clear();
}
// If any timers were started, print the group.
diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index 9bd685759ed..3ab98d58d5f 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -42,6 +42,7 @@ add_llvm_unittest(SupportTests
TargetRegistry.cpp
ThreadLocalTest.cpp
ThreadPool.cpp
+ TimerTest.cpp
TimeValueTest.cpp
TrailingObjectsTest.cpp
UnicodeTest.cpp
diff --git a/llvm/unittests/Support/TimerTest.cpp b/llvm/unittests/Support/TimerTest.cpp
new file mode 100644
index 00000000000..ac7c52db6d1
--- /dev/null
+++ b/llvm/unittests/Support/TimerTest.cpp
@@ -0,0 +1,49 @@
+//===- unittests/TimerTest.cpp - Timer tests ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Timer.h"
+#include "gtest/gtest.h"
+#include <chrono>
+#include <thread>
+
+using namespace llvm;
+
+namespace {
+
+TEST(Timer, Additivity) {
+ Timer T1("T1");
+
+ EXPECT_TRUE(T1.isInitialized());
+
+ T1.startTimer();
+ T1.stopTimer();
+ auto TR1 = T1.getTotalTime();
+
+ T1.startTimer();
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ T1.stopTimer();
+ auto TR2 = T1.getTotalTime();
+
+ EXPECT_TRUE(TR1 < TR2);
+}
+
+TEST(Timer, CheckIfTriggered) {
+ Timer T1("T1");
+
+ EXPECT_FALSE(T1.hasTriggered());
+ T1.startTimer();
+ EXPECT_TRUE(T1.hasTriggered());
+ T1.stopTimer();
+ EXPECT_TRUE(T1.hasTriggered());
+
+ T1.clear();
+ EXPECT_FALSE(T1.hasTriggered());
+}
+
+} // end anon namespace
OpenPOWER on IntegriCloud