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 RWlock when accessing os::env #81850

Merged
merged 5 commits into from
Feb 13, 2021
Merged

use RWlock when accessing os::env #81850

merged 5 commits into from
Feb 13, 2021

Conversation

the8472
Copy link
Member

@the8472 the8472 commented Feb 7, 2021

Multiple threads modifying the current process environment is fairly uncommon. Optimize for the more common read case.

r? @m-ou-se

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 7, 2021
@rust-log-analyzer

This comment has been minimized.

@sfackler
Copy link
Member

sfackler commented Feb 8, 2021

Is the common use case really massive read contention on the process environment? A mutex will be faster than an rwlock when uncontended.

@the8472
Copy link
Member Author

the8472 commented Feb 8, 2021

Is the common use case really massive read contention on the process environment? A mutex will be faster than an rwlock when uncontended.

At least with glibc a lock or unlock is a single atomic RMW instruction as long as it is in read mode. A mutex can't do much better than that.

That said, the contention I have observed is relatively small. It's the cause of about 1.9% of sampled context switches, which translates to an even smaller impact on wall time.

Copy link
Member

@m-ou-se m-ou-se left a comment

Choose a reason for hiding this comment

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

Looks good!

Can you split the guard type into two types as well? Then the enum is also no longer needed.

@m-ou-se
Copy link
Member

m-ou-se commented Feb 9, 2021

(I was also about to comment on the names of the methods (read_with_guard, write_with_guard), but then noticed that the names of the existing methods of sys_common's StaticMutex, Mutex and RWLock are inconsistent and not very clear. I'll open an issue for that, to rename all these methods at some point.)

@the8472
Copy link
Member Author

the8472 commented Feb 9, 2021

Can you split the guard type into two types as well? Then the enum is also no longer needed.

The enum is private though. Is there any reason to expose two different guards?

@m-ou-se
Copy link
Member

m-ou-se commented Feb 9, 2021

It simplifies the code, and it's also what we do for std::sync::RwLock.

@rust-log-analyzer

This comment has been minimized.

@m-ou-se
Copy link
Member

m-ou-se commented Feb 9, 2021

Thanks!

@bors r+

@bors
Copy link
Contributor

bors commented Feb 9, 2021

📌 Commit 4fc181d has been approved by m-ou-se

@bors bors 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 Feb 9, 2021
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Feb 11, 2021
use RWlock when accessing os::env

Multiple threads modifying the current process environment is fairly uncommon. Optimize for the more common read case.

r? ``@m-ou-se``
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Feb 12, 2021
use RWlock when accessing os::env

Multiple threads modifying the current process environment is fairly uncommon. Optimize for the more common read case.

r? ```@m-ou-se```
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 13, 2021
Rollup of 10 pull requests

Successful merges:

 - rust-lang#79775 (Fix injected errors when running doctests on a crate named after a keyword)
 - rust-lang#81012 (Stabilize the partition_point feature)
 - rust-lang#81479 (Allow casting mut array ref to mut ptr)
 - rust-lang#81506 (HWAddressSanitizer support)
 - rust-lang#81741 (Increment `self.index` before calling `Iterator::self.a.__iterator_ge…)
 - rust-lang#81850 (use RWlock when accessing os::env)
 - rust-lang#81911 (GAT/const_generics: Allow with_opt_const_param to return GAT param def_id)
 - rust-lang#82022 (Push a `char` instead of a `str` with len one into a String)
 - rust-lang#82023 (Remove unnecessary lint allow attrs on example)
 - rust-lang#82030 (Use `Iterator::all` instead of open-coding it)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 354f19c into rust-lang:master Feb 13, 2021
@rustbot rustbot added this to the 1.52.0 milestone Feb 13, 2021
ehuss added a commit to ehuss/rust that referenced this pull request Mar 7, 2021
This reverts commit 354f19c, reversing
changes made to 0cfba2f.
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 8, 2021
Revert switch of env locking to rwlock, to fix deadlock in process spawning

This reverts commit 354f19c, reversing changes made to 0cfba2f.

PR rust-lang#81850 switched the environment lock from a mutex to an rwlock. However, process spawning (when not able to use `posix_spawn`) locks the environment before forking, and unlocks it after forking (in both the parent and the child). With a mutex, this works (although probably not correct even with a mutex). With an rwlock, on at least some targets, unlocking in the child does not work correctly, resulting in a deadlock.

This has manifested as CI hangs on i686 Linux; that target doesn't use `posix_spawn` in the CI environment due to the age of the installed C library (currently glibc 2.23). (Switching to `posix_spawn` would just mask this issue, though, which would still arise in any case that can't use `posix_spawn`.)

Some additional cleanup of environment handling around process spawning may help, but for now, revert the PR and go back to a standard mutex.

Fixes rust-lang#82221
the8472 added a commit to the8472/rust that referenced this pull request Mar 14, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 15, 2021
use RWlock when accessing os::env (take 2)

This reverts commit acdca31 (rust-lang#82877) i.e. redoes rust-lang#81850 since the invalid unlock attempts in the child process have been fixed in rust-lang#82949

r? `@joshtriplett`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: 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.

8 participants