public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
@ 2012-03-21 23:00 Christian Franke
  2012-03-22  9:34 ` Corinna Vinschen
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Franke @ 2012-03-21 23:00 UTC (permalink / raw)
  To: cygwin

clock_getres(CLOCK_REALTIME, &ts) queries the actual resolution through
NtQueryTimerResolution (&coarsest, &finest, &actual) during its first 
call and returns this value unchanged afterwards.

This returns a global Windows setting which may be temporarily modified 
by other applications by using e.g. timeBegin/EndPeriod(). For example 
playing a flash video in browser sets the resolution to 1ms. It is reset 
to default ~15ms when the browser is closed.

As a consequence the actual resolution might be much lower than reported 
by clock_getres() when clock_gettime() is used for measurements later. 
It would IMO be better to return the 'coarsest' instead of the 'actual' 
value.

If clock_setres() is used, this setting should be returned instead of 
the 'actual' value at the time of the setting.

BTW: GetSystemTimeAsFileTime() apparently provides the same resolution 
(at least on Win7 x64). So the more complex use of 
SharedUserData.InterruptTime may have less benefit than expected.

Christian


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-21 23:00 clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution Christian Franke
@ 2012-03-22  9:34 ` Corinna Vinschen
  2012-03-22  9:39   ` Peter Rosin
  2012-03-22 17:47   ` Christian Franke
  0 siblings, 2 replies; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-22  9:34 UTC (permalink / raw)
  To: cygwin

On Mar 21 23:59, Christian Franke wrote:
> clock_getres(CLOCK_REALTIME, &ts) queries the actual resolution through
> NtQueryTimerResolution (&coarsest, &finest, &actual) during its
> first call and returns this value unchanged afterwards.
> 
> This returns a global Windows setting which may be temporarily
> modified by other applications by using e.g. timeBegin/EndPeriod().
> For example playing a flash video in browser sets the resolution to
> 1ms. It is reset to default ~15ms when the browser is closed.
> 
> As a consequence the actual resolution might be much lower than
> reported by clock_getres() when clock_gettime() is used for
> measurements later. It would IMO be better to return the 'coarsest'
> instead of the 'actual' value.

clock_getres already returns the coarsest time.  Did you mean the
setting in hires_ms::resolution, by any chance?  It's using the
actual setting right now.

> If clock_setres() is used, this setting should be returned instead
> of the 'actual' value at the time of the setting.

Well, I'm not overly concerned about clock_setres, given that it's
probably not used at all :)

> BTW: GetSystemTimeAsFileTime() apparently provides the same
> resolution (at least on Win7 x64). So the more complex use of
> SharedUserData.InterruptTime may have less benefit than expected.

On pre-Vista, the accuracy of GetSystemTimeAsFileTime is 15.625 ms,
fixed.  On Vista and later it seems to be 15ms or better, but its
resultion is not constant anymore.

But I'm not shure either, if the timeGetTime_ns shuffle has any positive
effect.  Given that we allow a jitter of 40 ms, we''re potentially worse
off than by just calling GetSystemTimeAsFileTime and be done with it.
Also, all processes would be guaranteed to be on the same time, not only
the processes within the same session sharing gtod.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-22  9:34 ` Corinna Vinschen
@ 2012-03-22  9:39   ` Peter Rosin
  2012-03-22  9:50     ` Corinna Vinschen
  2012-03-22 17:47   ` Christian Franke
  1 sibling, 1 reply; 14+ messages in thread
From: Peter Rosin @ 2012-03-22  9:39 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen skrev 2012-03-22 10:33:
> On Mar 21 23:59, Christian Franke wrote:
>> BTW: GetSystemTimeAsFileTime() apparently provides the same
>> resolution (at least on Win7 x64). So the more complex use of
>> SharedUserData.InterruptTime may have less benefit than expected.
> 
> On pre-Vista, the accuracy of GetSystemTimeAsFileTime is 15.625 ms,
> fixed.  On Vista and later it seems to be 15ms or better, but its
> resultion is not constant anymore.

I have definite memories of an (albeit odd) XP laptop with 10 ms
accuracy.  But that was years ago.  Hmmm?

Cheers,
Peter

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-22  9:39   ` Peter Rosin
@ 2012-03-22  9:50     ` Corinna Vinschen
  0 siblings, 0 replies; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-22  9:50 UTC (permalink / raw)
  To: cygwin

On Mar 22 10:39, Peter Rosin wrote:
> Corinna Vinschen skrev 2012-03-22 10:33:
> > On Mar 21 23:59, Christian Franke wrote:
> >> BTW: GetSystemTimeAsFileTime() apparently provides the same
> >> resolution (at least on Win7 x64). So the more complex use of
> >> SharedUserData.InterruptTime may have less benefit than expected.
> > 
> > On pre-Vista, the accuracy of GetSystemTimeAsFileTime is 15.625 ms,
> > fixed.  On Vista and later it seems to be 15ms or better, but its
> > resultion is not constant anymore.
> 
> I have definite memories of an (albeit odd) XP laptop with 10 ms
> accuracy.  But that was years ago.  Hmmm?

Oh, right.  It depends on the hardware.  Some commenter on
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724397%28v=vs.85%29.aspx
mentions that.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-22  9:34 ` Corinna Vinschen
  2012-03-22  9:39   ` Peter Rosin
@ 2012-03-22 17:47   ` Christian Franke
  2012-03-26  8:52     ` Corinna Vinschen
  1 sibling, 1 reply; 14+ messages in thread
From: Christian Franke @ 2012-03-22 17:47 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 3724 bytes --]

Corinna Vinschen wrote:
> On Mar 21 23:59, Christian Franke wrote:
>> clock_getres(CLOCK_REALTIME,&ts) queries the actual resolution through
>> NtQueryTimerResolution (&coarsest,&finest,&actual) during its
>> first call and returns this value unchanged afterwards.
>>
>> This returns a global Windows setting which may be temporarily
>> modified by other applications by using e.g. timeBegin/EndPeriod().
>> For example playing a flash video in browser sets the resolution to
>> 1ms. It is reset to default ~15ms when the browser is closed.
>>
>> As a consequence the actual resolution might be much lower than
>> reported by clock_getres() when clock_gettime() is used for
>> measurements later. It would IMO be better to return the 'coarsest'
>> instead of the 'actual' value.
> clock_getres already returns the coarsest time.  Did you mean the
> setting in hires_ms::resolution, by any chance?  It's using the
> actual setting right now.

No. Yes.

No, clock_getres(CLOCK_REALTIME, .) returns gtod.resolution() which 
calls hires_ms::resolution().

Yes, I mean this function which returns the 'actual' value from 
NtQueryTimerResolution(:-).


>> If clock_setres() is used, this setting should be returned instead
>> of the 'actual' value at the time of the setting.
> Well, I'm not overly concerned about clock_setres, given that it's
> probably not used at all :)

Yes, it is not POSIX and does not exist on Linux, FreeBSD, ...

It IMO is useful as CLOCK_REALTIME does only provide a rather coarse 
default resolution on Cygwin.


>> BTW: GetSystemTimeAsFileTime() apparently provides the same
>> resolution (at least on Win7 x64). So the more complex use of
>> SharedUserData.InterruptTime may have less benefit than expected.
> On pre-Vista, the accuracy of GetSystemTimeAsFileTime is 15.625 ms,
> fixed.  On Vista and later it seems to be 15ms or better, but its
> resultion is not constant anymore.


Here a run of a test program (attached) and some concurrent activities. 
Program prints observable resolutions of 3 clocks (clock_getres() 
results in parentheses):

[1] ./testres started/stopped to read default resolutions.
SystemTime  CLOCK_REALTIME (getres)     CLOCK_MONOTONIC (getres)
0.0156000   0.015600000 (0.015600000)   0.000000301 (0.000000301) ...
^C

[2] flash video started in SeaMonkey

[3] ./testres started
SystemTime  CLOCK_REALTIME (getres)     CLOCK_MONOTONIC (getres)
0.0010000   0.001000000 (0.001000000)   0.000000302 (0.000000301) ...
0.0005000   0.000500000 (0.001000000)   0.000000302 (0.000000301) [4]
0.0010000   0.001000000 (0.001000000)   0.000000301 (0.000000301) [5]
0.0156000   0.015600000 (0.001000000)   0.000000302 (0.000000301) [6]

Where:
[4] VM started in VirtualBox
[5] VM closed
[6] SeaMonkey closed


