X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=common%2Futility%2Ftimer.h;h=ce399327572e9190ef87d6dfbe27e56523bb2adc;hb=f9c7bf3eee1eefc10e11d8d760d627c70a8d111f;hp=574391682d057b98d3ea59b3d66a07268721583e;hpb=69c89fd3ef41155fb4502091f4b3a68490cafda8;p=casparcg diff --git a/common/utility/timer.h b/common/utility/timer.h index 574391682..ce3993275 100644 --- a/common/utility/timer.h +++ b/common/utility/timer.h @@ -1,26 +1,84 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG 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. +* +* CasparCG 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 CasparCG. If not, see . +* +*/ #pragma once +#define NOMINMAX + #include +#include namespace caspar { -class timer +class high_prec_timer { public: - timer() : time_(timeGetTime()){} - - double elapsed() + high_prec_timer() + : time_(0) { - return static_cast(timeGetTime() - time_)/1000.0; } - - void reset() - { - time_ = timeGetTime(); - } - + + // Author: Ryan M. Geiss + // http://www.geisswerks.com/ryan/FAQS/timing.html + void tick(double interval) + { + auto t = ::timeGetTime(); + + if (time_ != 0) + { + auto ticks_to_wait = static_cast(interval*1000.0); + bool done = 0; + do + { + auto ticks_passed = t - time_; + auto ticks_left = ticks_to_wait - ticks_passed; + + if (t < time_) // time wrap + done = 1; + if (ticks_passed >= ticks_to_wait) + done = 1; + + if (!done) + { + // if > 0.002s left, do Sleep(1), which will actually sleep some + // steady amount, probably 1-2 ms, + // and do so in a nice way (cpu meter drops; laptop battery spared). + // otherwise, do a few Sleep(0)'s, which just give up the timeslice, + // but don't really save cpu or battery, but do pass a tiny + // amount of time. + if (ticks_left > 2) + Sleep(1); + else + for (int i = 0; i < 10; ++i) + Sleep(0); // causes thread to give up its timeslice + } + + t = ::timeGetTime(); + } + while (!done); + } + + time_ = t; + } private: DWORD time_; }; + } \ No newline at end of file