Cygwin: clocks: use either tickcount or tick period
Use whatever native unit the system provides for the resolution of a timer to avoid rounding problems Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
09870c6e95
commit
43e8fddfa6
|
@ -6,16 +6,17 @@
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
|
|
||||||
static LONGLONG
|
static LONGLONG
|
||||||
system_qpc_resolution ()
|
system_qpc_tickspersec ()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER qpf;
|
LARGE_INTEGER qpf;
|
||||||
|
|
||||||
|
/* ticks per sec */
|
||||||
QueryPerformanceFrequency (&qpf);
|
QueryPerformanceFrequency (&qpf);
|
||||||
return qpf.QuadPart;
|
return qpf.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LONGLONG
|
static LONGLONG
|
||||||
system_tickcount_resolution ()
|
system_tickcount_period ()
|
||||||
{
|
{
|
||||||
ULONG coarsest = 0, finest, actual;
|
ULONG coarsest = 0, finest, actual;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ system_tickcount_resolution ()
|
||||||
can rely on is the coarsest value. */
|
can rely on is the coarsest value. */
|
||||||
NtQueryTimerResolution (&coarsest, &finest, &actual);
|
NtQueryTimerResolution (&coarsest, &finest, &actual);
|
||||||
}
|
}
|
||||||
return NS100PERSEC / coarsest;
|
return coarsest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -34,7 +35,7 @@ clk_t::init ()
|
||||||
{
|
{
|
||||||
spinlock spin (inited, 1);
|
spinlock spin (inited, 1);
|
||||||
if (!spin)
|
if (!spin)
|
||||||
ticks_per_sec = system_tickcount_resolution ();
|
period = system_tickcount_period ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -42,9 +43,12 @@ clk_realtime_t::init ()
|
||||||
{
|
{
|
||||||
spinlock spin (inited, 1);
|
spinlock spin (inited, 1);
|
||||||
if (!spin)
|
if (!spin)
|
||||||
ticks_per_sec = wincap.has_precise_system_time ()
|
{
|
||||||
? system_qpc_resolution ()
|
if (wincap.has_precise_system_time ())
|
||||||
: system_tickcount_resolution ();
|
ticks_per_sec = system_qpc_tickspersec ();
|
||||||
|
else
|
||||||
|
period = system_tickcount_period ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -52,7 +56,7 @@ clk_monotonic_t::init ()
|
||||||
{
|
{
|
||||||
spinlock spin (inited, 1);
|
spinlock spin (inited, 1);
|
||||||
if (!spin)
|
if (!spin)
|
||||||
ticks_per_sec = system_qpc_resolution ();
|
ticks_per_sec = system_qpc_tickspersec ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -202,16 +206,16 @@ clk_monotonic_coarse_t::now (clockid_t clockid, struct timespec *ts)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Vista-only: GetTickCount64 is biased but it's coarse and
|
/* Vista-only: GetTickCount64 is biased but it's coarse and monotonic. */
|
||||||
monotonic. */
|
ULONGLONG now;
|
||||||
LONGLONG now;
|
|
||||||
|
|
||||||
if (inited <= 0)
|
if (inited <= 0)
|
||||||
init ();
|
init ();
|
||||||
now = GetTickCount64 ();
|
now = GetTickCount64 ();
|
||||||
ts->tv_sec = now / ticks_per_sec;
|
now *= period; /* Normalize to 100ns period */
|
||||||
now %= ticks_per_sec;
|
ts->tv_sec = now / NS100PERSEC;
|
||||||
ts->tv_nsec = (now * NSPERSEC) / ticks_per_sec;
|
now %= NS100PERSEC;
|
||||||
|
ts->tv_nsec = now * (NSPERSEC/NS100PERSEC);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +253,10 @@ clk_t::resolution (struct timespec *ts)
|
||||||
if (inited <= 0)
|
if (inited <= 0)
|
||||||
init ();
|
init ();
|
||||||
ts->tv_sec = 0;
|
ts->tv_sec = 0;
|
||||||
ts->tv_nsec = NSPERSEC / ticks_per_sec;
|
if (ticks_per_sec)
|
||||||
|
ts->tv_nsec = NSPERSEC / ticks_per_sec;
|
||||||
|
else
|
||||||
|
ts->tv_nsec = period * (NSPERSEC/NS100PERSEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static clk_realtime_coarse_t clk_realtime_coarse;
|
static clk_realtime_coarse_t clk_realtime_coarse;
|
||||||
|
|
|
@ -53,7 +53,11 @@ class clk_t
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
LONG inited;
|
LONG inited;
|
||||||
|
/* Some values are returned as ticks/s, some as 100ns period of a
|
||||||
|
single tick. Store the original value and use a computation method
|
||||||
|
making the most sense for the value given, to avoid rounding issues. */
|
||||||
LONGLONG ticks_per_sec;
|
LONGLONG ticks_per_sec;
|
||||||
|
LONGLONG period;
|
||||||
virtual void init ();
|
virtual void init ();
|
||||||
virtual int now (clockid_t, struct timespec *) = 0;
|
virtual int now (clockid_t, struct timespec *) = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue