[PATCH] clock_nanosleep(2), pthread_condattr_[gs]etclock(3)

Yaakov (Cygwin/X) yselkowitz@users.sourceforge.net
Thu Jul 21 02:22:00 GMT 2011


On Wed, 2011-07-20 at 17:03 -0500, Yaakov (Cygwin/X) wrote:
> On Wed, 2011-07-20 at 16:11 +0200, Corinna Vinschen wrote:
> > The only problem I see is the fact that a call to clock_settime
> > influences calls to clock_nanosleep with absolute timeouts(*).

However, clock_settime() can set only CLOCK_REALTIME, not
CLOCK_MONOTONIC, so...

> > The problem is that we convert absolute timeouts to relative timeouts
> > and then use the timeout facility of the WFMO function to handle the
> > timeout for us.  IMO this is neither very reliable, nor is it elegant.
> > 
> > So, here's the question.  Shouldn't we better use waitable timers
> > to implement this sort of stuff?  Waitable timers are pretty easy to
> > use, they support relative and absolute timeouts with an accuracy of 100
> > ns in the API and a real accuracy which only depends on the underlying
> > HW, and they are especially not subject to the 49.7 days overflow
> > problem.
> 
> I see your point.  The question is how to use waitable timers for
> CLOCK_MONOTONIC.

...therefore we could still handle CLOCK_MONOTONIC timedwait as a
relative timeout.  So pthread_condattr_[gs]etclock should be correct
even without this (although it would still gain accuracy), but that does
leave a problem with clock_nanosleep(TIMER_ABSTIME).

Looking at the other uses of cancelable_wait(), would the following make
sense:

* change the timeout argument to struct timespec *;
* cancelable_wait (object, INFINITE) calls change to (object, NULL);
* cancelable_wait (object, DWORD) calls change to (object, &timespec);
* then in cancelable_wait:

HANDLE hTimer;
HANDLE wait_objects[4];
....
wait_objects[num++] = object;

if (timeout)
  {
    LARGE_INTEGER li;
    li.QuadPart = (timeout->tv_sec * NSPERSEC) + (timeout->tv_nsec /
100); /* rounding? */
    hTimer = CreateWaitableTimer (NULL, FALSE, NULL);
    SetWaitableTimer (hTimer, &li, 0, NULL, NULL, FALSE); /* handle
possible error?  what would cause one? */
    wait_objects[num++] = hTimer;
  }
...
while (1)
  {
    res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
....

Or am I completely off-base here?


Yaakov




More information about the Cygwin-patches mailing list