4

I am reading the libstdc++ implementation of std::condition_variable::wait_until, here is the source:

template<typename _Clock, typename _Duration>
  cv_status
  wait_until(unique_lock<mutex>& __lock,
     const chrono::time_point<_Clock, _Duration>& __atime)
  {
    // DR 887 - Sync unknown clock to known clock.
    const typename _Clock::time_point __c_entry = _Clock::now();
    const __clock_t::time_point __s_entry = __clock_t::now();
    const auto __delta = __atime - __c_entry;
    const auto __s_atime = __s_entry + __delta;

    return __wait_until_impl(__lock, __s_atime);
  }

template<typename _Clock, typename _Duration, typename _Predicate>
  bool
  wait_until(unique_lock<mutex>& __lock,
     const chrono::time_point<_Clock, _Duration>& __atime,
     _Predicate __p)
  {
    while (!__p())
      if (wait_until(__lock, __atime) == cv_status::timeout)
        return __p();
    return true;
  }

The second function call the first function in a loop.which will do clock sync operation.So if we call the second function,the sync operation may run many times.It is necessary to sync clock every time?I think the code can be improved by sync clock only once in the second function.Am I right?

2 Answers 2

1

I think you're right. On the other hand the assumptions for using wait_until are usually that the event will happen only sparsely and the predicate returning true for all but a few instances of unwanted wake-ups. Thus the overhead of re-syncing the clocks should be minimal. Remember also that in this case the thread had to be woken up and paged in already, which is probably more expensive than querying a clock.

Sign up to request clarification or add additional context in comments.

3 Comments

Can you please explain Remember also that in this case the thread had to be woken up and paged in already, which is probably more expensive than querying a clock.? I just can get the point.
@prehistoricpenguin the thread had to be woken up to continue execution which is probably more expensive than the two clock calls - the point is it's not worth optimising for the general case. see also Sean's answer for more details on the usual assumptions for wait_until.
@BeyerStudios,Thanks for the explanation ,got it
0

Yes, and no.

Yes, this code could be optimized to not manipulate time_points when it loops. However, I'm not sure that's really necessary.

Consider what makes the predicated wait_until loop.

When notified, it checks the predicate to see if there is work to do.

  1. If the predicate returns true, i.e. the condition protected by the condition variable is true, wait_until returns true.
  2. If the timeout elapses, wait_until returns the value of the predicate, which will typically be false (otherwise we would have expected the condition_variable to have have been notified).

This leaves only one case where the loop actually loops: When the condition_variable is notified, but the predicate returns false.

This is known as a spurious wakeup and is hardly the typical case, so it is not really worth optimizing for.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.