Skip to content

More granular locking in cargo_rustc #4282

New issue

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

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

Already on GitHub? # to your account

Open
alexcrichton opened this issue Jul 13, 2017 · 7 comments
Open

More granular locking in cargo_rustc #4282

alexcrichton opened this issue Jul 13, 2017 · 7 comments
Labels
A-build-execution Area: anything dealing with executing the compiler A-layout Area: target output directory layout, naming, and organization C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Performance Gotta go fast! S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing.

Comments

@alexcrichton
Copy link
Member

Right now whenever a build happens we lock the entirety of the target directory for the whole build, but it may be possible for us to have a more granular locking strategy which allows multiple instances of Cargo to proceed in parallel instead of serializing them.

@alexcrichton
Copy link
Member Author

@carols10cents carols10cents added A-build-execution Area: anything dealing with executing the compiler C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` labels Aug 28, 2017
@epage epage added the A-layout Area: target output directory layout, naming, and organization label Oct 13, 2023
@epage
Copy link
Contributor

epage commented Oct 13, 2023

As part of #5931, we've talked about changing the target directory layout so that there is a directory per package. This would give us more definitive units to lock.

@epage epage added Performance Gotta go fast! S-triage Status: This issue is waiting on initial triage. labels Oct 13, 2023
@epage
Copy link
Contributor

epage commented Nov 26, 2024

In #5931, we discuss having a directory per intermediate artifact inside of a user-wide cache directory. Each intermediate artifact would be lockable so there is exclusive access on the initial write and then multiple readers after that that prevent during builds. Depending on packages out of this shared location is important so we don't waste time copying things out.

To keep things simple, ideally we model the target directory the same way. So in a way, fixing this issue is a perfect subset of #5931.

We'd need a separate lock for the artifact directory though cargo check and cargo clippy shouldn't need that.

Any compilation that changes the fingerprint but not the -Cextra-filename would need to have exclusive access to the directory.

Therefore, the benefit of this feature would be limited to one of

  • check orclippy together or with a single full build command (build, run, test, doc)
  • Different enough --features
  • Different enough --packages
  • Different compilation modes (check, rustdoc, build)
    • clippy is not a separate mode but I think we do track it as separate somehow ("rustc"?)
  • Different RUSTFLAGS if fix(fingerprint): Don't throwaway the cache on RUSTFLAGS changes  #14830 is merged
  • Different profile

@epage epage added S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. and removed S-triage Status: This issue is waiting on initial triage. labels Nov 26, 2024
@ehuss
Copy link
Contributor

ehuss commented Nov 26, 2024

I think it would be good to also keep on eye on performance, since this could introduce more OS overhead. I'm also uncertain if we will run into lock limits, particularly on networked filesystems or filesystems like Docker, etc. It looks like the number of locks is configurable in Linux, but I don't immediately see any strict limits anywhere else.

@redactedontop
Copy link

Any updates?

@epage epage marked this as a duplicate of #15396 Apr 9, 2025
@ConradIrwin
Copy link

One important aspect of this (for me at least) is prioritizing user requests over background requests (for example from LSPs). Building Zed consumes all my CPU cores, and I'd like the rust-analyzer diagnostics to get out of my way when I run cargo run.

github-merge-queue bot pushed a commit that referenced this issue Apr 29, 2025
### What does this PR try to resolve?

While doing some investigation on the theoretical performance
implications of #4282 (and #15010 by extension) I was profiling cargo
with some experimental changes. (Still a work in progress)

But in the mean time, noticed that we do not have spans for rustc
invocations. I think these would be useful when profiling `cargo build`.
(`cargo build --timing` exists but is more geared towards debugging a
slow building project, not cargo itself)

For reference below is an example before/after of a profile run of a
dummy crate with a few random dependencies.

#### Before

![image](https://github.com/user-attachments/assets/710d1b93-133d-4826-9e7a-2deed876dbfa)

#### After

![image](https://github.com/user-attachments/assets/0f0ccad4-82b5-42ad-8762-6bd1dacecab4)
@epage
Copy link
Contributor

epage commented Apr 30, 2025

I think it would be good to also keep on eye on performance, since this could introduce more OS overhead. I'm also uncertain if we will run into lock limits, particularly on networked filesystems or filesystems like Docker, etc. It looks like the number of locks is configurable in Linux, but I don't immediately see any strict limits anywhere else.

For GC, Cargo has extended its file lock mechanism with effectively the semantics of (Read OR Append) XOR Write. A potential workaround would be to lock the entire build directory for Append (hand waiving away crates that need to be modified).

Another potential level to this problem is that we grab a Read lock for the workspace build directory and write only to a process build directory. Once we are done, we then move over any parts of the process build directory that weren't already in the workspace build directory. Risks include (1) race conditions (2) builds would happen in parallel, rather than serialized, potentially making the machine grind to a halt (currently --jobs effectively governs the workspace, not just the current process)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-build-execution Area: anything dealing with executing the compiler A-layout Area: target output directory layout, naming, and organization C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Performance Gotta go fast! S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing.
Projects
None yet
Development

No branches or pull requests

6 participants