diff --git a/tests/parallel/cancellation.rs b/tests/parallel/cancellation.rs index b9590f00..2ca97894 100644 --- a/tests/parallel/cancellation.rs +++ b/tests/parallel/cancellation.rs @@ -1,54 +1,9 @@ use crate::setup::{Input, Knobs, ParDatabase, ParDatabaseImpl, WithValue}; -use salsa::Database; -use salsa::ParallelDatabase; - -#[test] -fn in_par() { - let db1 = ParDatabaseImpl::default(); - let db2 = db1.fork(); - - db1.query(Input).set('a', 100); - db1.query(Input).set('b', 010); - db1.query(Input).set('c', 001); - db1.query(Input).set('d', 200); - db1.query(Input).set('e', 020); - db1.query(Input).set('f', 002); - - let thread1 = std::thread::spawn(move || db1.sum("abc")); - - let thread2 = std::thread::spawn(move || db2.sum("def")); - - assert_eq!(thread1.join().unwrap(), 111); - assert_eq!(thread2.join().unwrap(), 222); -} - -#[test] -fn in_par_get_set_race() { - let db1 = ParDatabaseImpl::default(); - let db2 = db1.fork(); - - db1.query(Input).set('a', 100); - db1.query(Input).set('b', 010); - db1.query(Input).set('c', 001); - - let thread1 = std::thread::spawn(move || { - let v = db1.sum("abc"); - v - }); - - let thread2 = std::thread::spawn(move || { - db2.query(Input).set('a', 1000); - db2.sum("a") - }); - - // If the 1st thread runs first, you get 111, otherwise you get - // 1011. - let value1 = thread1.join().unwrap(); - assert!(value1 == 111 || value1 == 1011, "illegal result {}", value1); - - assert_eq!(thread2.join().unwrap(), 1000); -} +use salsa::{Database, ParallelDatabase}; +/// Add test where a call to `sum` is cancelled by a simultaneous +/// write. Check that we recompute the result in next revision, even +/// though none of the inputs have changed. #[test] fn in_par_get_set_cancellation() { let db = ParDatabaseImpl::default(); diff --git a/tests/parallel/independent.rs b/tests/parallel/independent.rs new file mode 100644 index 00000000..c94f5337 --- /dev/null +++ b/tests/parallel/independent.rs @@ -0,0 +1,24 @@ +use crate::setup::{Input, ParDatabase, ParDatabaseImpl}; +use salsa::{Database, ParallelDatabase}; + +/// Test two `sum` queries (on distinct keys) executing in different +/// threads. Really just a test that `fork` etc compiles. +#[test] +fn in_par_two_independent_queries() { + let db1 = ParDatabaseImpl::default(); + let db2 = db1.fork(); + + db1.query(Input).set('a', 100); + db1.query(Input).set('b', 010); + db1.query(Input).set('c', 001); + db1.query(Input).set('d', 200); + db1.query(Input).set('e', 020); + db1.query(Input).set('f', 002); + + let thread1 = std::thread::spawn(move || db1.sum("abc")); + + let thread2 = std::thread::spawn(move || db2.sum("def")); + + assert_eq!(thread1.join().unwrap(), 111); + assert_eq!(thread2.join().unwrap(), 222); +} diff --git a/tests/parallel/main.rs b/tests/parallel/main.rs index 209dbc30..a837d680 100644 --- a/tests/parallel/main.rs +++ b/tests/parallel/main.rs @@ -1,3 +1,5 @@ mod setup; mod cancellation; +mod independent; +mod race; diff --git a/tests/parallel/race.rs b/tests/parallel/race.rs new file mode 100644 index 00000000..5333dffc --- /dev/null +++ b/tests/parallel/race.rs @@ -0,0 +1,31 @@ +use crate::setup::{Input, ParDatabase, ParDatabaseImpl}; +use salsa::{Database, ParallelDatabase}; + +/// Test where a read and a set are racing with one another. +/// Should be atomic. +#[test] +fn in_par_get_set_race() { + let db1 = ParDatabaseImpl::default(); + let db2 = db1.fork(); + + db1.query(Input).set('a', 100); + db1.query(Input).set('b', 010); + db1.query(Input).set('c', 001); + + let thread1 = std::thread::spawn(move || { + let v = db1.sum("abc"); + v + }); + + let thread2 = std::thread::spawn(move || { + db2.query(Input).set('a', 1000); + db2.sum("a") + }); + + // If the 1st thread runs first, you get 111, otherwise you get + // 1011. + let value1 = thread1.join().unwrap(); + assert!(value1 == 111 || value1 == 1011, "illegal result {}", value1); + + assert_eq!(thread2.join().unwrap(), 1000); +}