Conclusions:
- clock_getres() returns the 'actual' resolution from its first call. 
IMO this is a bug.
- The actual resolution may change without notice unless an application 
sets the min resolution (500us on this machine) itself.
- On Win7, GetSystemTimeAsFileTime() provides same resolution as 
InterruptTime and timeGetTime(). Could not test this on older Windows 
versions yet.
- Unlike on e.g. Linux, CLOCK_REALTIME does not provide a better 
resolution than gettimeofday().


> But I'm not shure either, if the timeGetTime_ns shuffle has any positive
> effect.  Given that we allow a jitter of 40 ms, we''re potentially worse
> off than by just calling GetSystemTimeAsFileTime and be done with it.
> Also, all processes would be guaranteed to be on the same time, not only
> the processes within the same session sharing gtod.
>

If this is also the case for older Windows versions, it would be 
probably better to revert to GetSystemTimeAsFileTime().

Christian


[-- Attachment #2: testres.cc --]
[-- Type: text/plain, Size: 1702 bytes --]

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <windows.h>

static long long get_win32_time(int)
{
  FILETIME ft;
  GetSystemTimeAsFileTime(&ft);
  LARGE_INTEGER it = { { ft.dwLowDateTime, ft.dwHighDateTime } };
  return it.QuadPart;
}

static long long get_posix_time(int id)
{
  timespec ts;
  if (clock_gettime(id, &ts))
    return -1;
  return ts.tv_sec * 1000000000LL + ts.tv_nsec;
}

static long long get_posix_res(int id)
{
  timespec ts;
  if (clock_getres(id, &ts))
    return -1;
  return ts.tv_sec * 1000000000LL + ts.tv_nsec;
}

static long long guess_resolution(long long (*f)(int), int id = -1)
{
  long long r = ~0ULL>>1;
  for (int i = 0; i < 5; i++) {
    long long t1 = f(id), t2;
    do
      t2 = f(id);
    while (t2 >= 0 && t2 == t1);
    if (t2 - t1 < r)
      r = t2 - t1;
  }
  return r;
}
    
int main(int argc, char **argv)
{
  printf("SystemTime  CLOCK_REALTIME (getres)     CLOCK_MONOTONIC (getres)");
  long long r1 = -1, r2 = -1, r3 = -1;
  int cnt = 0;
  for (;;) {
    long long r1n = guess_resolution(get_win32_time);
    long long r2n = guess_resolution(get_posix_time, CLOCK_REALTIME);
    long long r3n = guess_resolution(get_posix_time, CLOCK_MONOTONIC);

    if (r1 == r1n && r2 == r2n && llabs(r3-r3n) <= 1) {
      printf("%s%5d", (cnt ? "\b\b\b\b\b" : ""), cnt); fflush(stdout);
      sleep(1);
      cnt++;
    }
    else {
      r1 = r1n; r2 = r2n; r3 = r3n;
      printf("\n%.7f   %.9f (%.9f)   %.9f (%.9f)",
        r1/10000000.0,
        r2/1000000000.0, get_posix_res(CLOCK_REALTIME) /1000000000.0,
        r3/1000000000.0, get_posix_res(CLOCK_MONOTONIC)/1000000000.0);
      fflush(stdout);
      cnt = 0;
    }
  }

  return 0;
}
 

[-- Attachment #3: Type: text/plain, Size: 218 bytes --]

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-22 17:47   ` Christian Franke
@ 2012-03-26  8:52     ` Corinna Vinschen
  2012-03-26 17:01       ` Christian Franke
  0 siblings, 1 reply; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-26  8:52 UTC (permalink / raw)
  To: cygwin

On Mar 22 18:47, Christian Franke wrote:
> Corinna Vinschen wrote:
> >clock_getres already returns the coarsest time.  Did you mean the
> >setting in hires_ms::resolution, by any chance?  It's using the
> >actual setting right now.
> 
> No. Yes.
> 
> No, clock_getres(CLOCK_REALTIME, .) returns gtod.resolution() which
> calls hires_ms::resolution().
> 
> Yes, I mean this function which returns the 'actual' value from
> NtQueryTimerResolution(:-).
> 
> 
> >>If clock_setres() is used, this setting should be returned instead
> >>of the 'actual' value at the time of the setting.
> >Well, I'm not overly concerned about clock_setres, given that it's
> >probably not used at all :)
> 
> Yes, it is not POSIX and does not exist on Linux, FreeBSD, ...
> 
> It IMO is useful as CLOCK_REALTIME does only provide a rather coarse
> default resolution on Cygwin.

I see your point, but what bugs me a bit is the fact that
clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
always return the same value coarsest, regardless what value has been set.

I added this comment to clock_setres at one point:

  /* Convert to 100ns to match OS resolution.  The OS uses ULONG values
     to express resolution in 100ns units, so the coarsest timer resolution
     is < 430 secs.  Actually the coarsest timer resolution is only slightly
     beyond 15ms, but this might change in future OS versions, so we play nice
     here. */

So, what if the OS really returns bigger values in coarsest at one
point?  I know, I know, that's unlikely to the point of non-existence.

> - Unlike on e.g. Linux, CLOCK_REALTIME does not provide a better
> resolution than gettimeofday().

We can only use what the OS provides.  Starting with Windows 8 there
will be a new function call GetSystemTimePreciseAsFileTime:
http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895%28v=vs.85%29.aspx

> >But I'm not shure either, if the timeGetTime_ns shuffle has any positive
> >effect.  Given that we allow a jitter of 40 ms, we''re potentially worse
> >off than by just calling GetSystemTimeAsFileTime and be done with it.
> >Also, all processes would be guaranteed to be on the same time, not only
> >the processes within the same session sharing gtod.
> 
> If this is also the case for older Windows versions, it would be
> probably better to revert to GetSystemTimeAsFileTime().

Yes, I'm going to do that.  I think you're right on all accounts, I'm
just feeling a bit uncomfortable with clock_setres always returning the
coarsest resolution.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-26  8:52     ` Corinna Vinschen
@ 2012-03-26 17:01       ` Christian Franke
  2012-03-27  9:11         ` Corinna Vinschen
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Franke @ 2012-03-26 17:01 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen wrote:
> On Mar 22 18:47, Christian Franke wrote:
>> Corinna Vinschen wrote:
>>> clock_getres already returns the coarsest time.  Did you mean the
>>> setting in hires_ms::resolution, by any chance?  It's using the
>>> actual setting right now.
>> No. Yes.
>>
>> No, clock_getres(CLOCK_REALTIME, .) returns gtod.resolution() which
>> calls hires_ms::resolution().
>>
>> Yes, I mean this function which returns the 'actual' value from
>> NtQueryTimerResolution(:-).
>>
>>
>>>> If clock_setres() is used, this setting should be returned instead
>>>> of the 'actual' value at the time of the setting.
>>> Well, I'm not overly concerned about clock_setres, given that it's
>>> probably not used at all :)
>> Yes, it is not POSIX and does not exist on Linux, FreeBSD, ...
>>
>> It IMO is useful as CLOCK_REALTIME does only provide a rather coarse
>> default resolution on Cygwin.
> I see your point, but what bugs me a bit is the fact that
> clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
> always return the same value coarsest, regardless what value has been set.

If clock_setres was called and succeeded, then clock_getres(.) should 
return the value set before.

If clock_setres was not called, the coarsest value is IMO the only value 
that can be guaranteed.

The actual value returned by NtQueryTimerResolution is simply useless in 
this context: It is the minimum of all resolutions currently set by all 
running processes. It may change at any time. There is apparently no way 
the query the current setting of the current process.


clock_gettime is part of the POSIX realtime extensions. On Linux it 
requires -lrt which implies -lpthreads. So if clock_gettime is used we 
can probably assume that the program wants a finer resolution.

This leads to a possible alternative if clock_setres is not used: On 
first call of clock_gettime/getres set a finer (the finest?) resolution 
and return this with clock_getres.

Drawback: The finer resolution will persist until this process and all 
childs terminate. This may have unknown impact on performance, power 
management or whatever.

This could be fixed by resetting the resolution to default if 
clock_gettime is no longer used for some time (e.g. >= 10min).

Drawback: Even more complexity :-)


