Rollup merge of #135621 - bjorn3:move_tests_to_stdtests, r=Noratrieb
Move some std tests to integration tests Unit tests directly inside of standard library crates require a very fragile way of building that is hard to reproduce outside of bootstrap. Follow up to https://github.com/rust-lang/rust/pull/133859
This commit is contained in:
commit
d2aa3dec8a
53 changed files with 645 additions and 650 deletions
|
@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
|
||||||
repository = "https://github.com/rust-lang/rust.git"
|
repository = "https://github.com/rust-lang/rust.git"
|
||||||
description = "The Rust Standard Library"
|
description = "The Rust Standard Library"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
autobenches = false
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["dylib", "rlib"]
|
crate-type = ["dylib", "rlib"]
|
||||||
|
@ -130,6 +131,18 @@ name = "pipe-subprocess"
|
||||||
path = "tests/pipe_subprocess.rs"
|
path = "tests/pipe_subprocess.rs"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "sync"
|
||||||
|
path = "tests/sync/lib.rs"
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "floats"
|
||||||
|
path = "tests/floats/lib.rs"
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "thread_local"
|
||||||
|
path = "tests/thread_local/lib.rs"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "stdbenches"
|
name = "stdbenches"
|
||||||
path = "benches/lib.rs"
|
path = "benches/lib.rs"
|
||||||
|
|
|
@ -5,3 +5,5 @@
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
mod hash;
|
mod hash;
|
||||||
|
mod path;
|
||||||
|
mod time;
|
||||||
|
|
114
library/std/benches/path.rs
Normal file
114
library/std/benches/path.rs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
use core::hint::black_box;
|
||||||
|
use std::collections::{BTreeSet, HashSet};
|
||||||
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
use std::path::*;
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
||||||
|
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
|
||||||
|
let prefix = "my/home";
|
||||||
|
let mut paths: Vec<_> =
|
||||||
|
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
||||||
|
|
||||||
|
paths.sort();
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
black_box(paths.as_mut_slice()).sort_unstable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
||||||
|
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
|
||||||
|
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
|
||||||
|
let paths: Vec<_> =
|
||||||
|
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
||||||
|
|
||||||
|
let mut set = BTreeSet::new();
|
||||||
|
|
||||||
|
paths.iter().for_each(|p| {
|
||||||
|
set.insert(p.as_path());
|
||||||
|
});
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
set.remove(paths[500].as_path());
|
||||||
|
set.insert(paths[500].as_path());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
||||||
|
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
|
||||||
|
let prefix = "my/home";
|
||||||
|
let paths: Vec<_> =
|
||||||
|
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
||||||
|
|
||||||
|
let mut set = BTreeSet::new();
|
||||||
|
|
||||||
|
paths.iter().for_each(|p| {
|
||||||
|
set.insert(p.as_path());
|
||||||
|
});
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
set.remove(paths[500].as_path());
|
||||||
|
set.insert(paths[500].as_path());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
||||||
|
fn bench_path_hashset(b: &mut test::Bencher) {
|
||||||
|
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
|
||||||
|
let paths: Vec<_> =
|
||||||
|
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
||||||
|
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
|
||||||
|
paths.iter().for_each(|p| {
|
||||||
|
set.insert(p.as_path());
|
||||||
|
});
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
set.remove(paths[500].as_path());
|
||||||
|
set.insert(black_box(paths[500].as_path()))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
||||||
|
fn bench_path_hashset_miss(b: &mut test::Bencher) {
|
||||||
|
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
|
||||||
|
let paths: Vec<_> =
|
||||||
|
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
||||||
|
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
|
||||||
|
paths.iter().for_each(|p| {
|
||||||
|
set.insert(p.as_path());
|
||||||
|
});
|
||||||
|
|
||||||
|
let probe = PathBuf::from(prefix).join("other");
|
||||||
|
|
||||||
|
b.iter(|| set.remove(black_box(probe.as_path())));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_hash_path_short(b: &mut test::Bencher) {
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
let path = Path::new("explorer.exe");
|
||||||
|
|
||||||
|
b.iter(|| black_box(path).hash(&mut hasher));
|
||||||
|
|
||||||
|
black_box(hasher.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_hash_path_long(b: &mut test::Bencher) {
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
let path =
|
||||||
|
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
|
||||||
|
|
||||||
|
b.iter(|| black_box(path).hash(&mut hasher));
|
||||||
|
|
||||||
|
black_box(hasher.finish());
|
||||||
|
}
|
47
library/std/benches/time.rs
Normal file
47
library/std/benches/time.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
use test::{Bencher, black_box};
|
||||||
|
|
||||||
|
macro_rules! bench_instant_threaded {
|
||||||
|
($bench_name:ident, $thread_count:expr) => {
|
||||||
|
#[bench]
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
fn $bench_name(b: &mut Bencher) -> std::thread::Result<()> {
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
let running = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
|
let threads: Vec<_> = (0..$thread_count)
|
||||||
|
.map(|_| {
|
||||||
|
let flag = Arc::clone(&running);
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
while flag.load(Ordering::Relaxed) {
|
||||||
|
black_box(Instant::now());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
let a = Instant::now();
|
||||||
|
let b = Instant::now();
|
||||||
|
assert!(b >= a);
|
||||||
|
});
|
||||||
|
|
||||||
|
running.store(false, Ordering::Relaxed);
|
||||||
|
|
||||||
|
for t in threads {
|
||||||
|
t.join()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bench_instant_threaded!(instant_contention_01_threads, 0);
|
||||||
|
bench_instant_threaded!(instant_contention_02_threads, 1);
|
||||||
|
bench_instant_threaded!(instant_contention_04_threads, 3);
|
||||||
|
bench_instant_threaded!(instant_contention_08_threads, 7);
|
||||||
|
bench_instant_threaded!(instant_contention_16_threads, 15);
|
|
@ -10,9 +10,6 @@
|
||||||
|
|
||||||
#![stable(feature = "env", since = "1.0.0")]
|
#![stable(feature = "env", since = "1.0.0")]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::ffi::{OsStr, OsString};
|
use crate::ffi::{OsStr, OsString};
|
||||||
use crate::path::{Path, PathBuf};
|
use crate::path::{Path, PathBuf};
|
||||||
|
|
120
library/std/src/env/tests.rs
vendored
120
library/std/src/env/tests.rs
vendored
|
@ -1,120 +0,0 @@
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
|
|
||||||
fn test_self_exe_path() {
|
|
||||||
let path = current_exe();
|
|
||||||
assert!(path.is_ok());
|
|
||||||
let path = path.unwrap();
|
|
||||||
|
|
||||||
// Hard to test this function
|
|
||||||
assert!(path.is_absolute());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test() {
|
|
||||||
assert!((!Path::new("test-path").is_absolute()));
|
|
||||||
|
|
||||||
#[cfg(not(target_env = "sgx"))]
|
|
||||||
current_dir().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn split_paths_windows() {
|
|
||||||
use crate::path::PathBuf;
|
|
||||||
|
|
||||||
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
|
|
||||||
split_paths(unparsed).collect::<Vec<_>>()
|
|
||||||
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(check_parse("", &mut [""]));
|
|
||||||
assert!(check_parse(r#""""#, &mut [""]));
|
|
||||||
assert!(check_parse(";;", &mut ["", "", ""]));
|
|
||||||
assert!(check_parse(r"c:\", &mut [r"c:\"]));
|
|
||||||
assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
|
|
||||||
assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
|
|
||||||
assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
|
|
||||||
assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn split_paths_unix() {
|
|
||||||
use crate::path::PathBuf;
|
|
||||||
|
|
||||||
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
|
|
||||||
split_paths(unparsed).collect::<Vec<_>>()
|
|
||||||
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(check_parse("", &mut [""]));
|
|
||||||
assert!(check_parse("::", &mut ["", "", ""]));
|
|
||||||
assert!(check_parse("/", &mut ["/"]));
|
|
||||||
assert!(check_parse("/:", &mut ["/", ""]));
|
|
||||||
assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn join_paths_unix() {
|
|
||||||
use crate::ffi::OsStr;
|
|
||||||
|
|
||||||
fn test_eq(input: &[&str], output: &str) -> bool {
|
|
||||||
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(test_eq(&[], ""));
|
|
||||||
assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
|
|
||||||
assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
|
|
||||||
assert!(join_paths(["/te:st"].iter().cloned()).is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn join_paths_windows() {
|
|
||||||
use crate::ffi::OsStr;
|
|
||||||
|
|
||||||
fn test_eq(input: &[&str], output: &str) -> bool {
|
|
||||||
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(test_eq(&[], ""));
|
|
||||||
assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
|
|
||||||
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
|
|
||||||
assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
|
|
||||||
assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn args_debug() {
|
|
||||||
assert_eq!(
|
|
||||||
format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
|
|
||||||
format!("{:?}", args())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn args_os_debug() {
|
|
||||||
assert_eq!(
|
|
||||||
format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
|
|
||||||
format!("{:?}", args_os())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vars_debug() {
|
|
||||||
assert_eq!(
|
|
||||||
format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
|
|
||||||
format!("{:?}", vars())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vars_os_debug() {
|
|
||||||
assert_eq!(
|
|
||||||
format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
|
|
||||||
format!("{:?}", vars_os())
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,9 +1,6 @@
|
||||||
#![doc = include_str!("../../core/src/error.md")]
|
#![doc = include_str!("../../core/src/error.md")]
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use core::error::Error;
|
pub use core::error::Error;
|
||||||
#[unstable(feature = "error_generic_member_access", issue = "99301")]
|
#[unstable(feature = "error_generic_member_access", issue = "99301")]
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
//!
|
//!
|
||||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[unstable(feature = "f128", issue = "116909")]
|
#[unstable(feature = "f128", issue = "116909")]
|
||||||
pub use core::f128::consts;
|
pub use core::f128::consts;
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
//!
|
//!
|
||||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[unstable(feature = "f16", issue = "116909")]
|
#[unstable(feature = "f16", issue = "116909")]
|
||||||
pub use core::f16::consts;
|
pub use core::f16::consts;
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[allow(deprecated, deprecated_in_future)]
|
#[allow(deprecated, deprecated_in_future)]
|
||||||
pub use core::f32::{
|
pub use core::f32::{
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[allow(deprecated, deprecated_in_future)]
|
#[allow(deprecated, deprecated_in_future)]
|
||||||
pub use core::f64::{
|
pub use core::f64::{
|
||||||
|
|
|
@ -372,18 +372,3 @@ macro_rules! dbg {
|
||||||
($($crate::dbg!($val)),+,)
|
($($crate::dbg!($val)),+,)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
|
|
||||||
#[cfg(test)]
|
|
||||||
macro_rules! assert_approx_eq {
|
|
||||||
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
|
|
||||||
($a:expr, $b:expr, $lim:expr) => {{
|
|
||||||
let (a, b) = (&$a, &$b);
|
|
||||||
let diff = (*a - *b).abs();
|
|
||||||
assert!(
|
|
||||||
diff < $lim,
|
|
||||||
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
|
|
||||||
lim = $lim
|
|
||||||
);
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
||||||
pub use core::num::IntErrorKind;
|
pub use core::num::IntErrorKind;
|
||||||
#[stable(feature = "generic_nonzero", since = "1.79.0")]
|
#[stable(feature = "generic_nonzero", since = "1.79.0")]
|
||||||
|
@ -29,28 +26,3 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}
|
||||||
pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
|
pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
|
||||||
#[stable(feature = "nonzero", since = "1.28.0")]
|
#[stable(feature = "nonzero", since = "1.28.0")]
|
||||||
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
|
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
use crate::fmt;
|
|
||||||
#[cfg(test)]
|
|
||||||
use crate::ops::{Add, Div, Mul, Rem, Sub};
|
|
||||||
|
|
||||||
/// Helper function for testing numeric operations
|
|
||||||
#[cfg(test)]
|
|
||||||
pub fn test_num<T>(ten: T, two: T)
|
|
||||||
where
|
|
||||||
T: PartialEq
|
|
||||||
+ Add<Output = T>
|
|
||||||
+ Sub<Output = T>
|
|
||||||
+ Mul<Output = T>
|
|
||||||
+ Div<Output = T>
|
|
||||||
+ Rem<Output = T>
|
|
||||||
+ fmt::Debug
|
|
||||||
+ Copy,
|
|
||||||
{
|
|
||||||
assert_eq!(ten.add(two), ten + two);
|
|
||||||
assert_eq!(ten.sub(two), ten - two);
|
|
||||||
assert_eq!(ten.mul(two), ten * two);
|
|
||||||
assert_eq!(ten.div(two), ten / two);
|
|
||||||
assert_eq!(ten.rem(two), ten % two);
|
|
||||||
}
|
|
||||||
|
|
|
@ -529,6 +529,3 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
|
||||||
Err(new) => BacktraceStyle::from_u8(new),
|
Err(new) => BacktraceStyle::from_u8(new),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
|
@ -67,9 +67,6 @@
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use core::clone::CloneToUninit;
|
use core::clone::CloneToUninit;
|
||||||
|
|
||||||
use crate::borrow::{Borrow, Cow};
|
use crate::borrow::{Borrow, Cow};
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
// FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available
|
// FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available
|
||||||
use crate::sync::{Condvar, Mutex};
|
use crate::sync::{Condvar, Mutex};
|
||||||
|
|
|
@ -350,6 +350,3 @@ unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
|
||||||
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
|
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
|
||||||
#[stable(feature = "lazy_cell", since = "1.80.0")]
|
#[stable(feature = "lazy_cell", since = "1.80.0")]
|
||||||
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}
|
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
|
@ -137,12 +137,6 @@
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod sync_tests;
|
|
||||||
|
|
||||||
// MPSC channels are built as a wrapper around MPMC channels, which
|
// MPSC channels are built as a wrapper around MPMC channels, which
|
||||||
// were ported from the `crossbeam-channel` crate. MPMC channels are
|
// were ported from the `crossbeam-channel` crate. MPMC channels are
|
||||||
// not exposed publicly, but if you are curious about the implementation,
|
// not exposed publicly, but if you are curious about the implementation,
|
||||||
|
@ -737,9 +731,10 @@ impl<T> SyncSender<T> {
|
||||||
// Attempts to send for a value on this receiver, returning an error if the
|
// Attempts to send for a value on this receiver, returning an error if the
|
||||||
// corresponding channel has hung up, or if it waits more than `timeout`.
|
// corresponding channel has hung up, or if it waits more than `timeout`.
|
||||||
//
|
//
|
||||||
// This method is currently private and only used for tests.
|
// This method is currently only used for tests.
|
||||||
#[allow(unused)]
|
#[unstable(issue = "none", feature = "std_internals")]
|
||||||
fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
|
#[doc(hidden)]
|
||||||
|
pub fn send_timeout(&self, t: T, timeout: Duration) -> Result<(), mpmc::SendTimeoutError<T>> {
|
||||||
self.inner.send_timeout(t, timeout)
|
self.inner.send_timeout(t, timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -681,6 +681,3 @@ unsafe impl<#[may_dangle] T> Drop for OnceLock<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex};
|
use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex};
|
||||||
use crate::sys::sync as sys;
|
use crate::sys::sync as sys;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::cell::UnsafeCell;
|
use crate::cell::UnsafeCell;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
//! This primitive is meant to be used to run one-time initialization. An
|
//! This primitive is meant to be used to run one-time initialization. An
|
||||||
//! example use case would be for initializing an FFI library.
|
//! example use case would be for initializing an FFI library.
|
||||||
|
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::panic::{RefUnwindSafe, UnwindSafe};
|
use crate::panic::{RefUnwindSafe, UnwindSafe};
|
||||||
use crate::sys::sync as sys;
|
use crate::sys::sync as sys;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use crate::cell::UnsafeCell;
|
use crate::cell::UnsafeCell;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
|
|
||||||
use crate::cell::UnsafeCell;
|
use crate::cell::UnsafeCell;
|
||||||
|
@ -324,7 +321,10 @@ impl<T: ?Sized> ReentrantLock<T> {
|
||||||
/// Otherwise, an RAII guard is returned.
|
/// Otherwise, an RAII guard is returned.
|
||||||
///
|
///
|
||||||
/// This function does not block.
|
/// This function does not block.
|
||||||
pub(crate) fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
|
// FIXME maybe make it a public part of the API?
|
||||||
|
#[unstable(issue = "none", feature = "std_internals")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn try_lock(&self) -> Option<ReentrantLockGuard<'_, T>> {
|
||||||
let this_thread = current_id();
|
let this_thread = current_id();
|
||||||
// Safety: We only touch lock_count when we own the inner mutex.
|
// Safety: We only touch lock_count when we own the inner mutex.
|
||||||
// Additionally, we only call `self.owner.set()` while holding
|
// Additionally, we only call `self.owner.set()` while holding
|
||||||
|
|
|
@ -2,12 +2,6 @@
|
||||||
|
|
||||||
#![unstable(feature = "thread_local_internals", issue = "none")]
|
#![unstable(feature = "thread_local_internals", issue = "none")]
|
||||||
|
|
||||||
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod dynamic_tests;
|
|
||||||
|
|
||||||
use crate::cell::{Cell, RefCell};
|
use crate::cell::{Cell, RefCell};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
|
|
|
@ -31,9 +31,6 @@
|
||||||
|
|
||||||
#![stable(feature = "time", since = "1.3.0")]
|
#![stable(feature = "time", since = "1.3.0")]
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[stable(feature = "time", since = "1.3.0")]
|
#[stable(feature = "time", since = "1.3.0")]
|
||||||
pub use core::time::Duration;
|
pub use core::time::Duration;
|
||||||
#[stable(feature = "duration_checked_float", since = "1.66.0")]
|
#[stable(feature = "duration_checked_float", since = "1.66.0")]
|
||||||
|
|
|
@ -1,163 +1,123 @@
|
||||||
use std::env::*;
|
use std::env::*;
|
||||||
use std::ffi::{OsStr, OsString};
|
use std::path::Path;
|
||||||
|
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use common::test_rng;
|
#[test]
|
||||||
|
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi", target_env = "sgx"), ignore)]
|
||||||
|
fn test_self_exe_path() {
|
||||||
|
let path = current_exe();
|
||||||
|
assert!(path.is_ok());
|
||||||
|
let path = path.unwrap();
|
||||||
|
|
||||||
#[track_caller]
|
// Hard to test this function
|
||||||
fn make_rand_name() -> OsString {
|
assert!(path.is_absolute());
|
||||||
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
|
|
||||||
let n = OsString::from(n);
|
|
||||||
assert!(var_os(&n).is_none());
|
|
||||||
n
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eq(a: Option<OsString>, b: Option<&str>) {
|
|
||||||
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_var() {
|
fn test() {
|
||||||
let n = make_rand_name();
|
assert!((!Path::new("test-path").is_absolute()));
|
||||||
set_var(&n, "VALUE");
|
|
||||||
eq(var_os(&n), Some("VALUE"));
|
#[cfg(not(target_env = "sgx"))]
|
||||||
|
current_dir().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remove_var() {
|
#[cfg(windows)]
|
||||||
let n = make_rand_name();
|
fn split_paths_windows() {
|
||||||
set_var(&n, "VALUE");
|
|
||||||
remove_var(&n);
|
|
||||||
eq(var_os(&n), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_set_var_overwrite() {
|
|
||||||
let n = make_rand_name();
|
|
||||||
set_var(&n, "1");
|
|
||||||
set_var(&n, "2");
|
|
||||||
eq(var_os(&n), Some("2"));
|
|
||||||
set_var(&n, "");
|
|
||||||
eq(var_os(&n), Some(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
|
||||||
fn test_var_big() {
|
|
||||||
let mut s = "".to_string();
|
|
||||||
let mut i = 0;
|
|
||||||
while i < 100 {
|
|
||||||
s.push_str("aaaaaaaaaa");
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
let n = make_rand_name();
|
|
||||||
set_var(&n, &s);
|
|
||||||
eq(var_os(&n), Some(&s));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
|
||||||
fn test_env_set_get_huge() {
|
|
||||||
let n = make_rand_name();
|
|
||||||
let s = "x".repeat(10000);
|
|
||||||
set_var(&n, &s);
|
|
||||||
eq(var_os(&n), Some(&s));
|
|
||||||
remove_var(&n);
|
|
||||||
eq(var_os(&n), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_env_set_var() {
|
|
||||||
let n = make_rand_name();
|
|
||||||
|
|
||||||
let mut e = vars_os();
|
|
||||||
set_var(&n, "VALUE");
|
|
||||||
assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
|
|
||||||
|
|
||||||
assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
|
|
||||||
#[allow(deprecated)]
|
|
||||||
fn env_home_dir() {
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
|
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
|
||||||
match var {
|
split_paths(unparsed).collect::<Vec<_>>()
|
||||||
Ok(var) => Some(OsString::from(var)),
|
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
|
||||||
Err(VarError::NotUnicode(var)) => Some(var),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
assert!(check_parse("", &mut [""]));
|
||||||
if #[cfg(unix)] {
|
assert!(check_parse(r#""""#, &mut [""]));
|
||||||
let oldhome = var_to_os_string(var("HOME"));
|
assert!(check_parse(";;", &mut ["", "", ""]));
|
||||||
|
assert!(check_parse(r"c:\", &mut [r"c:\"]));
|
||||||
|
assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
|
||||||
|
assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"]));
|
||||||
|
assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
|
||||||
|
assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
|
||||||
|
}
|
||||||
|
|
||||||
set_var("HOME", "/home/MountainView");
|
#[test]
|
||||||
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
#[cfg(unix)]
|
||||||
|
fn split_paths_unix() {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
remove_var("HOME");
|
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
|
||||||
if cfg!(target_os = "android") {
|
split_paths(unparsed).collect::<Vec<_>>()
|
||||||
assert!(home_dir().is_none());
|
== parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
|
||||||
} else {
|
|
||||||
// When HOME is not set, some platforms return `None`,
|
|
||||||
// but others return `Some` with a default.
|
|
||||||
// Just check that it is not "/home/MountainView".
|
|
||||||
assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
|
|
||||||
} else if #[cfg(windows)] {
|
|
||||||
let oldhome = var_to_os_string(var("HOME"));
|
|
||||||
let olduserprofile = var_to_os_string(var("USERPROFILE"));
|
|
||||||
|
|
||||||
remove_var("HOME");
|
|
||||||
remove_var("USERPROFILE");
|
|
||||||
|
|
||||||
assert!(home_dir().is_some());
|
|
||||||
|
|
||||||
set_var("HOME", "/home/PaloAlto");
|
|
||||||
assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
|
|
||||||
|
|
||||||
set_var("USERPROFILE", "/home/MountainView");
|
|
||||||
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
|
||||||
|
|
||||||
remove_var("HOME");
|
|
||||||
|
|
||||||
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
|
||||||
|
|
||||||
set_var("USERPROFILE", "");
|
|
||||||
assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
|
|
||||||
|
|
||||||
remove_var("USERPROFILE");
|
|
||||||
|
|
||||||
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
|
|
||||||
if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert!(check_parse("", &mut [""]));
|
||||||
|
assert!(check_parse("::", &mut ["", "", ""]));
|
||||||
|
assert!(check_parse("/", &mut ["/"]));
|
||||||
|
assert!(check_parse("/:", &mut ["/", ""]));
|
||||||
|
assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] // miri shouldn't detect any data race in this fn
|
#[test]
|
||||||
#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
|
#[cfg(unix)]
|
||||||
fn test_env_get_set_multithreaded() {
|
fn join_paths_unix() {
|
||||||
let getter = thread::spawn(|| {
|
use std::ffi::OsStr;
|
||||||
for _ in 0..100 {
|
|
||||||
let _ = var_os("foo");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let setter = thread::spawn(|| {
|
fn test_eq(input: &[&str], output: &str) -> bool {
|
||||||
for _ in 0..100 {
|
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
|
||||||
set_var("foo", "bar");
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let _ = getter.join();
|
assert!(test_eq(&[], ""));
|
||||||
let _ = setter.join();
|
assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin"));
|
||||||
|
assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:"));
|
||||||
|
assert!(join_paths(["/te:st"].iter().cloned()).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn join_paths_windows() {
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
|
||||||
|
fn test_eq(input: &[&str], output: &str) -> bool {
|
||||||
|
&*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(test_eq(&[], ""));
|
||||||
|
assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\"));
|
||||||
|
assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;"));
|
||||||
|
assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#));
|
||||||
|
assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn args_debug() {
|
||||||
|
assert_eq!(
|
||||||
|
format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
|
||||||
|
format!("{:?}", args())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn args_os_debug() {
|
||||||
|
assert_eq!(
|
||||||
|
format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
|
||||||
|
format!("{:?}", args_os())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn vars_debug() {
|
||||||
|
assert_eq!(
|
||||||
|
format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
|
||||||
|
format!("{:?}", vars())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn vars_os_debug() {
|
||||||
|
assert_eq!(
|
||||||
|
format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
|
||||||
|
format!("{:?}", vars_os())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
166
library/std/tests/env_modify.rs
Normal file
166
library/std/tests/env_modify.rs
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
// These tests are in a separate integration test as they modify the environment,
|
||||||
|
// and would otherwise cause some other tests to fail.
|
||||||
|
|
||||||
|
use std::env::*;
|
||||||
|
use std::ffi::{OsStr, OsString};
|
||||||
|
|
||||||
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
use common::test_rng;
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn make_rand_name() -> OsString {
|
||||||
|
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
|
||||||
|
let n = OsString::from(n);
|
||||||
|
assert!(var_os(&n).is_none());
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eq(a: Option<OsString>, b: Option<&str>) {
|
||||||
|
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_var() {
|
||||||
|
let n = make_rand_name();
|
||||||
|
set_var(&n, "VALUE");
|
||||||
|
eq(var_os(&n), Some("VALUE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remove_var() {
|
||||||
|
let n = make_rand_name();
|
||||||
|
set_var(&n, "VALUE");
|
||||||
|
remove_var(&n);
|
||||||
|
eq(var_os(&n), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_var_overwrite() {
|
||||||
|
let n = make_rand_name();
|
||||||
|
set_var(&n, "1");
|
||||||
|
set_var(&n, "2");
|
||||||
|
eq(var_os(&n), Some("2"));
|
||||||
|
set_var(&n, "");
|
||||||
|
eq(var_os(&n), Some(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||||
|
fn test_var_big() {
|
||||||
|
let mut s = "".to_string();
|
||||||
|
let mut i = 0;
|
||||||
|
while i < 100 {
|
||||||
|
s.push_str("aaaaaaaaaa");
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
let n = make_rand_name();
|
||||||
|
set_var(&n, &s);
|
||||||
|
eq(var_os(&n), Some(&s));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||||
|
fn test_env_set_get_huge() {
|
||||||
|
let n = make_rand_name();
|
||||||
|
let s = "x".repeat(10000);
|
||||||
|
set_var(&n, &s);
|
||||||
|
eq(var_os(&n), Some(&s));
|
||||||
|
remove_var(&n);
|
||||||
|
eq(var_os(&n), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_env_set_var() {
|
||||||
|
let n = make_rand_name();
|
||||||
|
|
||||||
|
let mut e = vars_os();
|
||||||
|
set_var(&n, "VALUE");
|
||||||
|
assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
|
||||||
|
|
||||||
|
assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(not(any(unix, windows)), ignore, allow(unused))]
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fn env_home_dir() {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> {
|
||||||
|
match var {
|
||||||
|
Ok(var) => Some(OsString::from(var)),
|
||||||
|
Err(VarError::NotUnicode(var)) => Some(var),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
let oldhome = var_to_os_string(var("HOME"));
|
||||||
|
|
||||||
|
set_var("HOME", "/home/MountainView");
|
||||||
|
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
||||||
|
|
||||||
|
remove_var("HOME");
|
||||||
|
if cfg!(target_os = "android") {
|
||||||
|
assert!(home_dir().is_none());
|
||||||
|
} else {
|
||||||
|
// When HOME is not set, some platforms return `None`,
|
||||||
|
// but others return `Some` with a default.
|
||||||
|
// Just check that it is not "/home/MountainView".
|
||||||
|
assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
|
||||||
|
} else if #[cfg(windows)] {
|
||||||
|
let oldhome = var_to_os_string(var("HOME"));
|
||||||
|
let olduserprofile = var_to_os_string(var("USERPROFILE"));
|
||||||
|
|
||||||
|
remove_var("HOME");
|
||||||
|
remove_var("USERPROFILE");
|
||||||
|
|
||||||
|
assert!(home_dir().is_some());
|
||||||
|
|
||||||
|
set_var("HOME", "/home/PaloAlto");
|
||||||
|
assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
|
||||||
|
|
||||||
|
set_var("USERPROFILE", "/home/MountainView");
|
||||||
|
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
||||||
|
|
||||||
|
remove_var("HOME");
|
||||||
|
|
||||||
|
assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
|
||||||
|
|
||||||
|
set_var("USERPROFILE", "");
|
||||||
|
assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
|
||||||
|
|
||||||
|
remove_var("USERPROFILE");
|
||||||
|
|
||||||
|
if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
|
||||||
|
if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test] // miri shouldn't detect any data race in this fn
|
||||||
|
#[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)]
|
||||||
|
fn test_env_get_set_multithreaded() {
|
||||||
|
let getter = thread::spawn(|| {
|
||||||
|
for _ in 0..100 {
|
||||||
|
let _ = var_os("foo");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let setter = thread::spawn(|| {
|
||||||
|
for _ in 0..100 {
|
||||||
|
set_var("foo", "bar");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let _ = getter.join();
|
||||||
|
let _ = setter.join();
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
use core::error::Request;
|
#![feature(error_generic_member_access, error_reporter)]
|
||||||
|
|
||||||
use super::Error;
|
use std::backtrace::Backtrace;
|
||||||
use crate::fmt;
|
use std::error::{Error, Report, Request};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct A;
|
struct A;
|
||||||
|
@ -38,9 +39,6 @@ fn downcasting() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::backtrace::Backtrace;
|
|
||||||
use crate::error::Report;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SuperError {
|
struct SuperError {
|
||||||
source: SuperErrorSideKick,
|
source: SuperErrorSideKick,
|
|
@ -1,11 +1,11 @@
|
||||||
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
|
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
|
||||||
#![cfg(reliable_f128)]
|
#![cfg(reliable_f128)]
|
||||||
|
|
||||||
use crate::f128::consts;
|
use std::f128::consts;
|
||||||
use crate::num::FpCategory as Fp;
|
use std::num::FpCategory as Fp;
|
||||||
#[cfg(reliable_f128_math)]
|
#[cfg(reliable_f128_math)]
|
||||||
use crate::ops::Rem;
|
use std::ops::Rem;
|
||||||
use crate::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
|
|
||||||
// Note these tolerances make sense around zero, but not for more extreme exponents.
|
// Note these tolerances make sense around zero, but not for more extreme exponents.
|
||||||
|
|
||||||
|
@ -762,8 +762,6 @@ fn test_ln_gamma() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
use super::consts;
|
|
||||||
|
|
||||||
let pi: f128 = consts::PI;
|
let pi: f128 = consts::PI;
|
||||||
let frac_pi_2: f128 = consts::FRAC_PI_2;
|
let frac_pi_2: f128 = consts::FRAC_PI_2;
|
||||||
let frac_pi_3: f128 = consts::FRAC_PI_3;
|
let frac_pi_3: f128 = consts::FRAC_PI_3;
|
|
@ -1,8 +1,8 @@
|
||||||
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
|
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
|
||||||
#![cfg(reliable_f16)]
|
#![cfg(reliable_f16)]
|
||||||
|
|
||||||
use crate::f16::consts;
|
use std::f16::consts;
|
||||||
use crate::num::{FpCategory as Fp, *};
|
use std::num::FpCategory as Fp;
|
||||||
|
|
||||||
/// Tolerance for results on the order of 10.0e-2
|
/// Tolerance for results on the order of 10.0e-2
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -54,7 +54,7 @@ macro_rules! assert_f16_biteq {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_f16() {
|
fn test_num_f16() {
|
||||||
test_num(10f16, 2f16);
|
crate::test_num(10f16, 2f16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -734,7 +734,6 @@ fn test_ln_gamma() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
// FIXME(f16_f128): add math tests when available
|
// FIXME(f16_f128): add math tests when available
|
||||||
use super::consts;
|
|
||||||
|
|
||||||
let pi: f16 = consts::PI;
|
let pi: f16 = consts::PI;
|
||||||
let frac_pi_2: f16 = consts::FRAC_PI_2;
|
let frac_pi_2: f16 = consts::FRAC_PI_2;
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::f32::consts;
|
use std::f32::consts;
|
||||||
use crate::num::{FpCategory as Fp, *};
|
use std::num::FpCategory as Fp;
|
||||||
|
|
||||||
/// Smallest number
|
/// Smallest number
|
||||||
const TINY_BITS: u32 = 0x1;
|
const TINY_BITS: u32 = 0x1;
|
||||||
|
@ -35,7 +35,7 @@ macro_rules! assert_f32_biteq {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_f32() {
|
fn test_num_f32() {
|
||||||
test_num(10f32, 2f32);
|
crate::test_num(10f32, 2f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -700,8 +700,6 @@ fn test_ln_gamma() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
use super::consts;
|
|
||||||
|
|
||||||
let pi: f32 = consts::PI;
|
let pi: f32 = consts::PI;
|
||||||
let frac_pi_2: f32 = consts::FRAC_PI_2;
|
let frac_pi_2: f32 = consts::FRAC_PI_2;
|
||||||
let frac_pi_3: f32 = consts::FRAC_PI_3;
|
let frac_pi_3: f32 = consts::FRAC_PI_3;
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::f64::consts;
|
use std::f64::consts;
|
||||||
use crate::num::{FpCategory as Fp, *};
|
use std::num::FpCategory as Fp;
|
||||||
|
|
||||||
/// Smallest number
|
/// Smallest number
|
||||||
const TINY_BITS: u64 = 0x1;
|
const TINY_BITS: u64 = 0x1;
|
||||||
|
@ -35,7 +35,7 @@ macro_rules! assert_f64_biteq {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_f64() {
|
fn test_num_f64() {
|
||||||
test_num(10f64, 2f64);
|
crate::test_num(10f64, 2f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -680,7 +680,6 @@ fn test_ln_gamma() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
use super::consts;
|
|
||||||
let pi: f64 = consts::PI;
|
let pi: f64 = consts::PI;
|
||||||
let frac_pi_2: f64 = consts::FRAC_PI_2;
|
let frac_pi_2: f64 = consts::FRAC_PI_2;
|
||||||
let frac_pi_3: f64 = consts::FRAC_PI_3;
|
let frac_pi_3: f64 = consts::FRAC_PI_3;
|
42
library/std/tests/floats/lib.rs
Normal file
42
library/std/tests/floats/lib.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#![feature(f16, f128, float_gamma, float_minimum_maximum)]
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use std::ops::{Add, Div, Mul, Rem, Sub};
|
||||||
|
|
||||||
|
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
|
||||||
|
macro_rules! assert_approx_eq {
|
||||||
|
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
|
||||||
|
($a:expr, $b:expr, $lim:expr) => {{
|
||||||
|
let (a, b) = (&$a, &$b);
|
||||||
|
let diff = (*a - *b).abs();
|
||||||
|
assert!(
|
||||||
|
diff < $lim,
|
||||||
|
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
|
||||||
|
lim = $lim
|
||||||
|
);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function for testing numeric operations
|
||||||
|
pub fn test_num<T>(ten: T, two: T)
|
||||||
|
where
|
||||||
|
T: PartialEq
|
||||||
|
+ Add<Output = T>
|
||||||
|
+ Sub<Output = T>
|
||||||
|
+ Mul<Output = T>
|
||||||
|
+ Div<Output = T>
|
||||||
|
+ Rem<Output = T>
|
||||||
|
+ fmt::Debug
|
||||||
|
+ Copy,
|
||||||
|
{
|
||||||
|
assert_eq!(ten.add(two), ten + two);
|
||||||
|
assert_eq!(ten.sub(two), ten - two);
|
||||||
|
assert_eq!(ten.mul(two), ten * two);
|
||||||
|
assert_eq!(ten.div(two), ten / two);
|
||||||
|
assert_eq!(ten.rem(two), ten % two);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod f128;
|
||||||
|
mod f16;
|
||||||
|
mod f32;
|
||||||
|
mod f64;
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::ops::Mul;
|
use std::ops::Mul;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_saturating_add_uint() {
|
fn test_saturating_add_uint() {
|
||||||
|
@ -190,8 +190,8 @@ fn test_uint_to_str_overflow() {
|
||||||
assert_eq!(u64_val.to_string(), "0");
|
assert_eq!(u64_val.to_string(), "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> {
|
fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
|
||||||
crate::str::FromStr::from_str(t).ok()
|
std::str::FromStr::from_str(t).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
|
@ -1,9 +1,9 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use crate::panic::{AssertUnwindSafe, UnwindSafe};
|
use std::panic::{AssertUnwindSafe, UnwindSafe};
|
||||||
use crate::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
a: i32,
|
a: i32,
|
|
@ -1,10 +1,19 @@
|
||||||
use core::hint::black_box;
|
#![feature(
|
||||||
|
clone_to_uninit,
|
||||||
|
path_add_extension,
|
||||||
|
path_file_prefix,
|
||||||
|
maybe_uninit_slice,
|
||||||
|
os_string_pathbuf_leak
|
||||||
|
)]
|
||||||
|
|
||||||
use super::*;
|
use std::clone::CloneToUninit;
|
||||||
use crate::collections::{BTreeSet, HashSet};
|
use std::ffi::OsStr;
|
||||||
use crate::hash::DefaultHasher;
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
use crate::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use crate::ptr;
|
use std::path::*;
|
||||||
|
use std::ptr;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[allow(unknown_lints, unused_macro_rules)]
|
#[allow(unknown_lints, unused_macro_rules)]
|
||||||
macro_rules! t (
|
macro_rules! t (
|
||||||
|
@ -110,7 +119,7 @@ macro_rules! t (
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn into() {
|
fn into() {
|
||||||
use crate::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
let static_path = Path::new("/home/foo");
|
let static_path = Path::new("/home/foo");
|
||||||
let static_cow_path: Cow<'static, Path> = static_path.into();
|
let static_cow_path: Cow<'static, Path> = static_path.into();
|
||||||
|
@ -1525,7 +1534,7 @@ pub fn test_with_added_extension() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eq_receivers() {
|
fn test_eq_receivers() {
|
||||||
use crate::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
let borrowed: &Path = Path::new("foo/bar");
|
let borrowed: &Path = Path::new("foo/bar");
|
||||||
let mut owned: PathBuf = PathBuf::new();
|
let mut owned: PathBuf = PathBuf::new();
|
||||||
|
@ -1550,7 +1559,7 @@ fn test_eq_receivers() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_compare() {
|
pub fn test_compare() {
|
||||||
use crate::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
|
||||||
fn hash<T: Hash>(t: T) -> u64 {
|
fn hash<T: Hash>(t: T) -> u64 {
|
||||||
let mut s = DefaultHasher::new();
|
let mut s = DefaultHasher::new();
|
||||||
|
@ -1867,12 +1876,12 @@ fn test_ord() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(unix, target_os = "wasi"))]
|
#[cfg(any(unix, target_os = "wasi"))]
|
||||||
fn test_unix_absolute() {
|
fn test_unix_absolute() {
|
||||||
use crate::path::absolute;
|
use std::path::absolute;
|
||||||
|
|
||||||
assert!(absolute("").is_err());
|
assert!(absolute("").is_err());
|
||||||
|
|
||||||
let relative = "a/b";
|
let relative = "a/b";
|
||||||
let mut expected = crate::env::current_dir().unwrap();
|
let mut expected = std::env::current_dir().unwrap();
|
||||||
expected.push(relative);
|
expected.push(relative);
|
||||||
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
|
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
|
||||||
|
|
||||||
|
@ -1888,7 +1897,7 @@ fn test_unix_absolute() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test leading `.` and `..` components
|
// Test leading `.` and `..` components
|
||||||
let curdir = crate::env::current_dir().unwrap();
|
let curdir = std::env::current_dir().unwrap();
|
||||||
assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str());
|
assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str());
|
||||||
assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a
|
assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a
|
||||||
}
|
}
|
||||||
|
@ -1896,12 +1905,12 @@ fn test_unix_absolute() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn test_windows_absolute() {
|
fn test_windows_absolute() {
|
||||||
use crate::path::absolute;
|
use std::path::absolute;
|
||||||
// An empty path is an error.
|
// An empty path is an error.
|
||||||
assert!(absolute("").is_err());
|
assert!(absolute("").is_err());
|
||||||
|
|
||||||
let relative = r"a\b";
|
let relative = r"a\b";
|
||||||
let mut expected = crate::env::current_dir().unwrap();
|
let mut expected = std::env::current_dir().unwrap();
|
||||||
expected.push(relative);
|
expected.push(relative);
|
||||||
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
|
assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
|
||||||
|
|
||||||
|
@ -1953,116 +1962,6 @@ fn test_extension_path_sep_alternate() {
|
||||||
assert_eq!(path, Path::new("path/to/file.d\\test"));
|
assert_eq!(path, Path::new("path/to/file.d\\test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
|
||||||
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
|
||||||
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
|
|
||||||
let prefix = "my/home";
|
|
||||||
let mut paths: Vec<_> =
|
|
||||||
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
|
||||||
|
|
||||||
paths.sort();
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
black_box(paths.as_mut_slice()).sort_unstable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
|
||||||
fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
|
|
||||||
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
|
|
||||||
let paths: Vec<_> =
|
|
||||||
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
|
||||||
|
|
||||||
let mut set = BTreeSet::new();
|
|
||||||
|
|
||||||
paths.iter().for_each(|p| {
|
|
||||||
set.insert(p.as_path());
|
|
||||||
});
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
set.remove(paths[500].as_path());
|
|
||||||
set.insert(paths[500].as_path());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
|
||||||
fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
|
|
||||||
let prefix = "my/home";
|
|
||||||
let paths: Vec<_> =
|
|
||||||
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
|
||||||
|
|
||||||
let mut set = BTreeSet::new();
|
|
||||||
|
|
||||||
paths.iter().for_each(|p| {
|
|
||||||
set.insert(p.as_path());
|
|
||||||
});
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
set.remove(paths[500].as_path());
|
|
||||||
set.insert(paths[500].as_path());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
|
||||||
fn bench_path_hashset(b: &mut test::Bencher) {
|
|
||||||
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
|
|
||||||
let paths: Vec<_> =
|
|
||||||
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
|
||||||
|
|
||||||
let mut set = HashSet::new();
|
|
||||||
|
|
||||||
paths.iter().for_each(|p| {
|
|
||||||
set.insert(p.as_path());
|
|
||||||
});
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
set.remove(paths[500].as_path());
|
|
||||||
set.insert(black_box(paths[500].as_path()))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
#[cfg_attr(miri, ignore)] // Miri isn't fast...
|
|
||||||
fn bench_path_hashset_miss(b: &mut test::Bencher) {
|
|
||||||
let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
|
|
||||||
let paths: Vec<_> =
|
|
||||||
(0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
|
|
||||||
|
|
||||||
let mut set = HashSet::new();
|
|
||||||
|
|
||||||
paths.iter().for_each(|p| {
|
|
||||||
set.insert(p.as_path());
|
|
||||||
});
|
|
||||||
|
|
||||||
let probe = PathBuf::from(prefix).join("other");
|
|
||||||
|
|
||||||
b.iter(|| set.remove(black_box(probe.as_path())));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_hash_path_short(b: &mut test::Bencher) {
|
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
let path = Path::new("explorer.exe");
|
|
||||||
|
|
||||||
b.iter(|| black_box(path).hash(&mut hasher));
|
|
||||||
|
|
||||||
black_box(hasher.finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_hash_path_long(b: &mut test::Bencher) {
|
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
let path =
|
|
||||||
Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
|
|
||||||
|
|
||||||
b.iter(|| black_box(path).hash(&mut hasher));
|
|
||||||
|
|
||||||
black_box(hasher.finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn clone_to_uninit() {
|
fn clone_to_uninit() {
|
||||||
let a = Path::new("hello.txt");
|
let a = Path::new("hello.txt");
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::sync::mpsc::{TryRecvError, channel};
|
use std::sync::mpsc::{TryRecvError, channel};
|
||||||
use crate::sync::{Arc, Barrier};
|
use std::sync::{Arc, Barrier};
|
||||||
use crate::thread;
|
use std::thread;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
|
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use crate::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use crate::sync::{Arc, Condvar, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
use crate::thread;
|
use std::thread;
|
||||||
use crate::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smoke() {
|
fn smoke() {
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::cell::LazyCell;
|
use std::cell::LazyCell;
|
||||||
use crate::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use crate::sync::atomic::Ordering::SeqCst;
|
use std::sync::atomic::Ordering::SeqCst;
|
||||||
use crate::sync::{LazyLock, Mutex, OnceLock};
|
use std::sync::{LazyLock, Mutex, OnceLock};
|
||||||
use crate::{panic, thread};
|
use std::{panic, thread};
|
||||||
|
|
||||||
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
|
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
|
||||||
thread::spawn(f).join().unwrap()
|
thread::spawn(f).join().unwrap()
|
||||||
|
@ -149,7 +149,7 @@ fn is_sync_send() {
|
||||||
#[should_panic = "has previously been poisoned"]
|
#[should_panic = "has previously been poisoned"]
|
||||||
fn lazy_force_mut_panic() {
|
fn lazy_force_mut_panic() {
|
||||||
let mut lazy = LazyLock::<String>::new(|| panic!());
|
let mut lazy = LazyLock::<String>::new(|| panic!());
|
||||||
crate::panic::catch_unwind(crate::panic::AssertUnwindSafe(|| {
|
panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||||
let _ = LazyLock::force_mut(&mut lazy);
|
let _ = LazyLock::force_mut(&mut lazy);
|
||||||
}))
|
}))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
31
library/std/tests/sync/lib.rs
Normal file
31
library/std/tests/sync/lib.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#![feature(lazy_get)]
|
||||||
|
#![feature(mapped_lock_guards)]
|
||||||
|
#![feature(mpmc_channel)]
|
||||||
|
#![feature(once_cell_try)]
|
||||||
|
#![feature(lock_value_accessors)]
|
||||||
|
#![feature(reentrant_lock)]
|
||||||
|
#![feature(rwlock_downgrade)]
|
||||||
|
#![feature(std_internals)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
|
mod barrier;
|
||||||
|
mod condvar;
|
||||||
|
mod lazy_lock;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod mpmc;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod mpsc;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod mpsc_sync;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod mutex;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod once;
|
||||||
|
mod once_lock;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod reentrant_lock;
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod rwlock;
|
||||||
|
|
||||||
|
#[path = "../common/mod.rs"]
|
||||||
|
mod common;
|
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use std::sync::mpmc::*;
|
||||||
use crate::{env, thread};
|
use std::time::{Duration, Instant};
|
||||||
|
use std::{env, thread};
|
||||||
|
|
||||||
pub fn stress_factor() -> usize {
|
pub fn stress_factor() -> usize {
|
||||||
match env::var("RUST_TEST_STRESS") {
|
match env::var("RUST_TEST_STRESS") {
|
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use std::sync::mpsc::*;
|
||||||
use crate::{env, thread};
|
use std::time::{Duration, Instant};
|
||||||
|
use std::{env, thread};
|
||||||
|
|
||||||
pub fn stress_factor() -> usize {
|
pub fn stress_factor() -> usize {
|
||||||
match env::var("RUST_TEST_STRESS") {
|
match env::var("RUST_TEST_STRESS") {
|
|
@ -1,7 +1,8 @@
|
||||||
use super::*;
|
use std::rc::Rc;
|
||||||
use crate::rc::Rc;
|
use std::sync::mpmc::SendTimeoutError;
|
||||||
use crate::sync::mpmc::SendTimeoutError;
|
use std::sync::mpsc::*;
|
||||||
use crate::{env, thread};
|
use std::time::Duration;
|
||||||
|
use std::{env, thread};
|
||||||
|
|
||||||
pub fn stress_factor() -> usize {
|
pub fn stress_factor() -> usize {
|
||||||
match env::var("RUST_TEST_STRESS") {
|
match env::var("RUST_TEST_STRESS") {
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use crate::ops::FnMut;
|
use std::ops::FnMut;
|
||||||
use crate::panic::{self, AssertUnwindSafe};
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use crate::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
|
use std::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
|
||||||
use crate::{hint, mem, thread};
|
use std::{hint, mem, thread};
|
||||||
|
|
||||||
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
|
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use super::Once;
|
use std::sync::Once;
|
||||||
use crate::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use crate::sync::atomic::Ordering::Relaxed;
|
use std::sync::atomic::Ordering::Relaxed;
|
||||||
use crate::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use crate::time::Duration;
|
use std::time::Duration;
|
||||||
use crate::{panic, thread};
|
use std::{panic, thread};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smoke_once() {
|
fn smoke_once() {
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
use crate::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use crate::sync::atomic::Ordering::SeqCst;
|
use std::sync::atomic::Ordering::SeqCst;
|
||||||
use crate::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use crate::{panic, thread};
|
use std::{panic, thread};
|
||||||
|
|
||||||
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
|
fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R {
|
||||||
thread::spawn(f).join().unwrap()
|
thread::spawn(f).join().unwrap()
|
||||||
|
@ -33,15 +33,6 @@ fn sync_once_cell_get_mut() {
|
||||||
assert_eq!(c.get_mut(), Some(&mut 92));
|
assert_eq!(c.get_mut(), Some(&mut 92));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sync_once_cell_get_unchecked() {
|
|
||||||
let c = OnceLock::new();
|
|
||||||
c.set(92).unwrap();
|
|
||||||
unsafe {
|
|
||||||
assert_eq!(c.get_unchecked(), &92);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
|
#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
|
||||||
fn sync_once_cell_drop() {
|
fn sync_once_cell_drop() {
|
||||||
|
@ -88,7 +79,6 @@ fn get_or_try_init() {
|
||||||
|
|
||||||
let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
|
let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() }));
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
assert!(!cell.is_initialized());
|
|
||||||
assert!(cell.get().is_none());
|
assert!(cell.get().is_none());
|
||||||
|
|
||||||
assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
|
assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
|
||||||
|
@ -174,7 +164,7 @@ fn sync_once_cell_does_not_leak_partially_constructed_boxes() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#[cfg(target_env = "sgx")]
|
#[cfg(target_env = "sgx")]
|
||||||
crate::thread::yield_now();
|
std::thread::yield_now();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
use super::ReentrantLock;
|
use std::cell::RefCell;
|
||||||
use crate::cell::RefCell;
|
use std::sync::{Arc, ReentrantLock};
|
||||||
use crate::sync::Arc;
|
use std::thread;
|
||||||
use crate::thread;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smoke() {
|
fn smoke() {
|
|
@ -1,15 +1,15 @@
|
||||||
use rand::Rng;
|
use std::fmt::Debug;
|
||||||
|
use std::ops::FnMut;
|
||||||
use crate::fmt::Debug;
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
use crate::ops::FnMut;
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use crate::panic::{self, AssertUnwindSafe};
|
use std::sync::mpsc::channel;
|
||||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::{
|
||||||
use crate::sync::mpsc::channel;
|
|
||||||
use crate::sync::{
|
|
||||||
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
|
Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
|
||||||
TryLockError,
|
TryLockError,
|
||||||
};
|
};
|
||||||
use crate::{hint, mem, thread};
|
use std::{hint, mem, thread};
|
||||||
|
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
struct NonCopy(i32);
|
struct NonCopy(i32);
|
||||||
|
@ -57,7 +57,7 @@ fn frob() {
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let r = r.clone();
|
let r = r.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut rng = crate::test_helpers::test_rng();
|
let mut rng = crate::common::test_rng();
|
||||||
for _ in 0..M {
|
for _ in 0..M {
|
||||||
if rng.gen_bool(1.0 / (N as f64)) {
|
if rng.gen_bool(1.0 / (N as f64)) {
|
||||||
drop(r.write().unwrap());
|
drop(r.write().unwrap());
|
||||||
|
@ -704,7 +704,7 @@ fn test_downgrade_atomic() {
|
||||||
|
|
||||||
// Wait for a good amount of time so that evil threads go to sleep.
|
// Wait for a good amount of time so that evil threads go to sleep.
|
||||||
// Note: this is not strictly necessary...
|
// Note: this is not strictly necessary...
|
||||||
let eternity = crate::time::Duration::from_millis(42);
|
let eternity = std::time::Duration::from_millis(42);
|
||||||
thread::sleep(eternity);
|
thread::sleep(eternity);
|
||||||
|
|
||||||
// Once everyone is asleep, set the value to `NEW_VALUE`.
|
// Once everyone is asleep, set the value to `NEW_VALUE`.
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use crate::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::thread_local;
|
use std::thread_local;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smoke() {
|
fn smoke() {
|
4
library/std/tests/thread_local/lib.rs
Normal file
4
library/std/tests/thread_local/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
mod dynamic_tests;
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::cell::{Cell, UnsafeCell};
|
use std::cell::{Cell, UnsafeCell};
|
||||||
use crate::sync::atomic::{AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicU8, Ordering};
|
||||||
use crate::sync::{Arc, Condvar, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
use crate::thread::{self, Builder, LocalKey};
|
use std::thread::{self, Builder, LocalKey};
|
||||||
use crate::thread_local;
|
use std::thread_local;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
struct Signal(Arc<(Mutex<bool>, Condvar)>);
|
struct Signal(Arc<(Mutex<bool>, Condvar)>);
|
|
@ -1,9 +1,7 @@
|
||||||
use core::fmt::Debug;
|
#![feature(duration_constants)]
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
use std::fmt::Debug;
|
||||||
use test::{Bencher, black_box};
|
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
|
||||||
|
|
||||||
macro_rules! assert_almost_eq {
|
macro_rules! assert_almost_eq {
|
||||||
($a:expr, $b:expr) => {{
|
($a:expr, $b:expr) => {{
|
||||||
|
@ -29,10 +27,10 @@ fn instant_monotonic() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
fn instant_monotonic_concurrent() -> crate::thread::Result<()> {
|
fn instant_monotonic_concurrent() -> std::thread::Result<()> {
|
||||||
let threads: Vec<_> = (0..8)
|
let threads: Vec<_> = (0..8)
|
||||||
.map(|_| {
|
.map(|_| {
|
||||||
crate::thread::spawn(|| {
|
std::thread::spawn(|| {
|
||||||
let mut old = Instant::now();
|
let mut old = Instant::now();
|
||||||
let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
|
let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
|
@ -229,46 +227,3 @@ fn big_math() {
|
||||||
check(instant.checked_add(Duration::from_secs(100)), Instant::checked_sub);
|
check(instant.checked_add(Duration::from_secs(100)), Instant::checked_sub);
|
||||||
check(instant.checked_add(Duration::from_secs(i64::MAX as _)), Instant::checked_sub);
|
check(instant.checked_add(Duration::from_secs(i64::MAX as _)), Instant::checked_sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! bench_instant_threaded {
|
|
||||||
($bench_name:ident, $thread_count:expr) => {
|
|
||||||
#[bench]
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
fn $bench_name(b: &mut Bencher) -> crate::thread::Result<()> {
|
|
||||||
use crate::sync::Arc;
|
|
||||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
|
|
||||||
let running = Arc::new(AtomicBool::new(true));
|
|
||||||
|
|
||||||
let threads: Vec<_> = (0..$thread_count)
|
|
||||||
.map(|_| {
|
|
||||||
let flag = Arc::clone(&running);
|
|
||||||
crate::thread::spawn(move || {
|
|
||||||
while flag.load(Ordering::Relaxed) {
|
|
||||||
black_box(Instant::now());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
let a = Instant::now();
|
|
||||||
let b = Instant::now();
|
|
||||||
assert!(b >= a);
|
|
||||||
});
|
|
||||||
|
|
||||||
running.store(false, Ordering::Relaxed);
|
|
||||||
|
|
||||||
for t in threads {
|
|
||||||
t.join()?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bench_instant_threaded!(instant_contention_01_threads, 0);
|
|
||||||
bench_instant_threaded!(instant_contention_02_threads, 1);
|
|
||||||
bench_instant_threaded!(instant_contention_04_threads, 3);
|
|
||||||
bench_instant_threaded!(instant_contention_08_threads, 7);
|
|
||||||
bench_instant_threaded!(instant_contention_16_threads, 15);
|
|
Loading…
Add table
Add a link
Reference in a new issue