salsa/tests/parallel/cancellation.rs

102 lines
2.8 KiB
Rust
Raw Normal View History

2018-10-13 09:22:38 +00:00
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);
}
#[test]
fn in_par_get_set_cancellation() {
let db = ParDatabaseImpl::default();
db.query(Input).set('a', 100);
db.query(Input).set('b', 010);
db.query(Input).set('c', 001);
db.query(Input).set('d', 0);
let thread1 = std::thread::spawn({
let db = db.fork();
move || {
2018-10-13 09:22:38 +00:00
let v1 = db.sum_signal_on_entry().with_value(1, || {
db.sum_await_cancellation()
.with_value(true, || db.sum("abc"))
});
// check that we observed cancellation
assert_eq!(v1, std::usize::MAX);
// at this point, we have observed cancellation, so let's
// wait until the `set` is known to have occurred.
db.signal().await(2);
// Now when we read we should get the correct sums. Note
// in particular that we re-compute the sum of `"abc"`
// even though none of our inputs have changed.
let v2 = db.sum("abc");
(v1, v2)
}
});
let thread2 = std::thread::spawn({
let db = db.fork();
move || {
// Wait until we have entered `sum` in the other thread.
db.signal().await(1);
db.query(Input).set('d', 1000);
// Signal that we have *set* `d`
db.signal().signal(2);
db.sum("d")
}
});
assert_eq!(thread1.join().unwrap(), (std::usize::MAX, 111));
assert_eq!(thread2.join().unwrap(), 1000);
}