diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0a9284e46..4c221821f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -51,6 +51,13 @@ jobs: name: tsan rust_version: nightly +# Loom +- template: ci/azure-loom.yml + parameters: + name: loom + rust_version: stable + + - template: ci/azure-deploy-docs.yml parameters: dependsOn: diff --git a/ci/azure-loom.yml b/ci/azure-loom.yml new file mode 100644 index 000000000..1db9c3afe --- /dev/null +++ b/ci/azure-loom.yml @@ -0,0 +1,15 @@ +jobs: +- job: ${{parameters.name}} + displayName: Loom tests + pool: + vmImage: ubuntu-16.04 + + steps: + - template: azure-install-rust.yml + parameters: + rust_version: ${{parameters.rust_version}} + + - script: RUSTFLAGS="--cfg loom" cargo test --lib + displayName: RUSTFLAGS="--cfg loom" cargo test --lib + + diff --git a/src/bytes.rs b/src/bytes.rs index e07106f60..7b1e1e120 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -903,3 +903,36 @@ unsafe fn release_shared(ptr: *mut Shared) { // Drop the data Box::from_raw(ptr); } + +// fuzz tests +#[cfg(all(test, loom))] +mod fuzz { + use std::sync::Arc; + use loom::thread; + + use super::Bytes; + #[test] + fn bytes_cloning_vec() { + loom::model(|| { + let a = Bytes::from(b"abcdefgh".to_vec()); + let addr = a.as_ptr() as usize; + + // test the Bytes::clone is Sync by putting it in an Arc + let a1 = Arc::new(a); + let a2 = a1.clone(); + + let t1 = thread::spawn(move || { + let b: Bytes = (*a1).clone(); + assert_eq!(b.as_ptr() as usize, addr); + }); + + let t2 = thread::spawn(move || { + let b: Bytes = (*a2).clone(); + assert_eq!(b.as_ptr() as usize, addr); + }); + + t1.join().unwrap(); + t2.join().unwrap(); + }); + } +} diff --git a/src/bytes_mut.rs b/src/bytes_mut.rs index bc8cc0524..6cf791a01 100644 --- a/src/bytes_mut.rs +++ b/src/bytes_mut.rs @@ -1427,3 +1427,38 @@ unsafe fn shared_v_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) let shared = (*data.get_mut()) as *mut Shared; release_shared(shared as *mut Shared); } + +// fuzz tests +#[cfg(all(test, loom))] +mod fuzz { + use std::sync::Arc; + use loom::thread; + + use crate::Bytes; + use super::BytesMut; + + #[test] + fn bytes_mut_cloning_frozen() { + loom::model(|| { + let a = BytesMut::from(&b"abcdefgh"[..]).split().freeze(); + let addr = a.as_ptr() as usize; + + // test the Bytes::clone is Sync by putting it in an Arc + let a1 = Arc::new(a); + let a2 = a1.clone(); + + let t1 = thread::spawn(move || { + let b: Bytes = (*a1).clone(); + assert_eq!(b.as_ptr() as usize, addr); + }); + + let t2 = thread::spawn(move || { + let b: Bytes = (*a2).clone(); + assert_eq!(b.as_ptr() as usize, addr); + }); + + t1.join().unwrap(); + t2.join().unwrap(); + }); + } +} diff --git a/src/loom.rs b/src/loom.rs index b7c704e3a..80947acec 100644 --- a/src/loom.rs +++ b/src/loom.rs @@ -1,5 +1,9 @@ +#[cfg(not(all(test, loom)))] pub(crate) mod sync { pub(crate) mod atomic { pub(crate) use core::sync::atomic::{fence, AtomicPtr, AtomicUsize, Ordering}; } } + +#[cfg(all(test, loom))] +pub(crate) use ::loom::sync; diff --git a/tests/fuzz_bytes.rs b/tests/fuzz_bytes.rs deleted file mode 100644 index 5f894dde9..000000000 --- a/tests/fuzz_bytes.rs +++ /dev/null @@ -1,73 +0,0 @@ -// pretend to like `crate::` -extern crate alloc; -#[path = "../src/buf/mod.rs"] -#[allow(warnings)] -mod buf; -#[path = "../src/debug.rs"] -#[allow(warnings)] -mod debug; -#[path = "../src/bytes.rs"] -#[allow(warnings)] -mod bytes; -#[path = "../src/bytes_mut.rs"] -#[allow(warnings)] -mod bytes_mut; -use std::process::abort; - -use self::buf::{Buf, BufMut}; -use self::bytes::Bytes; -use self::bytes_mut::BytesMut; - -use std::sync::Arc; -use loom; -use loom::thread; - -#[test] -fn bytes_cloning_vec() { - loom::model(|| { - let a = Bytes::from(b"abcdefgh".to_vec()); - let addr = a.as_ptr() as usize; - - // test the Bytes::clone is Sync by putting it in an Arc - let a1 = Arc::new(a); - let a2 = a1.clone(); - - let t1 = thread::spawn(move || { - let b: Bytes = (*a1).clone(); - assert_eq!(b.as_ptr() as usize, addr); - }); - - let t2 = thread::spawn(move || { - let b: Bytes = (*a2).clone(); - assert_eq!(b.as_ptr() as usize, addr); - }); - - t1.join().unwrap(); - t2.join().unwrap(); - }); -} - -#[test] -fn bytes_mut_cloning_frozen() { - loom::model(|| { - let a = BytesMut::from(&b"abcdefgh"[..]).split().freeze(); - let addr = a.as_ptr() as usize; - - // test the Bytes::clone is Sync by putting it in an Arc - let a1 = Arc::new(a); - let a2 = a1.clone(); - - let t1 = thread::spawn(move || { - let b: Bytes = (*a1).clone(); - assert_eq!(b.as_ptr() as usize, addr); - }); - - let t2 = thread::spawn(move || { - let b: Bytes = (*a2).clone(); - assert_eq!(b.as_ptr() as usize, addr); - }); - - t1.join().unwrap(); - t2.join().unwrap(); - }); -}