<div dir="ltr"><div>Sorry for the late reply Louis,</div><div><br></div><div>I don't have any interest, I need only efficient sleep on Linux, so it's easy to work around. Mostly wanted to let people know about this gotcha. Probably most timers are driven from a epoll/kqueue event loop so these C++ APIs are not used much outside demo/example/student code.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 8, 2020 at 8:16 AM Louis Dionne <<a href="mailto:ldionne@apple.com">ldionne@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
> On Mar 5, 2020, at 15:30, Erik Rigtorp via libcxx-dev <<a href="mailto:libcxx-dev@lists.llvm.org" target="_blank">libcxx-dev@lists.llvm.org</a>> wrote:<br>
> <br>
> Hi!<br>
> <br>
> libcxx seems to have a suboptimal implementation of<br>
> std::this_thread::sleep_until for Linux.<br>
> <br>
> Currently it's implemented using pthread_cond_timedwait:<br>
> template <class _Clock, class _Duration><br>
> void<br>
> sleep_until(const chrono::time_point<_Clock, _Duration>& __t)<br>
> {<br>
>  using namespace chrono;<br>
>  mutex __mut;<br>
>  condition_variable __cv;<br>
>  unique_lock<mutex> __lk(__mut);<br>
>  while (_Clock::now() < __t)<br>
>    __cv.wait_until(__lk, __t);<br>
> }<br>
> (<a href="https://github.com/llvm/llvm-project/blob/master/libcxx/include/thread#L391" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/master/libcxx/include/thread#L391</a>)<br>
> <br>
> This leads to unnecessary stores to the stack and useless atomic<br>
> operations that can potential cause memory bus traffic. On Linux this<br>
> could be implemented using the clock_nanosleep() function with the<br>
> TIMER_ABSTIME flag.<br>
> <br>
> For std::chrono::steady_clock there is a specialization:<br>
> template <class _Duration><br>
> inline _LIBCPP_INLINE_VISIBILITY<br>
> void<br>
> sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)<br>
> {<br>
>  using namespace chrono;<br>
>  sleep_for(__t - steady_clock::now());<br>
> }<br>
> (<a href="https://github.com/llvm/llvm-project/blob/master/libcxx/include/thread#L404" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/master/libcxx/include/thread#L404</a>)<br>
> <br>
> This has a race condition where the thread could be preempted after<br>
> calling now() but before sleeping. The race window is extremely small,<br>
> but will lead to increased jitter in actual deadline. If the thread is<br>
> using something like linux SCHED_IDLE or competing with threads using<br>
> SCHED_FIFO/SCHED_RR the likelihood of hitting this race could be high.<br>
> Using clock_nanosleep() would also help here.<br>
> <br>
> Linux and most BSDs support the clock_nanosleep() function, it makes<br>
> sense to add a feature detection for it and use it if supported.<br>
<br>
<br>
If you still have interest in fixing that and want to submit a patch, I'd be happy to help review it.<br>
<br>
Louis<br>
<br>
</blockquote></div>