> I added this comment to clock_setres at one point:
>
>    /* Convert to 100ns to match OS resolution.  The OS uses ULONG values
>       to express resolution in 100ns units, so the coarsest timer resolution
>       is<  430 secs.  Actually the coarsest timer resolution is only slightly
>       beyond 15ms, but this might change in future OS versions, so we play nice
>       here. */
>
> So, what if the OS really returns bigger values in coarsest at one
> point?  I know, I know, that's unlikely to the point of non-existence.
>
>> - Unlike on e.g. Linux, CLOCK_REALTIME does not provide a better
>> resolution than gettimeofday().
> We can only use what the OS provides.  Starting with Windows 8 there
> will be a new function call GetSystemTimePreciseAsFileTime:
> http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895%28v=vs.85%29.aspx

This would provide an easy solution for >= Win8: clock_gettime returns 
GetSystemTimePreciseAsFileTime, clock_getres returns constant 1us.

Christian


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-26 17:01       ` Christian Franke
@ 2012-03-27  9:11         ` Corinna Vinschen
  2012-03-27 18:02           ` Christian Franke
  0 siblings, 1 reply; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-27  9:11 UTC (permalink / raw)
  To: cygwin

On Mar 26 19:00, Christian Franke wrote:
> Corinna Vinschen wrote:
> >I see your point, but what bugs me a bit is the fact that
> >clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
> >always return the same value coarsest, regardless what value has been set.
> 
> If clock_setres was called and succeeded, then clock_getres(.)
> should return the value set before.
> 
> If clock_setres was not called, the coarsest value is IMO the only
> value that can be guaranteed.
> 
> The actual value returned by NtQueryTimerResolution is simply
> useless in this context: It is the minimum of all resolutions
> currently set by all running processes. It may change at any time.
> There is apparently no way the query the current setting of the
> current process.

Uh, right, I misunderstood.  I reverted the change to clock_setres.

> clock_gettime is part of the POSIX realtime extensions. On Linux it
> requires -lrt which implies -lpthreads. So if clock_gettime is used
> we can probably assume that the program wants a finer resolution.

Not really.  The usage of clock_gettime only implies that somebody wants
to measure time in a certain way depending on the used clock.  It does
not imply any resolution requirements.  And POSIX does not require any
specific resolutions, rather they are "implementation-defined".

> This leads to a possible alternative if clock_setres is not used: On
> first call of clock_gettime/getres set a finer (the finest?)
> resolution and return this with clock_getres.
> 
> Drawback: The finer resolution will persist until this process and
> all childs terminate. This may have unknown impact on performance,
> power management or whatever.
> 
> This could be fixed by resetting the resolution to default if
> clock_gettime is no longer used for some time (e.g. >= 10min).
> 
> Drawback: Even more complexity :-)

Nah, let's not go that route.  If you want a finer resolution by
default, I think there might be some other solution...

> >>- Unlike on e.g. Linux, CLOCK_REALTIME does not provide a better
> >>resolution than gettimeofday().
> >We can only use what the OS provides.  Starting with Windows 8 there
> >will be a new function call GetSystemTimePreciseAsFileTime:
> >http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895%28v=vs.85%29.aspx
> 
> This would provide an easy solution for >= Win8: clock_gettime
> returns GetSystemTimePreciseAsFileTime, clock_getres returns
> constant 1us.

As far as I can tell from a quick debug session, the implementation
of the underlying RtlGetSystemTimePrecise function is based on a spiffy
combination of the standard clock tick with the performance counter.
I'm not very good at assembler debugging, but the essence is access
to some known and some unknown time values from SharedUserData, a
call to RtlQueryPerformanceCounter, and a bit of arithmetic.

Maybe we can implement something similar without waiting for W8?  Does
anybody have code to combine a not so precise clock with a more precise
counter to create a more precise clock?


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-27  9:11         ` Corinna Vinschen
@ 2012-03-27 18:02           ` Christian Franke
  2012-03-27 18:29             ` Corinna Vinschen
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Franke @ 2012-03-27 18:02 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen wrote:
> On Mar 26 19:00, Christian Franke wrote:
>> Corinna Vinschen wrote:
>>> I see your point, but what bugs me a bit is the fact that
>>> clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
>>> always return the same value coarsest, regardless what value has been set.
>> If clock_setres was called and succeeded, then clock_getres(.)
>> should return the value set before.
>>
>> If clock_setres was not called, the coarsest value is IMO the only
>> value that can be guaranteed.
>>
>> The actual value returned by NtQueryTimerResolution is simply
>> useless in this context: It is the minimum of all resolutions
>> currently set by all running processes. It may change at any time.
>> There is apparently no way the query the current setting of the
>> current process.
> Uh, right, I misunderstood.  I reverted the change to clock_setres.

