Opened 10 years ago

Closed 7 years ago

#7665 closed Bugs (fixed)

this_thread::sleep_for no longer uses steady_clock in thread

Reported by: ewdevel@… Owned by: viboes
Milestone: Boost 1.60.0 Component: thread
Version: Boost 1.52.0 Severity: Regression
Keywords: Cc:

Description

In 1.51 sleep_for slept for set time no matter what [unless it received interrupt]. In 1.52 sleep_for behaves like normal sleep [system_clock, which introduces problems witch changing time while sleeping] if in new thread.

How to reproduce: Compile and run the test. Change time [date -s 10:00:00].

Main thread will exit sleep_for after 10 seconds. Boost::thread will end after some other time.

In correct situation [ex. boost 1.51] they should end simultaneously.

I think it's introduced in revision 80450.

Example program demonstrating this behavior is attached.

Attachments (1)

sleep_for_test.cpp (485 bytes ) - added by ewdevel@… 10 years ago.
Test for sleep_for that fails when time is changed.

Download all attachments as: .zip

Change History (33)

by ewdevel@…, 10 years ago

Attachment: sleep_for_test.cpp added

Test for sleep_for that fails when time is changed.

comment:1 by viboes, 10 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned

Which platform and compiler are you using?

comment:2 by viboes, 10 years ago

Hi, I have checked your program on MacOs gcc-4.2.1, and I'm unable to reproduce the behavior you reported

gt-s8600:test viboes$ date
Jeu  8 nov 2012 22:00:03 CET
gt-s8600:test viboes$ ./a.out
Main thread START
Sleeping for 10 seconds - change time
Main thread END
Ended
gt-s8600:test viboes$ date
Jeu  8 nov 2012 10:10:06 CET

I have changed the date to 10:10

Last edited 10 years ago by viboes (previous) (diff)

comment:3 by Eryk Wieliczko <ewdevel@…>, 10 years ago

It seems that mac version [guessing from boost/chrono/detail/inlined] uses different sources for time keeping.

I've been able to reproduce this bug under: CentOS 6.2 x64 [gcc 4.4.6] VirtualBox'ed Ubuntu 10.04 x64 [gcc 4.6.1]

Can someone check this under different linux distros?

in reply to:  3 comment:4 by viboes, 10 years ago

Replying to Eryk Wieliczko <ewdevel@…>:

It seems that mac version [guessing from boost/chrono/detail/inlined] uses different sources for time keeping.

I've been able to reproduce this bug under: CentOS 6.2 x64 [gcc 4.4.6] VirtualBox'ed Ubuntu 10.04 x64 [gcc 4.6.1]

OK I will check.

comment:5 by viboes, 10 years ago

I don't know if there is a regression in trunk of Boost.Thread on Ubuntu as a lot of tests are failing independently of setting the date. It is surprising that the code is working on Ubuntu 12.04-64 testers. I'll continue the analysis.

Last edited 10 years ago by viboes (previous) (diff)

comment:6 by viboes, 10 years ago

Milestone: To Be DeterminedBoost 1.53.0
Summary: this_thread::sleep_for no longer uses steady_clock in threadl

I've made some changes on the sleep_for algo depending on BOOST_THREAD_SLEEP_FOR_IS_STEADY is defined or not. have you the possibility to check if this rework solves the issue?

Committed in trunk [81649]

comment:7 by viboes, 10 years ago

Summary: lsleep_for doesn't use steady_clock

comment:8 by viboes, 10 years ago

Summary: sleep_for doesn't use steady_clockthis_thread::sleep_for no longer uses steady_clock in thread

comment:9 by viboes, 10 years ago

Resolution: fixed
Status: assignedclosed

I hope the modification fixes the bug. Reopen it if you see the issue on 1.53 or on trunk.

comment:10 by Volker_pruess@…, 9 years ago

I think this needs to become reopened. We observe regression with boost 1.54.0, 1.55.0 and latest git version. Additionally the discussion #6787 also points in this direction.

