简体   繁体   中英

implementation of std::condition_variable::wait_until

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?

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.

Yes, and no.

Yes, this code could be optimized to not manipulate time_point s 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, ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM