Opened 7 years ago

Closed 7 years ago

#11322 closed Bugs (fixed)

sleep_for() nanoseconds overload will always return too early on windows

Reported by: jlamotte@… Owned by: viboes
Milestone: Boost 1.60.0 Component: thread
Version: Boost 1.55.0 Severity: Showstopper
Keywords: Cc:

Description

We isolated the issue to the following test:

#include <boost/thread.hpp>
#include <boost/chrono.hpp>

int main()
{

    const boost::chrono::nanoseconds SLEEP_DURATION(boost::chrono::milliseconds(500));
    const auto SLEEP_DURATION_MS = boost::chrono::duration_cast<boost::chrono::milliseconds>(SLEEP_DURATION);
    const auto SLEEP_DURATION_US = boost::chrono::duration_cast<boost::chrono::microseconds>(SLEEP_DURATION);
    const auto SLEEP_DURATION_NANO = boost::chrono::duration_cast<boost::chrono::nanoseconds>(SLEEP_DURATION);
    const auto SLEEP_DURATION_STEADY = boost::chrono::duration_cast<boost::chrono::steady_clock::duration>(SLEEP_DURATION);


    const auto begin = boost::chrono::steady_clock::now();
    boost::this_thread::sleep_for(SLEEP_DURATION);
    const auto end = boost::chrono::steady_clock::now();
    const auto sleep_duration = end - begin;
    const auto sleep_duration_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(sleep_duration);
    const auto sleep_duration_us = boost::chrono::duration_cast<boost::chrono::microseconds>(sleep_duration);
    const auto sleep_duration_nano = boost::chrono::duration_cast<boost::chrono::nanoseconds>(sleep_duration);

    assert(sleep_duration >= SLEEP_DURATION);
    assert(sleep_duration_ms >= SLEEP_DURATION_MS);
    assert(sleep_duration_us >= SLEEP_DURATION_US);
    assert(sleep_duration_nano >= SLEEP_DURATION_NANO);
  
}

It fails with msvc10. If SLEEP_DURATION is a milliseconds instead of nanoseconds, it runs without failure.

Stepping in the code shows that the nanoseconds sleep_for() overload does not use a condition variable like the other template sleep_for overloads, which leads to that bug where the sleep took less time than asked (instead of equal or more).

It seems that his bug is related to #9720 and #10967 but I'm not sure.

Change History (10)

comment:1 by viboes, 7 years ago

Could you try the develop branch or boost 1.58?

comment:2 by viboes, 7 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned

comment:3 by jlamotte@…, 7 years ago

So far I didn't find the time to test this with 1.58, sorry. I should be able to test it soon though.

comment:4 by jlamotte@…, 7 years ago

I managed to try with Boost 1.58.0 on Windows with MSVC 10.0 (our current compiler) in Debug.

So far 1/5 runs will trigger the first assert. So I guess that the bug is still there but is "reduced" in 1.58.

comment:5 by viboes, 7 years ago

Thanks for trying version 1.58.

comment:6 by viboes, 7 years ago

Please, could you try commenting the sleep_for on nanoseconds overload in thread/win32/thread_data.hpp

#ifdef BOOST_THREAD_USES_CHRONO
        inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
        {
          interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
        }
#endif

comment:7 by jlamotte@…, 7 years ago

Yes indeed the test pass if I comment this overload. (vs2010 32 bit boost 1.58.0 Debug and Release)

comment:8 by viboes, 7 years ago

Thanks, I will comment it as well and deliver it to the develop branch.

Note: See TracTickets for help on using tickets.