C++11's std::condition_variable, std::timed_mutex and
std::recursive_timed_mutex support waiting with a timeout specified using
an arbitrary clock. It's common to use std::chrono::steady_clock (which
corresponds to CLOCK_MONOTONIC) or std::chrono::system_clock (which
corresponds to CLOCK_REALTIME) for these waits, and other clocks end up
being converted to one of those when performing the wait.

Unfortunately, I don't believe that it's possible to implement these on top
of the pthread equivalents correctly for std::chrono::steady_clock (i.e.
CLOCK_MONOTONIC) since:

1. pthread_mutex_timedlock only supports a time measured against
   CLOCK_REALTIME.

2. The clock used for pthread_cond_timedwait must be specified when the
   condition variable is created by pthread_cond_init. The clock to be used
   for future waits is not known at the point that the
   std::condition_variable constructor is called.

I'm most interested in the std::condition_variable case. since I have code
that wants to wait using std::chrono::steady_clock.

There are a number of possible workarounds for these. I've described some
in a blog post[1] and in defect 0001164[2]. But, my favourite solution is
to introduce a variant of pthread_cond_timedwait that takes a an additional
clockid_t parameter:

 int pthread_cond_timedwaitonclock(pthread_cond_t *cond,
                                   pthread_mutex_t *mutex,
                                   clockid_t clockid,
                                   const struct timespec *abstimeout);

I've proposed[3] an implementation of this function for glibc (as
pthread_cond_timedwaitonclock_np) and it was suggested that I ought to
raise it here. (This led me to enter defect 0001164, but since that yielded
no response I've finally got round to writing this email too.)

The equivalent for mutex would probably be:

 int pthread_mutex_timedlockonclock(pthread_mutex_t *mutex,
                                    clockid_t clockid,
                                    const struct timespec *abstimeout);

but I've not yet made any attempt to implement it in glibc.

Would making the C++ standard library implementable on top of POSIX be
considered a good enough reason to add such functions?

Are these functions generic enough or perhaps too generic? Android had a
pthread_cond_timedwait_monotonic function for a while, but deprecated it
when they added support for pthread_condattr_setclock.

Thanks.

Mike.

[1] 
https://randombitsofuselessinformation.blogspot.com/2018/06/its-about-time-monotonic-time.html
[2] http://austingroupbugs.net/view.php?id=1164
[3] 
http://libc-alpha.sourceware.narkive.com/3ZPZzEOy/rfcv4-add-pthread-cond-timedwaitonclock-np#post1

Reply via email to