Skip to content

Commit

Permalink
allow bypassing the build directory lock
Browse files Browse the repository at this point in the history
As bootstrap locks its entire build directory, parallel bootstrapping
for anything becomes impossible. This change enables developers to bypass
the locking mechanism when it is unnecessary for their specific use case.

Signed-off-by: onur-ozkan <[email protected]>
  • Loading branch information
onur-ozkan committed Dec 9, 2023
1 parent ee5ef3a commit 6860654
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 68 deletions.
61 changes: 33 additions & 28 deletions src/bootstrap/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,40 @@ fn main() {
let mut build_lock;
#[cfg(all(any(unix, windows), not(target_os = "solaris")))]
let _build_lock_guard;
#[cfg(all(any(unix, windows), not(target_os = "solaris")))]
// Display PID of process holding the lock
// PID will be stored in a lock file
{
let path = config.out.join("lock");
let pid = match fs::read_to_string(&path) {
Ok(contents) => contents,
Err(_) => String::new(),
};

build_lock =
fd_lock::RwLock::new(t!(fs::OpenOptions::new().write(true).create(true).open(&path)));
_build_lock_guard = match build_lock.try_write() {
Ok(mut lock) => {
t!(lock.write(&process::id().to_string().as_ref()));
lock
}
err => {
drop(err);
println!("WARNING: build directory locked by process {pid}, waiting for lock");
let mut lock = t!(build_lock.write());
t!(lock.write(&process::id().to_string().as_ref()));
lock
}
};
}

#[cfg(any(not(any(unix, windows)), target_os = "solaris"))]
println!("WARNING: file locking not supported for target, not locking build directory");
if !config.bypass_bootstrap_lock {
// Display PID of process holding the lock
// PID will be stored in a lock file
#[cfg(all(any(unix, windows), not(target_os = "solaris")))]
{
let path = config.out.join("lock");
let pid = match fs::read_to_string(&path) {
Ok(contents) => contents,
Err(_) => String::new(),
};

build_lock = fd_lock::RwLock::new(t!(fs::OpenOptions::new()
.write(true)
.create(true)
.open(&path)));
_build_lock_guard = match build_lock.try_write() {
Ok(mut lock) => {
t!(lock.write(&process::id().to_string().as_ref()));
lock
}
err => {
drop(err);
println!("WARNING: build directory locked by process {pid}, waiting for lock");
let mut lock = t!(build_lock.write());
t!(lock.write(&process::id().to_string().as_ref()));
lock
}
};
}

#[cfg(any(not(any(unix, windows)), target_os = "solaris"))]
println!("WARNING: file locking not supported for target, not locking build directory");
}

// check_version warnings are not printed during setup
let changelog_suggestion =
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl Display for DebuginfoLevel {
pub struct Config {
pub changelog_seen: Option<usize>, // FIXME: Deprecated field. Remove it at 2024.
pub change_id: Option<usize>,
pub bypass_bootstrap_lock: bool,
pub ccache: Option<String>,
/// Call Build::ninja() instead of this.
pub ninja_in_file: bool,
Expand Down Expand Up @@ -1057,6 +1058,7 @@ define_config! {
impl Config {
pub fn default_opts() -> Config {
let mut config = Config::default();
config.bypass_bootstrap_lock = false;
config.llvm_optimize = true;
config.ninja_in_file = true;
config.llvm_static_stdcpp = false;
Expand Down Expand Up @@ -1135,6 +1137,7 @@ impl Config {
config.llvm_profile_use = flags.llvm_profile_use;
config.llvm_profile_generate = flags.llvm_profile_generate;
config.enable_bolt_settings = flags.enable_bolt_settings;
config.bypass_bootstrap_lock = flags.bypass_bootstrap_lock;

// Infer the rest of the configuration.

Expand Down
7 changes: 7 additions & 0 deletions src/bootstrap/src/core/config/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ pub struct Flags {
/// whether to use color in cargo and rustc output
pub color: Color,

#[arg(global(true), long)]
/// Bootstrap uses this value to decide whether it should bypass locking the build process.
/// This is rarely needed (e.g., compiling the std library for different targets in parallel).
///
/// Unless you know exactly what you are doing, you probably don't need this.
pub bypass_bootstrap_lock: bool,

/// whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml
#[arg(global(true), long, value_name = "VALUE")]
pub llvm_skip_rebuild: Option<bool>,
Expand Down
Loading

0 comments on commit 6860654

Please sign in to comment.