// ----------------------------------------------------------------------
// File: IntervalStopwatch.cc
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2019 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "common/IntervalStopwatch.hh"
#include "common/SteadyClock.hh"
EOSCOMMONNAMESPACE_BEGIN
//------------------------------------------------------------------------------
//! Constructor. It's possible to pass a fake clock for testing - if none is
//! passed, a default one will be used.
//!
//! The first cycle starts as soon as the constructor is called, with the
//! given duration. (zero by default)
//------------------------------------------------------------------------------
IntervalStopwatch::IntervalStopwatch(std::chrono::milliseconds initialCycleDuration,
SteadyClock *clock) : mClock(clock) {
startCycle(initialCycleDuration);
}
//------------------------------------------------------------------------------
// Start a cycle from this point onwards, with the given duration.
// The previously running cycle is discarded.
//------------------------------------------------------------------------------
void IntervalStopwatch::startCycle(std::chrono::milliseconds duration) {
mCycleStart = common::SteadyClock::now(mClock);
mCycleDuration = duration;
}
//------------------------------------------------------------------------------
// Get timepoint of cycle start
//------------------------------------------------------------------------------
std::chrono::steady_clock::time_point IntervalStopwatch::getCycleStart() const {
return mCycleStart;
}
//------------------------------------------------------------------------------
// Return how much time has elapsed within this cycle, ie milliseconds since
// startCycle was called.
//------------------------------------------------------------------------------
std::chrono::milliseconds IntervalStopwatch::timeIntoCycle() const {
return std::chrono::duration_cast(
common::SteadyClock::now(mClock) - mCycleStart);
}
//------------------------------------------------------------------------------
// Return how much time is remaining in this cycle. If more time has elapsed
// than the cycle duration, this function returns 0.
//------------------------------------------------------------------------------
std::chrono::milliseconds IntervalStopwatch::timeRemainingInCycle() const {
std::chrono::milliseconds elapsed =
std::chrono::duration_cast(
common::SteadyClock::now(mClock) - mCycleStart);
std::chrono::milliseconds remaining = mCycleDuration - elapsed;
if(remaining < std::chrono::milliseconds(0)) {
remaining = std::chrono::milliseconds(0);
}
return remaining;
}
//------------------------------------------------------------------------------
// Convenience function - if the cycle has expired:
// - Restart from this point on, with the same exact duration.
// - Return true.
// Else, return false and do nothing else.
//------------------------------------------------------------------------------
bool IntervalStopwatch::restartIfExpired() {
if(timeRemainingInCycle() == std::chrono::milliseconds(0)) {
startCycle(mCycleDuration);
return true;
}
return false;
}
EOSCOMMONNAMESPACE_END