[PATCH] clock_nanosleep(2), pthread_condattr_[gs]etclock(3)
Corinna Vinschen
corinna-cygwin@cygwin.com
Thu Jul 21 09:21:00 GMT 2011
On Jul 20 21:22, Yaakov (Cygwin/X) wrote:
> 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...
> [...]
> ...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, ×pec);
> * 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?
No, you're not at all off-base. Personally I'd prefer to use the native
NT timer functions, but that's not important. What I'm missing is a way
to specify relative vs. absolute timeouts in your above sketch. I guess
we need a flag argument as well.
Other than that, I think we should make sure to create the waitable
timer only once on a per-thread base. Object creation and deletion is
usually a time consuming process. So what we could do is to add a
HANDLE "cw_timer" to struct _local_storage in cygtls.h, which gets
inited to NULL in _cygtls::init_thread as well as in
_cygtls::fixup_after_fork.
Then cancelable_wait with a non-NULL timespec would check for the handle
being NULL and create a non-inheritable timer, if so. All subsequent
calls only set (and cancel) the timer.
Does that sound reasonable?
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
More information about the Cygwin-patches
mailing list