aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2009-06-23 20:52:29 +0000
committerOwen Anderson <resistor@mac.com>2009-06-23 20:52:29 +0000
commit46d9a6494496d215e850f337b5a723c484212f80 (patch)
tree0e7bb70cb2e9fac383f1673e8aaf334e215cd59e
parent223e99cd8d9a0a6a57504589b8593d402c67d38b (diff)
Make timers threadsafe again. This isn't quite as nice as I'd hoped (it uses locking rather than atomic arithmetic),
but should work on all the platforms we care about. I might revisit this if a totally awesome way to do it occurs to me. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74002 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/Timer.h25
-rw-r--r--lib/Support/Timer.cpp54
2 files changed, 74 insertions, 5 deletions
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 584199f440..71b7ee58fd 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -16,6 +16,7 @@
#define LLVM_SUPPORT_TIMER_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/System/Mutex.h"
#include <string>
#include <vector>
#include <iosfwd>
@@ -43,6 +44,7 @@ class Timer {
std::string Name; // The name of this time variable
bool Started; // Has this time variable ever been started?
TimerGroup *TG; // The TimerGroup this Timer is in.
+ mutable sys::SmartMutex<true> Lock; // Mutex for the contents of this Timer.
public:
explicit Timer(const std::string &N);
Timer(const std::string &N, TimerGroup &tg);
@@ -56,6 +58,14 @@ public:
std::string getName() const { return Name; }
const Timer &operator=(const Timer &T) {
+ if (&T < this) {
+ T.Lock.acquire();
+ Lock.acquire();
+ } else {
+ Lock.acquire();
+ T.Lock.acquire();
+ }
+
Elapsed = T.Elapsed;
UserTime = T.UserTime;
SystemTime = T.SystemTime;
@@ -65,6 +75,15 @@ public:
Name = T.Name;
Started = T.Started;
assert(TG == T.TG && "Can only assign timers in the same TimerGroup!");
+
+ if (&T < this) {
+ T.Lock.release();
+ Lock.release();
+ } else {
+ Lock.release();
+ T.Lock.release();
+ }
+
return *this;
}
@@ -160,11 +179,9 @@ public:
private:
friend class Timer;
- void addTimer() { ++NumTimers; }
+ void addTimer();
void removeTimer();
- void addTimerToPrint(const Timer &T) {
- TimersToPrint.push_back(Timer(true, T));
- }
+ void addTimerToPrint(const Timer &T);
};
} // End llvm namespace
diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp
index bcb27a4ab4..ede1dc96e8 100644
--- a/lib/Support/Timer.cpp
+++ b/lib/Support/Timer.cpp
@@ -38,6 +38,8 @@ static std::string &getLibSupportInfoOutputFilename() {
return *LibSupportInfoOutputFilename;
}
+static ManagedStatic<sys::SmartMutex<true> > TimerLock;
+
namespace {
static cl::opt<bool>
TrackSpace("track-memory", cl::desc("Enable -time-passes memory "
@@ -143,6 +145,7 @@ static TimeRecord getTimeRecord(bool Start) {
static ManagedStatic<std::vector<Timer*> > ActiveTimers;
void Timer::startTimer() {
+ sys::SmartScopedLock<true> L(&Lock);
Started = true;
ActiveTimers->push_back(this);
TimeRecord TR = getTimeRecord(true);
@@ -154,6 +157,7 @@ void Timer::startTimer() {
}
void Timer::stopTimer() {
+ sys::SmartScopedLock<true> L(&Lock);
TimeRecord TR = getTimeRecord(false);
Elapsed += TR.Elapsed;
UserTime += TR.UserTime;
@@ -171,11 +175,27 @@ void Timer::stopTimer() {
}
void Timer::sum(const Timer &T) {
+ if (&T < this) {
+ T.Lock.acquire();
+ Lock.acquire();
+ } else {
+ Lock.acquire();
+ T.Lock.acquire();
+ }
+
Elapsed += T.Elapsed;
UserTime += T.UserTime;
SystemTime += T.SystemTime;
MemUsed += T.MemUsed;
PeakMem += T.PeakMem;
+
+ if (&T < this) {
+ T.Lock.release();
+ Lock.release();
+ } else {
+ Lock.release();
+ T.Lock.release();
+ }
}
/// addPeakMemoryMeasurement - This method should be called whenever memory
@@ -186,8 +206,11 @@ void Timer::addPeakMemoryMeasurement() {
size_t MemUsed = getMemUsage();
for (std::vector<Timer*>::iterator I = ActiveTimers->begin(),
- E = ActiveTimers->end(); I != E; ++I)
+ E = ActiveTimers->end(); I != E; ++I) {
+ (*I)->Lock.acquire();
(*I)->PeakMem = std::max((*I)->PeakMem, MemUsed-(*I)->PeakMemBase);
+ (*I)->Lock.release();
+ }
}
//===----------------------------------------------------------------------===//
@@ -206,6 +229,7 @@ static ManagedStatic<Name2Timer> NamedTimers;
static ManagedStatic<Name2Pair> NamedGroupedTimers;
static Timer &getNamedRegionTimer(const std::string &Name) {
+ sys::SmartScopedLock<true> L(&*TimerLock);
Name2Timer::iterator I = NamedTimers->find(Name);
if (I != NamedTimers->end())
return I->second;
@@ -215,6 +239,7 @@ static Timer &getNamedRegionTimer(const std::string &Name) {
static Timer &getNamedRegionTimer(const std::string &Name,
const std::string &GroupName) {
+ sys::SmartScopedLock<true> L(&*TimerLock);
Name2Pair::iterator I = NamedGroupedTimers->find(GroupName);
if (I == NamedGroupedTimers->end()) {
@@ -276,6 +301,14 @@ static void printVal(double Val, double Total, std::ostream &OS) {
}
void Timer::print(const Timer &Total, std::ostream &OS) {
+ if (&Total < this) {
+ Total.Lock.acquire();
+ Lock.acquire();
+ } else {
+ Lock.acquire();
+ Total.Lock.acquire();
+ }
+
if (Total.UserTime)
printVal(UserTime, Total.UserTime, OS);
if (Total.SystemTime)
@@ -300,6 +333,14 @@ void Timer::print(const Timer &Total, std::ostream &OS) {
OS << Name << "\n";
Started = false; // Once printed, don't print again
+
+ if (&Total < this) {
+ Total.Lock.release();
+ Lock.release();
+ } else {
+ Lock.release();
+ Total.Lock.release();
+ }
}
// GetLibSupportInfoOutputFile - Return a file stream to print our output on...
@@ -324,6 +365,7 @@ llvm::GetLibSupportInfoOutputFile() {
void TimerGroup::removeTimer() {
+ sys::SmartScopedLock<true> L(&*TimerLock);
if (--NumTimers == 0 && !TimersToPrint.empty()) { // Print timing report...
// Sort the timers in descending order by amount of time taken...
std::sort(TimersToPrint.begin(), TimersToPrint.end(),
@@ -391,3 +433,13 @@ void TimerGroup::removeTimer() {
}
}
+void TimerGroup::addTimer() {
+ sys::SmartScopedLock<true> L(&*TimerLock);
+ ++NumTimers;
+}
+
+void TimerGroup::addTimerToPrint(const Timer &T) {
+ sys::SmartScopedLock<true> L(&*TimerLock);
+ TimersToPrint.push_back(Timer(true, T));
+}
+