Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2018-11-29 14:56:18 +0300
committerCorinna Vinschen <corinna@vinschen.de>2018-11-29 15:03:54 +0300
commit43e8fddfa654365f96ffa87825a99ccc63cfa0db (patch)
tree1adf889d3ecc257d6a402b77eca4e554d9cd25e7
parent09870c6e958cf32fd62676e742c1c70d378a90a1 (diff)
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>
-rw-r--r--winsup/cygwin/clock.cc37
-rw-r--r--winsup/cygwin/clock.h4
2 files changed, 26 insertions, 15 deletions
diff --git a/winsup/cygwin/clock.cc b/winsup/cygwin/clock.cc
index 99d0a281b..0c8390a49 100644
--- a/winsup/cygwin/clock.cc
+++ b/winsup/cygwin/clock.cc
@@ -6,16 +6,17 @@
#include "spinlock.h"
static LONGLONG
-system_qpc_resolution ()
+system_qpc_tickspersec ()
{
LARGE_INTEGER qpf;
+ /* ticks per sec */
QueryPerformanceFrequency (&qpf);
return qpf.QuadPart;
}
static LONGLONG
-system_tickcount_resolution ()
+system_tickcount_period ()
{
ULONG coarsest = 0, finest, actual;
@@ -26,7 +27,7 @@ system_tickcount_resolution ()
can rely on is the coarsest value. */
NtQueryTimerResolution (&coarsest, &finest, &actual);
}
- return NS100PERSEC / coarsest;
+ return coarsest;
}
void
@@ -34,7 +35,7 @@ clk_t::init ()
{
spinlock spin (inited, 1);
if (!spin)
- ticks_per_sec = system_tickcount_resolution ();
+ period = system_tickcount_period ();
}
void
@@ -42,9 +43,12 @@ clk_realtime_t::init ()
{
spinlock spin (inited, 1);
if (!spin)
- ticks_per_sec = wincap.has_precise_system_time ()
- ? system_qpc_resolution ()
- : system_tickcount_resolution ();
+ {
+ if (wincap.has_precise_system_time ())
+ ticks_per_sec = system_qpc_tickspersec ();
+ else
+ period = system_tickcount_period ();
+ }
}
void
@@ -52,7 +56,7 @@ clk_monotonic_t::init ()
{
spinlock spin (inited, 1);
if (!spin)
- ticks_per_sec = system_qpc_resolution ();
+ ticks_per_sec = system_qpc_tickspersec ();
}
int
@@ -202,16 +206,16 @@ clk_monotonic_coarse_t::now (clockid_t clockid, struct timespec *ts)
}
else
{
- /* Vista-only: GetTickCount64 is biased but it's coarse and
- monotonic. */
- LONGLONG now;
+ /* Vista-only: GetTickCount64 is biased but it's coarse and monotonic. */
+ ULONGLONG now;
if (inited <= 0)
init ();
now = GetTickCount64 ();
- ts->tv_sec = now / ticks_per_sec;
- now %= ticks_per_sec;
- ts->tv_nsec = (now * NSPERSEC) / ticks_per_sec;
+ now *= period; /* Normalize to 100ns period */
+ ts->tv_sec = now / NS100PERSEC;
+ now %= NS100PERSEC;
+ ts->tv_nsec = now * (NSPERSEC/NS100PERSEC);
}
return 0;
}
@@ -249,7 +253,10 @@ clk_t::resolution (struct timespec *ts)
if (inited <= 0)
init ();
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;
diff --git a/winsup/cygwin/clock.h b/winsup/cygwin/clock.h
index 3c5bd5fbd..075aaed1d 100644
--- a/winsup/cygwin/clock.h
+++ b/winsup/cygwin/clock.h
@@ -53,7 +53,11 @@ class clk_t
{
protected:
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 period;
virtual void init ();
virtual int now (clockid_t, struct timespec *) = 0;