1

I was referring to cpp reference for wait_for and wait_until and this SO answer. I understand from both is that wait_for() SHOULD be immune to jumps in system time while wait_until() on system clock is susceptible to jumps in system time and may wait for incorrect duration because of that.

The notes on cpp reference (also a comment to that answer) points out that wait_until() internally uses system clock even if caller suggests (uses) steady clock. The code for dev toolset 9 on centos confirms the same:

  typedef chrono::system_clock        __clock_t;                                                                                                                                                                   
  typedef chrono::steady_clock        __steady_clock_t;
  .....
  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;

    if (__wait_until_impl(__lock, __s_atime) == cv_status::no_timeout)
      return cv_status::no_timeout;
    // We got a timeout when measured against __clock_t but
    // we need to check against the caller-supplied clock
    // to tell whether we should return a timeout.
    if (_Clock::now() < __atime)
      return cv_status::no_timeout;
    return cv_status::timeout;
  }  

What is interesting is that wait_for() internally uses wait_until() directly:

  template<typename _Rep, typename _Period>
  cv_status
  wait_for(unique_lock<mutex>& __lock,                                                                                                                                                                                      
  const chrono::duration<_Rep, _Period>& __rtime)
  {
    using __dur = typename __steady_clock_t::duration;
    auto __reltime = chrono::duration_cast<__dur>(__rtime);
    if (__reltime < __rtime)
      ++__reltime;
    return wait_until(__lock, __steady_clock_t::now() + __reltime);
  }

This makes no sense as wait_until() will get rid of the steady clock and wait_for(0 too will become susceptible to system clock jumps. My understanding is that wait_for() SHOULD be immune to system time jumps.

Please help me understand what is happening here. What should I do if I want to wait on a conditional variable AND be immune from system time jumps?

user207421
  • 305,947
  • 44
  • 307
  • 483
yashC
  • 887
  • 7
  • 20
  • You cannot be immune from spurious wake-ups. – n. m. could be an AI Oct 05 '21 at 09:59
  • @n.1.8e9-where's-my-sharem. What are the causes for spurious wake-ups (other than jump in system time)? – yashC Oct 06 '21 at 04:27
  • 1
    Could be anything. https://en.m.wikipedia.org/wiki/Spurious_wakeup – n. m. could be an AI Oct 06 '21 at 05:02
  • @n.1.8e9-where's-my-sharem. Thanks for the info. BTW for anyone looking for more info - in devset 10, the issue of wait_for ending up using system clock has been resolved and in devset 10 wait_until has a special definition that is used by wait_for to eliminate clock conversion from steady to system. – yashC Oct 07 '21 at 10:47

0 Answers0