Sorry, I probably forgot to mention that NtSetTimerResolution returns 
the same useless actual value than NtQueryTimerResolution.

I would suggest:

     status = NtSetTimerResolution (period, TRUE, &actual);
     if (!NT_SUCCESS (status))
       { ... return -1; }
  -  minperiod = actual;
  +  minperiod = period;


>>>> - Unlike on e.g. Linux, CLOCK_REALTIME does not provide a better
>>>> resolution than gettimeofday().
>>> We can only use what the OS provides.  Starting with Windows 8 there
>>> will be a new function call GetSystemTimePreciseAsFileTime:
>>> http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895%28v=vs.85%29.aspx
>> This would provide an easy solution for>= Win8: clock_gettime
>> returns GetSystemTimePreciseAsFileTime, clock_getres returns
>> constant 1us.
> As far as I can tell from a quick debug session, the implementation
> of the underlying RtlGetSystemTimePrecise function is based on a spiffy
> combination of the standard clock tick with the performance counter.
> I'm not very good at assembler debugging, but the essence is access
> to some known and some unknown time values from SharedUserData, a
> call to RtlQueryPerformanceCounter, and a bit of arithmetic.
>
> Maybe we can implement something similar without waiting for W8?  Does
> anybody have code to combine a not so precise clock with a more precise
> counter to create a more precise clock?

The problem is that unlike the OS we don't have interrupts and probably 
don't want to start an extra thread which does timer calibrations.

It may be possible to implement a clock_gettime(CLOCK_REALTIME) which 
has the following properties (in most cases:-):
- Absolute time returned is in interval [GetSystemTime, 
GetSystemTime+coarsest)
- Differences between two returned times provide the resolution of the 
PerformanceCounter if the difference is small (tens of seconds).
I probably will have some time to check this next week.

Christian


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-27 18:02           ` Christian Franke
@ 2012-03-27 18:29             ` Corinna Vinschen
  2012-03-27 19:00               ` Christian Franke
  0 siblings, 1 reply; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-27 18:29 UTC (permalink / raw)
  To: cygwin

On Mar 27 20:01, Christian Franke wrote:
> Corinna Vinschen wrote:
> >On Mar 26 19:00, Christian Franke wrote:
> >>Corinna Vinschen wrote:
> >>>I see your point, but what bugs me a bit is the fact that
> >>>clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
> >>>always return the same value coarsest, regardless what value has been set.
> >>If clock_setres was called and succeeded, then clock_getres(.)
> >>should return the value set before.
> >>
> >>If clock_setres was not called, the coarsest value is IMO the only
> >>value that can be guaranteed.
> >>
> >>The actual value returned by NtQueryTimerResolution is simply
> >>useless in this context: It is the minimum of all resolutions
> >>currently set by all running processes. It may change at any time.
> >>There is apparently no way the query the current setting of the
> >>current process.
> >Uh, right, I misunderstood.  I reverted the change to clock_setres.
> 
> Sorry, I probably forgot to mention that NtSetTimerResolution
> returns the same useless actual value than NtQueryTimerResolution.
> 
> I would suggest:
> 
>     status = NtSetTimerResolution (period, TRUE, &actual);
>     if (!NT_SUCCESS (status))
>       { ... return -1; }
>  -  minperiod = actual;
>  +  minperiod = period;

But that's not right.  The "actual" value is not useless, but the value
the resolution has actually been set to.  The OS just doesn't support
arbitrary values for the period.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-27 18:29             ` Corinna Vinschen
@ 2012-03-27 19:00               ` Christian Franke
  2012-03-27 20:51                 ` Corinna Vinschen
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Franke @ 2012-03-27 19:00 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen wrote:
> On Mar 27 20:01, Christian Franke wrote:
>> Corinna Vinschen wrote:
>>> On Mar 26 19:00, Christian Franke wrote:
>>>> Corinna Vinschen wrote:
>>>>> I see your point, but what bugs me a bit is the fact that
>>>>> clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
>>>>> always return the same value coarsest, regardless what value has been set.
>>>> If clock_setres was called and succeeded, then clock_getres(.)
>>>> should return the value set before.
>>>>
>>>> If clock_setres was not called, the coarsest value is IMO the only
>>>> value that can be guaranteed.
>>>>
>>>> The actual value returned by NtQueryTimerResolution is simply
>>>> useless in this context: It is the minimum of all resolutions
>>>> currently set by all running processes. It may change at any time.
>>>> There is apparently no way the query the current setting of the
>>>> current process.
>>> Uh, right, I misunderstood.  I reverted the change to clock_setres.
>> Sorry, I probably forgot to mention that NtSetTimerResolution
>> returns the same useless actual value than NtQueryTimerResolution.
>>
>> I would suggest:
>>
>>      status = NtSetTimerResolution (period, TRUE,&actual);
>>      if (!NT_SUCCESS (status))
>>        { ... return -1; }
>>   -  minperiod = actual;
>>   +  minperiod = period;
> But that's not right.  The "actual" value is not useless, but the value
> the resolution has actually been set to.

No, again this is the minimum of all resolutions currently set by all 
processes.


>    The OS just doesn't support
> arbitrary values for the period.
>

Yes - but in 'actual' a smaller value than the value set for the current 
process may be returned.

Christian


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-27 19:00               ` Christian Franke
@ 2012-03-27 20:51                 ` Corinna Vinschen
  2012-03-27 21:29                   ` Christian Franke
  0 siblings, 1 reply; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-27 20:51 UTC (permalink / raw)
  To: cygwin

On Mar 27 20:59, Christian Franke wrote:
> Corinna Vinschen wrote:
> >On Mar 27 20:01, Christian Franke wrote:
> >>Corinna Vinschen wrote:
> >>>On Mar 26 19:00, Christian Franke wrote:
> >>>>Corinna Vinschen wrote:
> >>>>>I see your point, but what bugs me a bit is the fact that
> >>>>>clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
> >>>>>always return the same value coarsest, regardless what value has been set.
> >>>>If clock_setres was called and succeeded, then clock_getres(.)
> >>>>should return the value set before.
> >>>>
> >>>>If clock_setres was not called, the coarsest value is IMO the only
> >>>>value that can be guaranteed.
> >>>>
> >>>>The actual value returned by NtQueryTimerResolution is simply
> >>>>useless in this context: It is the minimum of all resolutions
> >>>>currently set by all running processes. It may change at any time.
> >>>>There is apparently no way the query the current setting of the
> >>>>current process.
> >>>Uh, right, I misunderstood.  I reverted the change to clock_setres.
> >>Sorry, I probably forgot to mention that NtSetTimerResolution
> >>returns the same useless actual value than NtQueryTimerResolution.
> >>
> >>I would suggest:
> >>
> >>     status = NtSetTimerResolution (period, TRUE,&actual);
> >>     if (!NT_SUCCESS (status))
> >>       { ... return -1; }
> >>  -  minperiod = actual;
> >>  +  minperiod = period;
> >But that's not right.  The "actual" value is not useless, but the value
> >the resolution has actually been set to.
> 
> No, again this is the minimum of all resolutions currently set by
> all processes.
> 
> 
> >   The OS just doesn't support
> >arbitrary values for the period.
> >
> 
> Yes - but in 'actual' a smaller value than the value set for the
> current process may be returned.

Hmpf, ok.  Boy is that ugly.  Is there a chance that actual is bigger
than period?  In that case we should perhaps set minperiod like this:

  minperiod = MAX (actual, period);


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-27 20:51                 ` Corinna Vinschen
@ 2012-03-27 21:29                   ` Christian Franke
  2012-03-28  7:40                     ` Corinna Vinschen
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Franke @ 2012-03-27 21:29 UTC (permalink / raw)
  To: cygwin

