diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2019-11-24 21:49:12 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2019-11-24 21:49:12 +0000 |
commit | 704cc4595c0ddeba4eebfd4264c4ac61f1ca9ba7 (patch) | |
tree | 149fad72114e44a23197212ccf3b14cf0d754816 /staging_vespalib/src | |
parent | eef2bd2d629588fea48d23d4d8b481b83ce6d231 (diff) |
Add test for volatile clock.
Diffstat (limited to 'staging_vespalib/src')
-rw-r--r-- | staging_vespalib/src/tests/clock/clock_benchmark.cpp | 122 | ||||
-rw-r--r-- | staging_vespalib/src/vespa/vespalib/util/clock.cpp | 1 |
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)), |