aboutsummaryrefslogtreecommitdiffstats
path: root/staging_vespalib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2019-11-24 21:49:12 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2019-11-24 21:49:12 +0000
commit704cc4595c0ddeba4eebfd4264c4ac61f1ca9ba7 (patch)
tree149fad72114e44a23197212ccf3b14cf0d754816 /staging_vespalib
parenteef2bd2d629588fea48d23d4d8b481b83ce6d231 (diff)
Add test for volatile clock.
Diffstat (limited to 'staging_vespalib')
-rw-r--r--staging_vespalib/src/tests/clock/clock_benchmark.cpp122
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/clock.cpp1
2 files changed, 97 insertions, 26 deletions
diff --git a/staging_vespalib/src/tests/clock/clock_benchmark.cpp b/staging_vespalib/src/tests/clock/clock_benchmark.cpp
index 49eac95de66..4456c9dbb5c 100644
--- a/staging_vespalib/src/tests/clock/clock_benchmark.cpp
+++ b/staging_vespalib/src/tests/clock/clock_benchmark.cpp
@@ -7,26 +7,92 @@
using vespalib::Clock;
using fastos::TimeStamp;
-struct Sampler : public FastOS_Runnable {
- Sampler(Clock & clock, fastos::SteadyTimeStamp end) :
- _samples(0),
- _clock(clock),
- _theEnd(end)
+struct UpdateClock {
+ virtual ~UpdateClock() {}
+ virtual void update() = 0;
+};
+
+struct NSValue : public UpdateClock {
+ void update() override { _value = std::chrono::steady_clock::now().time_since_epoch().count(); }
+ int64_t _value;
+};
+
+struct NSVolatileValue : public UpdateClock {
+ void update() override { _value = std::chrono::steady_clock::now().time_since_epoch().count(); }
+ volatile int64_t _value;
+};
+
+class TestClock : public FastOS_Runnable
+{
+private:
+ int _timePeriodMS;
+ std::mutex _lock;
+ std::condition_variable _cond;
+ UpdateClock &_clock;
+ bool _stop;
+
+ void Run(FastOS_ThreadInterface *thisThread, void *arguments) override;
+
+public:
+ TestClock(UpdateClock & clock, double timePeriod)
+ : _timePeriodMS(static_cast<uint32_t>(timePeriod*1000)),
+ _lock(),
+ _cond(),
+ _clock(clock),
+ _stop(false)
+ { }
+ ~TestClock() {
+ std::lock_guard<std::mutex> guard(_lock);
+ _stop = true;
+ _cond.notify_all();
+ }
+};
+
+void TestClock::Run(FastOS_ThreadInterface *thread, void *)
+{
+ std::unique_lock<std::mutex> guard(_lock);
+ while ( ! thread->GetBreakFlag() && !_stop) {
+ _clock.update();
+ _cond.wait_for(guard, std::chrono::milliseconds(_timePeriodMS));
+ }
+}
+
+struct SamplerBase : public FastOS_Runnable {
+ FastOS_ThreadInterface * _thread;
+ uint64_t _samples;
+};
+
+template<typename Func>
+struct Sampler : public SamplerBase {
+ Sampler(Func func) :
+ _func(func)
{ }
void Run(FastOS_ThreadInterface *, void *) override {
- printf("Starting at %s with doom at %s\n", _clock.getTimeNSAssumeRunning().toString().c_str(), _theEnd.toString().c_str());
- for (_samples = 0; (_clock.getTimeNSAssumeRunning() < _theEnd) && (_samples < 40000000000l); _samples++) {
-
+ fastos::SteadyTimeStamp start = fastos::ClockSteady::now();
+ printf("Starting at %s \n", fastos::ClockSystem::now().toString().c_str());
+ uint64_t samples;
+ uint64_t countFalse(0);
+ for (samples = 0; (samples < _samples); samples++) {
+ if ( ! _func(samples)) countFalse++;
}
- printf("Took %ld clock samples at %s\n", _samples, _clock.getTimeNSAssumeRunning().toString().c_str());
+ printf("Took %ld clock samples in %2.3f with %ld keeping up\n", samples, (fastos::ClockSteady::now() - start).sec(), countFalse);
}
- uint64_t _samples;
- const Clock & _clock;
- fastos::SteadyTimeStamp _theEnd;
- FastOS_ThreadInterface * _thread;
+ Func _func;
};
-void sample() {
+template<typename Func>
+void benchmark(FastOS_ThreadPool & pool, uint64_t samples, int numThreads, Func func) {
+ std::vector<std::unique_ptr<SamplerBase>> threads;
+ threads.reserve(numThreads);
+ for (int i(0); i < numThreads; i++) {
+ SamplerBase * sampler = new Sampler(func);
+ sampler->_samples = samples;
+ sampler->_thread = pool.NewThread(sampler, nullptr);
+ threads.emplace_back(sampler);
+ }
+ for (const auto & sampler : threads) {
+ sampler->_thread->Join();
+ }
}
int
@@ -34,20 +100,26 @@ main(int , char *argv[])
{
long frequency = atoll(argv[1]);
int numThreads = atoi(argv[2]);
- Clock clock(1.0/frequency);
+ uint64_t samples = atoll(argv[3]);
FastOS_ThreadPool pool(0x10000);
+ NSValue nsValue;
+ NSVolatileValue nsVolatileValue;
+ Clock clock(1.0/frequency);
+ TestClock nsClock(nsValue, 1.0/frequency);
+ TestClock nsVolatileClock(nsVolatileValue, 1.0/frequency);
assert(pool.NewThread(&clock, nullptr) != nullptr);
+ assert(pool.NewThread(&nsClock, nullptr) != nullptr);
+ assert(pool.NewThread(&nsVolatileClock, nullptr) != nullptr);
+ fastos::SteadyTimeStamp now = clock.getTimeNSAssumeRunning();
+ FastOS_Thread::Sleep(100);
+
+ benchmark(pool, samples, numThreads, [&clock, &now](int64_t i){ return (now+i < clock.getTimeNSAssumeRunning());});
+ benchmark(pool, samples, numThreads, [&nsValue, &now](int64_t i){ return (now+i < fastos::SteadyTimeStamp(nsValue._value));});
+ benchmark(pool, samples, numThreads, [&nsVolatileValue, &now](int64_t i){ return (now+i < fastos::SteadyTimeStamp(nsVolatileValue._value));});
+
+ benchmark(pool, samples, numThreads, [&now](uint64_t i){ return (now+i < fastos::ClockSteady::now());});
- std::vector<std::unique_ptr<Sampler>> threads;
- threads.reserve(numThreads);
- for (int i(0); i < numThreads; i++) {
- threads.push_back(std::make_unique<Sampler>(clock, fastos::ClockSteady::now() + 10*TimeStamp::SEC));
- Sampler * sampler = threads[i].get();
- sampler->_thread = pool.NewThread(threads[i].get(), nullptr);
- }
- for (const auto & sampler : threads) {
- sampler->_thread->Join();
- }
pool.Close();
clock.stop();
+ return 0;
}
diff --git a/staging_vespalib/src/vespa/vespalib/util/clock.cpp b/staging_vespalib/src/vespa/vespalib/util/clock.cpp
index 543a475480b..7f81b967a00 100644
--- a/staging_vespalib/src/vespa/vespalib/util/clock.cpp
+++ b/staging_vespalib/src/vespa/vespalib/util/clock.cpp
@@ -6,7 +6,6 @@
namespace vespalib {
-
Clock::Clock(double timePeriod) :
_timeNS(0u),
_timePeriodMS(static_cast<uint32_t>(timePeriod*1000)),