2009-03-01 13:13:25 +00:00
|
|
|
/*
|
2014-03-09 15:58:00 +00:00
|
|
|
* precise timer routines for Linux/UNIX
|
2009-03-01 13:13:25 +00:00
|
|
|
* copyright (C) LGB & A'rpi/ASTRAL
|
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* This file is part of mpv.
|
2009-03-01 13:13:25 +00:00
|
|
|
*
|
2017-05-05 10:34:56 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2009-03-01 13:13:25 +00:00
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2009-03-01 13:13:25 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2017-05-05 10:34:56 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2009-03-01 13:13:25 +00:00
|
|
|
*
|
2017-05-05 10:34:56 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2009-03-01 13:13:25 +00:00
|
|
|
*/
|
2001-02-24 20:28:24 +00:00
|
|
|
|
2023-10-28 19:17:28 +00:00
|
|
|
#include <errno.h>
|
2002-03-24 00:58:27 +00:00
|
|
|
#include <stdlib.h>
|
2001-10-25 23:34:14 +00:00
|
|
|
#include <time.h>
|
2023-10-28 19:17:28 +00:00
|
|
|
|
|
|
|
#include "common/common.h"
|
2008-08-12 10:46:01 +00:00
|
|
|
#include "timer.h"
|
2001-02-24 20:28:24 +00:00
|
|
|
|
2023-10-28 19:17:28 +00:00
|
|
|
static clockid_t clk_id;
|
|
|
|
|
2023-09-29 22:24:21 +00:00
|
|
|
void mp_sleep_ns(int64_t ns)
|
2001-10-19 02:16:21 +00:00
|
|
|
{
|
2023-09-29 22:24:21 +00:00
|
|
|
if (ns < 0)
|
2013-05-17 17:54:37 +00:00
|
|
|
return;
|
2001-10-19 02:16:21 +00:00
|
|
|
struct timespec ts;
|
2023-10-22 02:31:36 +00:00
|
|
|
ts.tv_sec = ns / MP_TIME_S_TO_NS(1);
|
|
|
|
ts.tv_nsec = ns % MP_TIME_S_TO_NS(1);
|
2013-05-17 17:54:37 +00:00
|
|
|
nanosleep(&ts, NULL);
|
2014-03-09 15:58:00 +00:00
|
|
|
}
|
2001-10-19 02:16:21 +00:00
|
|
|
|
2023-09-10 00:09:28 +00:00
|
|
|
uint64_t mp_raw_time_ns(void)
|
timer: switch to CLOCK_MONOTONIC
Apparently, this is always _really_ monotonic, despite what the Linux
manpages say. So this should be much better than gettimeofday(). (At
times there were kernel bugs which broke the monotonic property.)
From the perspective of the player, time can still be discontinuous
(you could just stop the process with ^Z), but at least it's guaranteed
to be monotonic without further hacks required.
Also note that clock_gettime() returns the time in nanoseconds. We want
microseconds only, because that's the unit we chose internally. Another
problem is that nanoseconds can wrap pretty quickly (less than 300 years
in 63 bits), so it's just better to use microseconds. The devision won't
make the code that much slower (compilers can avoid a real division).
Note: this expects that the system provides clock_gettime() as well as
CLOCK_MONOTONIC. Both are optional according to POSIX. The only system
I know which doesn't have these, OSX, has seperate timer code anyway,
but I still don't know whether more obscure (yet supported) platforms
have a problem with this, so I'm playing safely. But this still expects
that CLOCK_MONOTONIC always works at runtime if it's defined.
2014-03-09 14:34:26 +00:00
|
|
|
{
|
2023-09-10 00:09:28 +00:00
|
|
|
struct timespec tp = {0};
|
2023-10-28 19:17:28 +00:00
|
|
|
clock_gettime(clk_id, &tp);
|
2023-10-22 02:31:36 +00:00
|
|
|
return MP_TIME_S_TO_NS(tp.tv_sec) + tp.tv_nsec;
|
2023-09-10 00:09:28 +00:00
|
|
|
}
|
2001-02-24 20:28:24 +00:00
|
|
|
|
2013-05-17 17:54:37 +00:00
|
|
|
void mp_raw_time_init(void)
|
2009-04-19 22:27:02 +00:00
|
|
|
{
|
2023-10-28 19:17:28 +00:00
|
|
|
static const clockid_t clock_ids[] = {
|
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
|
|
|
CLOCK_MONOTONIC_RAW,
|
|
|
|
#endif
|
|
|
|
CLOCK_MONOTONIC,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct timespec tp;
|
|
|
|
for (int i = 0; i < MP_ARRAY_SIZE(clock_ids); ++i) {
|
|
|
|
clk_id = clock_ids[i];
|
|
|
|
if (!clock_gettime(clk_id, &tp))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fputs("No clock source available!\n", stderr);
|
|
|
|
abort();
|
2001-02-24 20:28:24 +00:00
|
|
|
}
|