summaryrefslogtreecommitdiffstats
path: root/storageframework
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahoo-inc.com>2016-11-28 15:08:43 +0100
committerTor Brede Vekterli <vekterli@yahoo-inc.com>2016-11-28 15:11:55 +0100
commitc81a8988422515e4ae642d832c4eeeddac764fc2 (patch)
tree0d3fdf90b569185cace905c21f7c911c7320e672 /storageframework
parente548190672bc4d23990507a81c336ed151753c13 (diff)
Add monotonic clock support to storage framework
Let MilliSecTimer expose elapsed time as a double instead of quantizing down elapsed time to discrete millliseconds. Remove really gnarly implicit time_t operator conversion in favor of an explicit duration reporting method.
Diffstat (limited to 'storageframework')
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h13
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp16
-rw-r--r--storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.h7
-rw-r--r--storageframework/src/vespa/storageframework/generic/clock/clock.h8
-rw-r--r--storageframework/src/vespa/storageframework/generic/clock/time.h9
-rw-r--r--storageframework/src/vespa/storageframework/generic/clock/timer.h28
6 files changed, 51 insertions, 30 deletions
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h b/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h
index f15414b3f51..c4659bea21e 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h
@@ -19,7 +19,7 @@ struct FakeClock : public framework::Clock {
enum Mode {
FAKE_ABSOLUTE, // Time is always equal to supplied absolute time
FAKE_ABSOLUTE_CYCLE // Time is equal to absolute time + counter that
- // increase for each request so you never get same
+ // increases for each request so you never get same
// timestamp twice.
};
@@ -63,17 +63,22 @@ public:
_absoluteTime += framework::MicroSecTime(nr * uint64_t(1000000));
}
- virtual framework::MicroSecTime getTimeInMicros() const {
+ framework::MicroSecTime getTimeInMicros() const override {
vespalib::LockGuard guard(_lock);
if (_mode == FAKE_ABSOLUTE) return _absoluteTime;
return _absoluteTime + framework::MicroSecTime(1000000 * _cycleCount++);
}
- virtual framework::MilliSecTime getTimeInMillis() const {
+ framework::MilliSecTime getTimeInMillis() const override {
return getTimeInMicros().getMillis();
}
- virtual framework::SecondTime getTimeInSeconds() const {
+ framework::SecondTime getTimeInSeconds() const override {
return getTimeInMicros().getSeconds();
}
+ framework::MonotonicTimePoint getMonotonicTime() const override {
+ // For simplicity, assume fake monotonic time follows fake wall clock.
+ return MonotonicTimePoint(std::chrono::microseconds(
+ getTimeInMicros().getTime()));
+ }
};
} // defaultimplementation
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp b/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp
index e9348512427..86343a7c4ea 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp
@@ -9,31 +9,29 @@ namespace storage {
namespace framework {
namespace defaultimplementation {
-MicroSecTime
-RealClock::getTimeInMicros() const
-{
+MicroSecTime RealClock::getTimeInMicros() const {
struct timeval mytime;
gettimeofday(&mytime, 0);
return MicroSecTime(mytime.tv_sec * 1000000llu + mytime.tv_usec);
}
-MilliSecTime
-RealClock::getTimeInMillis() const
-{
+MilliSecTime RealClock::getTimeInMillis() const {
struct timeval mytime;
gettimeofday(&mytime, 0);
return MilliSecTime(
mytime.tv_sec * 1000llu + mytime.tv_usec / 1000);
}
-SecondTime
-RealClock::getTimeInSeconds() const
-{
+SecondTime RealClock::getTimeInSeconds() const {
struct timeval mytime;
gettimeofday(&mytime, 0);
return SecondTime(mytime.tv_sec);
}
+MonotonicTimePoint RealClock::getMonotonicTime() const {
+ return std::chrono::steady_clock::now();
+}
+
} // defaultimplementation
} // framework
} // storage
diff --git a/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.h b/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.h
index 633ab126c45..a8fd5d597d7 100644
--- a/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.h
+++ b/storageframework/src/vespa/storageframework/defaultimplementation/clock/realclock.h
@@ -16,9 +16,10 @@ namespace framework {
namespace defaultimplementation {
struct RealClock : public Clock {
- virtual MicroSecTime getTimeInMicros() const;
- virtual MilliSecTime getTimeInMillis() const;
- virtual SecondTime getTimeInSeconds() const;
+ MicroSecTime getTimeInMicros() const override;
+ MilliSecTime getTimeInMillis() const override;
+ SecondTime getTimeInSeconds() const override;
+ MonotonicTimePoint getMonotonicTime() const override;
};
} // defaultimplementation
diff --git a/storageframework/src/vespa/storageframework/generic/clock/clock.h b/storageframework/src/vespa/storageframework/generic/clock/clock.h
index bd9415a5a8c..acc7a537418 100644
--- a/storageframework/src/vespa/storageframework/generic/clock/clock.h
+++ b/storageframework/src/vespa/storageframework/generic/clock/clock.h
@@ -13,20 +13,24 @@
#pragma once
-#include <memory>
#include <vespa/storageframework/generic/clock/time.h>
+#include <memory>
+#include <chrono>
namespace storage {
namespace framework {
struct Clock {
- typedef std::unique_ptr<Clock> UP;
+ using UP = std::unique_ptr<Clock>;
virtual ~Clock() {}
virtual MicroSecTime getTimeInMicros() const = 0;
virtual MilliSecTime getTimeInMillis() const = 0;
virtual SecondTime getTimeInSeconds() const = 0;
+
+ // Time point resolution is intentionally not defined here.
+ virtual MonotonicTimePoint getMonotonicTime() const = 0;
};
} // framework
diff --git a/storageframework/src/vespa/storageframework/generic/clock/time.h b/storageframework/src/vespa/storageframework/generic/clock/time.h
index e09a4d5ef92..6e4ee615441 100644
--- a/storageframework/src/vespa/storageframework/generic/clock/time.h
+++ b/storageframework/src/vespa/storageframework/generic/clock/time.h
@@ -2,13 +2,17 @@
#pragma once
#include <boost/operators.hpp>
-#include <limits>
#include <vespa/vespalib/stllike/string.h>
#include <vespa/vespalib/stllike/asciistream.h>
+#include <limits>
+#include <chrono>
namespace storage {
namespace framework {
+using MonotonicTimePoint = std::chrono::steady_clock::time_point;
+using MonotonicDuration = std::chrono::steady_clock::duration;
+
class Clock;
enum TimeFormat {
@@ -27,6 +31,9 @@ enum TimeFormat {
*/
vespalib::string getTimeString(uint64_t microSecondTime, TimeFormat format);
+// TODO deprecate framework time point and duration classes in favor of
+// using std::chrono.
+
// As this class can't include clock, this utility function can be used in
// header implementation to get actual time.
uint64_t getRawMicroTime(const Clock&);
diff --git a/storageframework/src/vespa/storageframework/generic/clock/timer.h b/storageframework/src/vespa/storageframework/generic/clock/timer.h
index 66ff8cdef15..ea4568fc817 100644
--- a/storageframework/src/vespa/storageframework/generic/clock/timer.h
+++ b/storageframework/src/vespa/storageframework/generic/clock/timer.h
@@ -4,9 +4,6 @@
* \ingroup clock
*
* \brief Class used to measure time differences.
- *
- * This timer class is a simple class that then used as a time_t instance, it
- * will calculate time difference from some preset point of time.
*/
#pragma once
@@ -18,17 +15,26 @@ namespace framework {
class MilliSecTimer {
const Clock* _clock;
- time_t _startTime;
+ MonotonicTimePoint _startTime;
public:
MilliSecTimer(const Clock& clock)
- : _clock(&clock), _startTime(getCurrentTime()) {}
-
- MilliSecTime getTime() const { return MilliSecTime(getCurrentTime() - _startTime); }
- operator time_t() const { return getCurrentTime() - _startTime; }
-
- time_t getCurrentTime() const
- { return _clock->getTimeInMillis().getTime(); }
+ : _clock(&clock), _startTime(_clock->getMonotonicTime()) {}
+
+ // Copy construction makes the most sense when creating a timer that is
+ // intended to inherit another timer's start time point, without incurring
+ // the cost of an initial clock sampling.
+ MilliSecTimer(const MilliSecTimer&) = default;
+ MilliSecTimer& operator=(const MilliSecTimer&) = default;
+
+ MonotonicDuration getElapsedTime() const {
+ return _clock->getMonotonicTime() - _startTime;
+ }
+
+ double getElapsedTimeAsDouble() const {
+ using ToDuration = std::chrono::duration<double, std::milli>;
+ return std::chrono::duration_cast<ToDuration>(getElapsedTime()).count();
+ }
};
} // framework