diff --git a/Cargo.toml b/Cargo.toml index 379c5300..99c575c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ maintenance = { status = "experimental" } crossbeam-epoch = "0.8" parking_lot = "0.10" num_cpus = "1.12.0" +loom_macro = { path = "loom_macro" } [dev-dependencies] rand = "0.7" diff --git a/loom_macro/Cargo.toml b/loom_macro/Cargo.toml new file mode 100644 index 00000000..d3b7681d --- /dev/null +++ b/loom_macro/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "loom_macro" +version = "0.0.1" +edition = "2018" +autotests = false +publish = false + +[lib] +proc-macro = true + +[dependencies] +loom = "0.2.14" +syn = { version = "0.15", features = ["extra-traits", "full", "visit-mut"] } +proc-macro2 = "0.4" +quote = "0.6" \ No newline at end of file diff --git a/loom_macro/src/lib.rs b/loom_macro/src/lib.rs new file mode 100644 index 00000000..c854d394 --- /dev/null +++ b/loom_macro/src/lib.rs @@ -0,0 +1,22 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input}; + +#[proc_macro_attribute] +pub fn wrapper(args: TokenStream, input: TokenStream) -> TokenStream { + assert!(args.is_empty()); + + let ts = input.clone(); + let ast = parse_macro_input!(ts); + + if cfg!(all(loom, test)) { + let ts = quote! { + loom::model(|| { + #ast + }) + }; + ts.into() + } else { + input + } +} diff --git a/src/lib.rs b/src/lib.rs index 8e29891a..8aa7365f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -200,9 +200,6 @@ )] #![warn(rust_2018_idioms)] -#[macro_use] -extern crate lazy_static; - mod map; mod node; mod raw; diff --git a/src/map.rs b/src/map.rs index e570299f..6da55ca4 100644 --- a/src/map.rs +++ b/src/map.rs @@ -8,13 +8,14 @@ use std::fmt::{self, Debug, Formatter}; use std::hash::{BuildHasher, Hash, Hasher}; use std::iter::FromIterator; -#[cfg(debug_assertions)] +#[cfg(all(loom, test))] +use lazy_static::lazy_static; +#[cfg(all(loom, test))] use loom::sync::atomic::{AtomicUsize, Ordering}; -#[cfg(debug_assertions)] -use std::sync::atomic::AtomicIsize; -#[cfg(debug_assertions)] -use std::sync::Once; -#[cfg(not(debug_assertions))] +#[cfg(all(loom, test))] +use std::sync::{atomic::AtomicIsize, Once}; + +#[cfg(not(all(loom, test)))] use std::sync::{ atomic::{AtomicIsize, AtomicUsize, Ordering}, Once, @@ -57,10 +58,10 @@ const MAX_RESIZERS: isize = (1 << (isize_bits!() - RESIZE_STAMP_BITS)) - 1; const RESIZE_STAMP_SHIFT: usize = isize_bits!() - RESIZE_STAMP_BITS; static NCPU_INITIALIZER: Once = Once::new(); -#[cfg(not(debug_assertions))] +#[cfg(not(all(loom, test)))] static NCPU: AtomicUsize = AtomicUsize::new(0); -#[cfg(debug_assertions)] +#[cfg(all(loom, test))] lazy_static! { static ref NCPU: AtomicUsize = AtomicUsize::new(0); } diff --git a/tests/basic.rs b/tests/basic.rs index 6ded616b..b19d2f62 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -1,13 +1,16 @@ use crossbeam_epoch as epoch; use flurry::*; +use loom_macro::wrapper; + +#[cfg(all(loom, test))] use loom::sync::Arc; +#[cfg(all(loom, test))] use loom::thread; #[test] +#[wrapper] fn new() { - loom::model(|| { - let _map = HashMap::::new(); - }); + let _map = HashMap::::new(); } #[test]