/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2010-2016 Danny Robson */ #include "time.hpp" #include "log.hpp" #include using cruft::delta_clock; /////////////////////////////////////////////////////////////////////////////// static const uint64_t SECOND = 1'000'000'000UL; static const uint64_t MILLISECOND = 1'000'000UL; /////////////////////////////////////////////////////////////////////////////// uintmax_t cruft::nanoseconds (void) { return std::chrono::duration_cast< std::chrono::duration > ( std::chrono::high_resolution_clock::now ().time_since_epoch () ).count (); } /////////////////////////////////////////////////////////////////////////////// delta_clock::delta_clock (): time { cruft::nanoseconds (), cruft::nanoseconds () } { ; } //----------------------------------------------------------------------------- std::chrono::nanoseconds delta_clock::dt (void) { time.prev = time.curr; time.curr = nanoseconds (); return std::chrono::nanoseconds (time.curr - time.prev); } /////////////////////////////////////////////////////////////////////////////// cruft::period_query::period_query (float seconds) { m_time.start = nanoseconds (); m_time.period = static_cast (seconds * SECOND); } //----------------------------------------------------------------------------- bool cruft::period_query::poll (void) { uint64_t now = nanoseconds (); uint64_t diff = now - m_time.start; if (diff < m_time.period) return false; m_time.start += diff % m_time.period; return true; } /////////////////////////////////////////////////////////////////////////////// cruft::rate_limiter::rate_limiter (unsigned rate): m_last (nanoseconds ()), m_target (SECOND / rate) { ; } //----------------------------------------------------------------------------- void cruft::rate_limiter::poll (void) { uint64_t now = nanoseconds (); uint64_t total = now - m_last; if (total < m_target) sleep (m_target - total); m_last = now; } /////////////////////////////////////////////////////////////////////////////// cruft::period_limiter::period_limiter (std::chrono::nanoseconds _period) : period_limiter (_period.count ()) { ; } //----------------------------------------------------------------------------- cruft::period_limiter::period_limiter (u64 _period) : m_period (_period) , m_prev (nanoseconds () - _period) { ; } //----------------------------------------------------------------------------- void cruft::period_limiter::wait (void) const { auto const now = nanoseconds (); auto const diff = now - m_prev; if (diff < m_period) sleep (m_period - diff); } //----------------------------------------------------------------------------- void cruft::period_limiter::reset (void) { m_prev = nanoseconds (); } //----------------------------------------------------------------------------- void cruft::period_limiter::poll (void) { wait (); reset (); } /////////////////////////////////////////////////////////////////////////////// cruft::polled_duration::polled_duration (std::string name, uint64_t interval): m_name (std::move (name)), m_interval (interval), m_next (nanoseconds () + interval) { ; } //----------------------------------------------------------------------------- void cruft::polled_duration::start (void) { m_last = nanoseconds (); } //----------------------------------------------------------------------------- void cruft::polled_duration::stop (void) { uint64_t now = nanoseconds (); uint64_t dt = now - m_last; m_series.add (dt / MILLISECOND); if (m_next < now) { LOG_DEBUG ("timing: '{:s}'. {}", m_name, m_series); m_series.reset (); m_next = now + m_interval; } }