Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use monotonic time in condition variables. #35048

Merged
merged 3 commits into from Aug 31, 2016
Merged

Use monotonic time in condition variables. #35048

merged 3 commits into from Aug 31, 2016

Conversation

ghost
Copy link

@ghost ghost commented Jul 26, 2016

Configure condition variables to use monotonic time using
pthread_condattr_setclock on systems where this is possible.
This fixes the issue when thread waiting on condition variable is
woken up too late when system time is moved backwards.

@nagisa
Copy link
Member

nagisa commented Jul 26, 2016

Any backcompat hazards? Is there anybody who could be relying on the current behaviour?

@ghost
Copy link
Author

ghost commented Jul 26, 2016

The only observable change should occur when system time is moved backwards.
Previously, if system time has been moved backwards by dt, then wait time was
extended by dt. After change, the waiting time should be unaffected by changes
in system time.

I don't think anyone could rely on previous behaviour, especially considering
possibility of spurious wakeups.

@sfackler
Copy link
Member

The implementation was pulled pretty directly from C++ standard libraries - do you know why they don't do something similar?

@sfackler
Copy link
Member

Specifically libcxx: #21132

@nagisa
Copy link
Member

nagisa commented Jul 26, 2016

@sfackler r? self if you’re interested in reviewing this. hfive didn’t assign anybody for some reason.

@sfackler sfackler added I-nominated T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jul 26, 2016
@sfackler sfackler self-assigned this Jul 26, 2016
@sfackler
Copy link
Member

Yep, I'll grab it.

@@ -18,14 +20,14 @@ use sys::condvar as imp;
/// condition variables. It is consequently entirely unsafe to use. It is
/// recommended to use the safer types at the top level of this crate instead of
/// this type.
pub struct Condvar(imp::Condvar);
pub struct Condvar(Box<imp::Condvar>);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial intention of these sys_common types was to be a thin a layer over the system primitives as possible, unsafety an all. Could this box be left upwards and the initialization be delayed like with mutexes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexcrichton There are two main reasons for moving the box. First, it seemed
preferable to me, to ensure that Condvar::new() returns fully initialized
object (especially now given that StaticCondvar is gone). Second, it didn't
require chasing all uses of Condvar::new() and inserting init nearby.

If you prefer to have boxes outside sys_common I can of course move them back.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather the Box not be here because it is punishing Windows for something that isn't its fault.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@retep998 This PR does not add any additional boxes. It just has been moved from sync::Condvar::inner.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, well it certainly confused me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tmiasko yeah let's keep the boxes instd::sync to stay consistent with the mutex module next to this one.

@ghost
Copy link
Author

ghost commented Jul 26, 2016

@sfackler C++ story is much more complicated because std::condition_variable
can be used with potentially different clocks. This is problematic with
pthreads, because while you can choose the clock, you have to specify it
upfront. Regardless of which one you chose the others will suffer from some
variations of this problem (because timeouts have to be converted from one
clock to another). It also probably didn't help that libcxx has been written by
Apple employee and OS X doesn't even have pthread_condattr_setclock.

