Skip to content

std: Avoid usage of Once in Instant - #59676

Merged
bors merged 1 commit into
rust-lang:masterfrom
alexcrichton:osx-deadlock
Apr 4, 2019
Merged

std: Avoid usage of Once in Instant#59676
bors merged 1 commit into
rust-lang:masterfrom
alexcrichton:osx-deadlock

Conversation

@alexcrichton

Copy link
Copy Markdown
Member

This commit removes usage of Once from the internal implementation of
time utilities on OSX and Windows. It turns out that we accidentally hit
a deadlock today (#59020) via events that look like:

  • A thread invokes park_timeout
  • Internally, only on OSX, park_timeout calls Instant::elapsed
  • Inside of Instant::elapsed on OSX we enter a Once to initialize
    global timer data
  • Inside of Once, it attempts to park

This means on the same stack frame, when there's contention, we're
calling park from inside park_timeout, causing a deadlock!

The solution implemented in this commit was to remove usage of Once
and instead just do a small dance with atomics. There's no real need we
need to guarantee that the global information is only learned once, only
that it's only stored once. This implementation may have multiple
threads invoke mach_timebase_info, but only one will store the global
information which will amortize the cost for all other threads.

A similar fix has been applied to windows to be uniform across our
implementations, but looking at the code on Windows no deadlock was
possible. This is purely just a consistency update for Windows and in
theory a slightly leaner implementation.

Closes#59020

@rust-highfive

Copy link
Copy Markdown
Contributor

r? @rkruppe

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfiverust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 3, 2019
@alexcrichton

Copy link
Copy Markdown
MemberAuthor

r? @sfackler

@sfackler

Copy link
Copy Markdown
Member

@bors r+

@bors

bors commented Apr 3, 2019

Copy link
Copy Markdown
Collaborator

📌 Commit 4ef32a4 has been approved by sfackler

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 3, 2019
Centril added a commit to Centril/rust that referenced this pull request Apr 3, 2019
std: Avoid usage of `Once` in `Instant`
This commit removes usage of `Once` from the internal implementation of
time utilities on OSX and Windows. It turns out that we accidentally hit
a deadlock today (rust-lang#59020) via events that look like:
* A thread invokes `park_timeout`
* Internally, only on OSX, `park_timeout` calls `Instant::elapsed`
* Inside of `Instant::elapsed` on OSX we enter a `Once` to initialize
global timer data
* Inside of `Once`, it attempts to `park`
This means on the same stack frame, when there's contention, we're
calling `park` from inside `park_timeout`, causing a deadlock!
The solution implemented in this commit was to remove usage of `Once`
and instead just do a small dance with atomics. There's no real need we
need to guarantee that the global information is only learned once, only
that it's only *stored* once. This implementation may have multiple
threads invoke `mach_timebase_info`, but only one will store the global
information which will amortize the cost for all other threads.
A similar fix has been applied to windows to be uniform across our
implementations, but looking at the code on Windows no deadlock was
possible. This is purely just a consistency update for Windows and in
theory a slightly leaner implementation.
Closesrust-lang#59020
@CentrilCentril mentioned this pull request Apr 3, 2019
@Centril

Copy link
Copy Markdown
Contributor

Failed in #59682 (comment), @bors r-

@borsbors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 3, 2019
@CentrilCentril closed this Apr 3, 2019
@CentrilCentril reopened this Apr 3, 2019
This commit removes usage of `Once` from the internal implementation of
time utilities on OSX and Windows. It turns out that we accidentally hit
a deadlock today (rust-lang#59020) via events that look like:
* A thread invokes `park_timeout`
* Internally, only on OSX, `park_timeout` calls `Instant::elapsed`
* Inside of `Instant::elapsed` on OSX we enter a `Once` to initialize
global timer data
* Inside of `Once`, it attempts to `park`
This means on the same stack frame, when there's contention, we're
calling `park` from inside `park_timeout`, causing a deadlock!
The solution implemented in this commit was to remove usage of `Once`
and instead just do a small dance with atomics. There's no real need we
need to guarantee that the global information is only learned once, only
that it's only *stored* once. This implementation may have multiple
threads invoke `mach_timebase_info`, but only one will store the global
information which will amortize the cost for all other threads.
A similar fix has been applied to windows to be uniform across our
implementations, but looking at the code on Windows no deadlock was
possible. This is purely just a consistency update for Windows and in
theory a slightly leaner implementation.
Closesrust-lang#59020
@alexcrichton

Copy link
Copy Markdown
MemberAuthor

@bors: r=sfackler

@bors

bors commented Apr 4, 2019

Copy link
Copy Markdown
Collaborator

📌 Commit cb57484 has been approved by sfackler

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 4, 2019
@bors

bors commented Apr 4, 2019

Copy link
Copy Markdown
Collaborator

⌛ Testing commit cb57484 with merge 53f2165...

bors added a commit that referenced this pull request Apr 4, 2019
std: Avoid usage of `Once` in `Instant`
This commit removes usage of `Once` from the internal implementation of
time utilities on OSX and Windows. It turns out that we accidentally hit
a deadlock today (#59020) via events that look like:
* A thread invokes `park_timeout`
* Internally, only on OSX, `park_timeout` calls `Instant::elapsed`
* Inside of `Instant::elapsed` on OSX we enter a `Once` to initialize
global timer data
* Inside of `Once`, it attempts to `park`
This means on the same stack frame, when there's contention, we're
calling `park` from inside `park_timeout`, causing a deadlock!
The solution implemented in this commit was to remove usage of `Once`
and instead just do a small dance with atomics. There's no real need we
need to guarantee that the global information is only learned once, only
that it's only *stored* once. This implementation may have multiple
threads invoke `mach_timebase_info`, but only one will store the global
information which will amortize the cost for all other threads.
A similar fix has been applied to windows to be uniform across our
implementations, but looking at the code on Windows no deadlock was
possible. This is purely just a consistency update for Windows and in
theory a slightly leaner implementation.
Closes#59020
@bors

bors commented Apr 4, 2019

Copy link
Copy Markdown
Collaborator

☀️ Test successful - checks-travis, status-appveyor
Approved by: sfackler
Pushing 53f2165 to master...

@borsbors added the merged-by-bors This PR was explicitly merged by bors. label Apr 4, 2019
@bors
bors merged commit cb57484 into rust-lang:masterApr 4, 2019
@alexcrichton
alexcrichton deleted the osx-deadlock branch May 1, 2019 17:49
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-borsThis PR was explicitly merged by bors.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

park_timeout not waking up after timeout on macs

6 participants

@alexcrichton@rust-highfive@sfackler@bors@Centril@hanna-kruppe