BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
c940aec
Branches
Tags
master
Blinker
src
linux
Time.cpp
bugfix for neg. times
Stefan Schuermans
commited
c940aec
at 2017-09-24 10:45:58
Time.cpp
Blame
History
Raw
/* Blinker Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <errno.h> #include <math.h> #include <stdint.h> #include <sys/time.h> #include <time.h> #include "Time.h" namespace Blinker { const Time Time::zero(0); ///< zero time /** * @brief get current time * @return current time */ Time Time::now() { Time now; struct timeval tv; gettimeofday(&tv, NULL); now.m_sec = tv.tv_sec; now.m_ns = tv.tv_usec * 1000; return now; } /// constructor Time::Time(): m_sec(0), m_ns(0) { } /** * @brief constructor from seconds * @param[in] t time in seconds */ Time::Time(time_t t): m_sec(t), m_ns(0) { } /// comparison //@{ int Time::compare(const Time &that) const { if (m_sec < that.m_sec) return -1; if (m_sec > that.m_sec) return 1; if (m_ns < that.m_ns) return -1; if (m_ns > that.m_ns) return 1; return 0; } bool Time::operator==(const Time &that) const { return compare(that) == 0; } bool Time::operator!=(const Time &that) const { return compare(that) != 0; } bool Time::operator<(const Time &that) const { return compare(that) < 0; } bool Time::operator>(const Time &that) const { return compare(that) > 0; } bool Time::operator<=(const Time &that) const { return compare(that) <= 0; } bool Time::operator>=(const Time &that) const { return compare(that) >= 0; } //@} /// arithmetic //@{ const Time & Time::operator+=(const Time &that) { m_sec += that.m_sec; m_ns += that.m_ns; fix(); return *this; } const Time & Time::operator-=(const Time &that) { m_sec -= that.m_sec; m_ns -= that.m_ns; fix(); return *this; } Time Time::operator+(const Time &that) const { Time result(*this); result += that; return result; } Time Time::operator-(const Time &that) const { Time result(*this); result -= that; return result; } //@} /** * @brief convert from floating point seconds * @param[in] s time in seconds */ void Time::fromFloatSec(float s) { m_sec = (int64_t)truncf(s); m_ns = (int64_t)((s - m_sec) * 1.0e9); } /** * @brief convert from milliseconds * @param[in] ms milliseconds */ void Time::fromMs(int ms) { if (ms >= 0) { m_sec = ms / 1000; m_ns = (ms % 1000) * 1000000; } else { m_sec = -(-ms / 1000); m_ns = -(-ms % 1000) * 1000000; } } /** * @brief convert to seconds * @return seconds */ time_t Time::toSec() const { if (m_ns >= 500000000) return m_sec + 1; else if (m_ns <= -500000000) return m_sec - 1; else return m_sec; } /** * @brief convert to floating point seconds * @return time in seconds */ float Time::toFloatSec() const { return m_sec + m_ns * 1.0e-9f; } /** * @brief convert to struct timeval * @param[out] tv struct timeval */ void Time::toTimeval(struct timeval &tv) const { if (m_sec >= 0) { tv.tv_sec = m_sec; tv.tv_usec = (m_ns + 500) / 1000; if (tv.tv_usec >= 1000000) { ++tv.tv_sec; tv.tv_usec -= 1000000; } } else { tv.tv_sec = m_sec; tv.tv_usec = -((-m_ns + 500) / 1000); if (tv.tv_usec <= -1000000) { --tv.tv_sec; tv.tv_usec += 1000000; } } } /// fix internal time representation after calculation void Time::fix() { if (m_ns >= 1000000000) { m_sec += m_ns / 1000000000; m_ns = m_ns % 1000000000; } else if (m_ns <= -1000000000) { m_sec -= -m_ns / 1000000000; m_ns = -(-m_ns % 1000000000); } if (m_sec > 0 && m_ns < 0) { m_sec -= 1; m_ns += 1000000000; } else if (m_sec < 0 && m_ns > 0) { m_sec += 1; m_ns -= 1000000000; } } /// sleep for duration void Time::sleepFor() const { // do not sleep for negative time if (*this < zero) return; // sleep struct timespec req, rem; req.tv_sec = m_sec; req.tv_nsec = m_ns; while (nanosleep(&req, &rem) && errno == EINTR) req = rem; } /// sleep until time void Time::sleepUntil() const { (*this - now()).sleepFor(); } } // namespace Blinker