fn drop(&mut self) {
unsafe { libc::pthread_condattr_destroy(self.0) };
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to not worry about assertions below cleaning this up, this can just be inserted after the pthread_cond_init (like mutex initialization)

@ghost
Copy link
Author

ghost commented Jul 27, 2016

I reverted box changes and added init function to sys::Condvar instead.
The RAII for pthread_condattr_t has also been removed.

@bors
Copy link
Contributor

bors commented Jul 31, 2016

☔ The latest upstream changes (presumably #35060) made this pull request unmergeable. Please resolve the merge conflicts.

Configure condition variables to use monotonic time using
pthread_condattr_setclock on systems where this is possible.
This fixes the issue when thread waiting on condition variable is
woken up too late when system time is moved backwards.
@ghost
Copy link
Author

ghost commented Jul 31, 2016

I rebased changes against master. The commit updating liblibc is gone as it is no longer necessary.

@sfackler
Copy link
Member

It also probably didn't help that libcxx has been written by
Apple employee and OS X doesn't even have pthread_condattr_setclock.

IIRC, the implementations in Boost and GCC's standard library are basically the same.

@ghost
Copy link
Author

ghost commented Aug 1, 2016

Boost implementation was changed to use monotonic clock in version 1.60:
boostorg/thread@8f5de1d

It seems that similar solution is considered in GNU libstdc++
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861
There is also a path to glibc that adds pthread_cond_timedwait like function
that supports waiting on arbitrary clock.

@sfackler
Copy link
Member

sfackler commented Aug 5, 2016

The libs team discussed this at the last triage meeting, and decided that we're on board with this change, but would possibly like the documentation for the Condvar type to be updated to note that we make a best effort to use monotonic clocks where available.

Could you add that bit on? We should be good to merge afterwards!

@ghost
Copy link
Author

ghost commented Aug 19, 2016

I have updated the docs for Condvar::wait_timeout_ms and Condvar::wait_timeout with:

Note that the best effort is made to ensure that the time waited is
measured with a monotonic clock, and not affected by the changes made to
the system time.

@alexcrichton
Copy link
Member

Discussed in @rust-lang/libs triage today, conclusion was that this is good to go, thanks @tmiasko!

@bors: r+

@bors
Copy link
Contributor

bors commented Aug 23, 2016

📌 Commit 8dae1b6 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Aug 23, 2016

⌛ Testing commit 8dae1b6 with merge 388a060...

bors added a commit that referenced this pull request Aug 23, 2016
Use monotonic time in condition variables.

Configure condition variables to use monotonic time using
pthread_condattr_setclock on systems where this is possible.
This fixes the issue when thread waiting on condition variable is
woken up too late when system time is moved backwards.
@bors
Copy link
Contributor

bors commented Aug 23, 2016

💔 Test failed - auto-linux-64-x-android-t

The pthread_condattr_setclock is available only since
Android 5.0 and API level 21.
@sfackler
Copy link
Member

@tmiasko good for another bors run?

@ghost
Copy link
Author

ghost commented Aug 29, 2016

The android build failed to link with pthread_condattr_setclock. The
pthread_condattr_setclock is available since Android 5.0 and API level 21.

I am not sure if there is some minimum Android version supported by Rust, and
if there is one what it is. But regardless, as it doesn't seem to support
pthread_condattr_setclock, I would go with conservative option of using previous
implementation on Android for now (and this is implemented in last commit).

@sfackler If that is ok with you, then yes, it is ready for another bors run.

@sfackler
Copy link
Member

@bors r=alexcrichton

@bors
Copy link
Contributor

bors commented Aug 29, 2016

📌 Commit 59e5e0b has been approved by alexcrichton

@sfackler
Copy link
Member

Cool! I think the minimum Android API level we support is somewhere in the teens unfortunately.

@bors
Copy link
Contributor

bors commented Aug 29, 2016

⌛ Testing commit 59e5e0b with merge b953acf...

@bors
Copy link
Contributor

bors commented Aug 29, 2016

💔 Test failed - auto-mac-64-opt-rustbuild

@alexcrichton
Copy link
Member

@bors: retry

@bors
Copy link
Contributor

bors commented Aug 29, 2016

⌛ Testing commit 59e5e0b with merge e797b8f...

@bors
Copy link
Contributor

bors commented Aug 29, 2016

⛄ The build was interrupted to prioritize another pull request.

@bors
Copy link
Contributor

bors commented Aug 30, 2016

⌛ Testing commit 59e5e0b with merge e08f211...

@alexcrichton
Copy link
Member

@bors: retry force clean

  • restarted buildbot

@bors
Copy link
Contributor

bors commented Aug 30, 2016

💣 Buildbot returned an error: <span>exceptions.KeyError</span>: <span>'auto-linux-64-opt-no-mir'</span>

@bors
Copy link
Contributor

bors commented Aug 30, 2016

⌛ Testing commit 59e5e0b with merge 4f0023b...

@bors
Copy link
Contributor

bors commented Aug 30, 2016

💔 Test failed - auto-mac-32-opt

@alexcrichton
Copy link
Member

@bors: retry

On Tue, Aug 30, 2016 at 11:27 AM, bors notifications@github.com wrote:

💔 Test failed - auto-mac-32-opt
https://buildbot.rust-lang.org/builders/auto-mac-32-opt/builds/10393


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#35048 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAD95D0JrnE6_nW8EGeUs9niQdmsDcliks5qlHYfgaJpZM4JVPEO
.

@bors
Copy link
Contributor

bors commented Aug 30, 2016

⌛ Testing commit 59e5e0b with merge 86c6c1c...

@alexcrichton
Copy link
Member

@bors: retry force clean

  • Unfortunately won't succeed, but buildbot is reconfigured and can hopefully do so now

@bors
Copy link
Contributor

bors commented Aug 30, 2016

⌛ Testing commit 59e5e0b with merge eac4146...

bors added a commit that referenced this pull request Aug 30, 2016
Use monotonic time in condition variables.

Configure condition variables to use monotonic time using
pthread_condattr_setclock on systems where this is possible.
This fixes the issue when thread waiting on condition variable is
woken up too late when system time is moved backwards.
@bors bors merged commit 59e5e0b into rust-lang:master Aug 31, 2016
@sdroege
Copy link
Contributor

sdroege commented Sep 7, 2016

On Android, you might want to optionally use pthread_cond_timedwait_monotonic_np() as pthread_condattr_setclock() was only added with Android API 21 (5.0 / Lollipop), and pthread_cond_timedwait_monotonic() was using the wallclock. If that's something you would consider (instead of just not supporting Android pre 21 properly), I could probably make a patch for this.

@ghost ghost deleted the monotonic-wait-timeout branch September 8, 2016 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants