-
Notifications
You must be signed in to change notification settings - Fork 13k
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
std: use futex in Once
#99505
std: use futex in Once
#99505
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
r? @kennytm (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I heard you have little time, @kennytm, please reassign if I'm wrong! |
r? rust-lang/libs |
r? @m-ou-se |
c79c240
to
198e05b
Compare
r? @thomcc |
// This is a non-generic function to reduce the monomorphization cost of | ||
// using `call_once` (this isn't exactly a trivial or small implementation). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've copied this from the old implementation, but I'm not sure whether it's really necessary?
There was a bug in the futex implementation which I've now resolved (changing the state from |
Is generic.rs equivalent to the old code, or does it need close scrutiny? |
It's basically the same, except for some style changes (using convenience functions for masking the pointers, making the loop in |
Can you put the changes into a separate commit from the file move? I really don't want to review the entire generic.rs, especially given that the current impl has been proven correct (IIRC). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not done reviewing futex.rs, only nits so far, but I have to run for a bit.
A bit of a meta-comment though, does this actually improve perf here? Our current Once
code is actually quite good IMO.
Cool, this really looks like a small but noticeable improvement ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, and sorry for the delay (didn't want to halfass the review of a synchronization primitive). The new impl is very clean, it sure is nice when we don't have to manage the linked list ourselves...
@bors r+ rollup=never |
📌 Commit 66278fd73072e0c449a245efcf22d48485d689c7 has been approved by It is now in the queue for this repository. |
@bors r- |
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (a688a03): comparison URL. Overall result: ❌✅ regressions and improvements - ACTION NEEDEDNext Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Footnotes |
Looks like this ended up being a small regression. I think the regression results are small and neutral enough that we don't need to investigate. @rustbot labels: perf-regression-triaged |
Now that we have efficient locks, let's optimize the rest of
sync
as well. This PR adds a futex-based implementation forOnce
, which drastically simplifies the implementation compared to the generic version, which is provided as fallback for platforms without futex (Windows only supports them on newer versions, so it uses the fallback for now).Instead of storing a linked list of waiters, the new implementation adds another state (
QUEUED
), which is set when there are waiting threads. These now usefutex_wait
on that state and are woken by the running thread when it finishes and notices theQUEUED
state, thereby avoiding unnecessary calls tofutex_wake_all
.