Corinna Vinschen wrote:
> On Mar 27 20:59, Christian Franke wrote:
>> Corinna Vinschen wrote:
>>> On Mar 27 20:01, Christian Franke wrote:
>>>> Corinna Vinschen wrote:
>>>>> On Mar 26 19:00, Christian Franke wrote:
>>>>>> Corinna Vinschen wrote:
>>>>>>> I see your point, but what bugs me a bit is the fact that
>>>>>>> clock_getres(CLOCK_REALTIME) and clock_setres(CLOCK_REALTIME) will
>>>>>>> always return the same value coarsest, regardless what value has been set.
>>>>>> If clock_setres was called and succeeded, then clock_getres(.)
>>>>>> should return the value set before.
>>>>>>
>>>>>> If clock_setres was not called, the coarsest value is IMO the only
>>>>>> value that can be guaranteed.
>>>>>>
>>>>>> The actual value returned by NtQueryTimerResolution is simply
>>>>>> useless in this context: It is the minimum of all resolutions
>>>>>> currently set by all running processes. It may change at any time.
>>>>>> There is apparently no way the query the current setting of the
>>>>>> current process.
>>>>> Uh, right, I misunderstood.  I reverted the change to clock_setres.
>>>> Sorry, I probably forgot to mention that NtSetTimerResolution
>>>> returns the same useless actual value than NtQueryTimerResolution.
>>>>
>>>> I would suggest:
>>>>
>>>>      status = NtSetTimerResolution (period, TRUE,&actual);
>>>>      if (!NT_SUCCESS (status))
>>>>        { ... return -1; }
>>>>   -  minperiod = actual;
>>>>   +  minperiod = period;
>>> But that's not right.  The "actual" value is not useless, but the value
>>> the resolution has actually been set to.
>> No, again this is the minimum of all resolutions currently set by
>> all processes.
>>
>>
>>>    The OS just doesn't support
>>> arbitrary values for the period.
>>>
>> Yes - but in 'actual' a smaller value than the value set for the
>> current process may be returned.
> Hmpf, ok.  Boy is that ugly.

Yes, aka broken by design :-)

There should be a function to query the actual setting for the current 
process only. But there is none.


>    Is there a chance that actual is bigger
> than period?  In that case we should perhaps set minperiod like this:
>
>    minperiod = MAX (actual, period);

According to some experiments this can only happen if period < finest. 
In this case NtSetTimerResolution also succeeds and returns actual == 
finest.

Christian


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution
  2012-03-27 21:29                   ` Christian Franke
@ 2012-03-28  7:40                     ` Corinna Vinschen
  0 siblings, 0 replies; 14+ messages in thread
From: Corinna Vinschen @ 2012-03-28  7:40 UTC (permalink / raw)
  To: cygwin

On Mar 27 23:28, Christian Franke wrote:
> Corinna Vinschen wrote:
> >On Mar 27 20:59, Christian Franke wrote:
> >>>>Sorry, I probably forgot to mention that NtSetTimerResolution
> >>>>returns the same useless actual value than NtQueryTimerResolution.
> >>>>
> >>>>I would suggest:
> >>>>
> >>>>     status = NtSetTimerResolution (period, TRUE,&actual);
> >>>>     if (!NT_SUCCESS (status))
> >>>>       { ... return -1; }
> >>>>  -  minperiod = actual;
> >>>>  +  minperiod = period;
> >>>But that's not right.  The "actual" value is not useless, but the value
> >>>the resolution has actually been set to.
> >>No, again this is the minimum of all resolutions currently set by
> >>all processes.
> >>
> >>
> >>>   The OS just doesn't support
> >>>arbitrary values for the period.
> >>>
> >>Yes - but in 'actual' a smaller value than the value set for the
> >>current process may be returned.
> >Hmpf, ok.  Boy is that ugly.
> 
> Yes, aka broken by design :-)
> 
> There should be a function to query the actual setting for the
> current process only. But there is none.
> 
> 
> >   Is there a chance that actual is bigger
> >than period?  In that case we should perhaps set minperiod like this:
> >
> >   minperiod = MAX (actual, period);
> 
> According to some experiments this can only happen if period <
> finest. In this case NtSetTimerResolution also succeeds and returns
> actual == finest.

Since period < finest can't happen, I set minperiod to period now as
you suggested.  But, frankly, this would have been much simpler if
you would have send a patch right from the start ;)


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-03-28  7:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-21 23:00 clock_getres(CLOCK_REALTIME, .) may return an outdated and too high resolution Christian Franke
2012-03-22  9:34 ` Corinna Vinschen
2012-03-22  9:39   ` Peter Rosin
2012-03-22  9:50     ` Corinna Vinschen
2012-03-22 17:47   ` Christian Franke
2012-03-26  8:52     ` Corinna Vinschen
2012-03-26 17:01       ` Christian Franke
2012-03-27  9:11         ` Corinna Vinschen
2012-03-27 18:02           ` Christian Franke
2012-03-27 18:29             ` Corinna Vinschen
2012-03-27 19:00               ` Christian Franke
2012-03-27 20:51                 ` Corinna Vinschen
2012-03-27 21:29                   ` Christian Franke
2012-03-28  7:40                     ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).