We're using Ubuntu 12.04.4 LTS 64 bit for x86.

comment:11 by viboes, 9 years ago

And what do you think of the proposition in #6787?

comment:12 by viboes, 9 years ago

Resolution: fixed
Status: closedreopened

comment:13 by Volker Prüß <Volker_Pruess@…>, 9 years ago

I'm not quite sure about the solution you proposed but I see the problem :

  • 'boost::this_thread::sleep_for' has to remain an interruption point
  • there are no standard library or pthread functions allowing interuptible operation based upon a stable clock, especially for a portable library.

I checked against the c++ library provided alongside with the gcc 4.6.3 and at least their implementation of sleep_for is not affected by changes in the system clock. It seems that the gcc implementation is based upon nanosleep (http://stackoverflow.com/questions/12523122/what-is-glibcxx-use-nanosleep-all-about), IMHO therefore not interruptible.

I'm not quite sure whether an implementation of sleep_for (and sleep) that is affected by changes made to the system clock would be acceptable anyway. And moving sleep_for out of the namespace 'this_thread' would break existing code.

Seems to be a question for the standard library experts ...

comment:14 by viboes, 9 years ago

The standard doesn't includes interruptible threads. And Boost can do whatever we decide without the standard library experts advice ;-)

So it is up to you to decide if we want additional non-interruptible functions or not. By compatibility, we can not replace the current behavior.

comment:15 by Volker Prüß <Volker_Pruess@…>, 9 years ago

When you refer to the current behaviour you mean that boost::this_thread::sleep_for has been mentioned in the list of predefined interruption points ? The documentation about sleep_for also says

Suspends the current thread until the duration specified by by rel_time has elapsed.

Question is which clock is used to measure the duration. I would expect that most programmers would intuitively expect a stable clock here. But referring to the type of clock in the documentation would do it. So I would agree to your suggestion adding another set of methods.

comment:16 by Volker Prüß <Volker_Pruess@…>, 9 years ago

I saw that sleep_for is using pthread_cond_wait to achieve thread suspension and being interruptible. Is it possible to initialize the condition variable to use the monotonic clock as described here ?

comment:17 by viboes, 8 years ago

I was not aware of pthread_condattr_setclock. I will adapt condition_variable to use it on the platforms providing it.

Thanks for the pointer.

comment:18 by viboes, 8 years ago

Unfortunately pthread_condattr_setclock is not available on MacOs?.

comment:19 by viboes, 8 years ago

Milestone: Boost 1.53.0To Be Determined

comment:21 by viboes, 8 years ago

Resolution: fixed
Status: reopenedclosed

comment:22 by viboes, 7 years ago

Milestone: Boost 1.57.0To Be Determined
Resolution: fixed
Status: closedreopened

I'm writing a patch that uses pthread_condattr_setclock. As I said I have no platform providing it (I'm using MacOS). The user will need to define BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC until I find a way to detect it.

Is there any one that can test it?

comment:23 by viboes, 7 years ago

Milestone: To Be DeterminedBoost 1.60.0

comment:24 by viboes, 7 years ago

Status: reopenednew

comment:25 by viboes, 7 years ago

Milestone: Boost 1.60.0To Be Determined

comment:26 by viboes, 7 years ago

Status: newassigned

comment:27 by viboes, 7 years ago

Please could you try to replace in thread/v2/thread.hpp line #94

#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY

by

#if defined BOOST_THREAD_SLEEP_FOR_IS_STEADY && ! defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC

comment:29 by viboes, 7 years ago

Milestone: To Be DeterminedBoost 1.60.0

comment:30 by mail@…, 7 years ago

I'm experiencing the same problem (Linux Mint, 3.13.0-37-generic # 64-Ubuntu SMP, boost 1.54).

Can confirm that the threads are behaving differently with the test code.

Checked out modular-boost, switched to develop for boost-thread, compiled everything and tried the test code above. Adding

#define BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC 1

fixes the bug for me.

comment:31 by viboes, 7 years ago

Thanks for the report.

Note: See TracTickets for help on using tickets.