This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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, &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?

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]