/** * File: TimeMs.cc * Project: libvdr - classes taken from vdr-project * * from "Video Disk Recorder": * * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger * * 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 2 * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * The original author can be reached at kls@tvdr.de * * The vdr project's page is at http://www.tvdr.de * */ #include #include #include #include #include #include #include cTimeMs::cTimeMs(int Ms) { if (Ms >= 0) Set(Ms); else begin = 0; } uint64_t cTimeMs::Now(void) { #if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) #define MIN_RESOLUTION 5 // ms static bool initialized = false; static bool monotonic = false; struct timespec tp; if (!initialized) { // check if monotonic timer is available and provides enough accurate resolution: if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) { long Resolution = tp.tv_nsec; // require a minimum resolution: if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) { if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) { dsyslog("cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution); monotonic = true; } else esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed"); } else dsyslog("cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec); } else esyslog("cTimeMs: clock_getres(CLOCK_MONOTONIC) failed"); initialized = true; } if (monotonic) { if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000; esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed"); monotonic = false; // fall back to gettimeofday() } #else # warning Posix monotonic clock not available #endif struct timeval t; if (gettimeofday(&t, NULL) == 0) return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000; return 0; } void cTimeMs::Set(int Ms) { begin = Now() + Ms; } bool cTimeMs::TimedOut(void) { return Now() >= begin; } uint64_t cTimeMs::Elapsed(void) { return Now() - begin; }