forked from ROMEO/nexosim
Merge pull request #55 from asynchronics/feature/multiexecutor-integration-tests
Run integration tests on both ST and MT executors
This commit is contained in:
commit
c6fd4d90c4
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -3,7 +3,7 @@ name: CI
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches: [main, dev]
|
branches: [ main ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: -Dwarnings
|
RUSTFLAGS: -Dwarnings
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Dry-run cargo test (Loom)
|
- name: Dry-run cargo test (Loom)
|
||||||
run: cargo test --no-run --tests --all-features
|
run: cargo test --no-run --lib --all-features
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: --cfg asynchronix_loom
|
RUSTFLAGS: --cfg asynchronix_loom
|
||||||
|
|
||||||
|
3
.github/workflows/loom.yml
vendored
3
.github/workflows/loom.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: Loom
|
name: Loom
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
@ -30,6 +31,6 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Run cargo test (Loom)
|
- name: Run cargo test (Loom)
|
||||||
run: cargo test --tests --release
|
run: cargo test --lib --release
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: --cfg asynchronix_loom
|
RUSTFLAGS: --cfg asynchronix_loom
|
||||||
|
@ -21,7 +21,6 @@ A high performance asychronous compute framework for system simulation.
|
|||||||
"""
|
"""
|
||||||
categories = ["simulation", "aerospace", "science"]
|
categories = ["simulation", "aerospace", "science"]
|
||||||
keywords = ["simulation", "discrete-event", "systems", "cyberphysical", "real-time"]
|
keywords = ["simulation", "discrete-event", "systems", "cyberphysical", "real-time"]
|
||||||
autotests = false
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# gRPC service.
|
# gRPC service.
|
||||||
@ -65,7 +64,7 @@ futures-executor = "0.3"
|
|||||||
tracing-subscriber = { version= "0.3.18", features=["env-filter"] }
|
tracing-subscriber = { version= "0.3.18", features=["env-filter"] }
|
||||||
|
|
||||||
[target.'cfg(asynchronix_loom)'.dev-dependencies]
|
[target.'cfg(asynchronix_loom)'.dev-dependencies]
|
||||||
loom = "0.5"
|
loom = "0.7"
|
||||||
waker-fn = "1.1"
|
waker-fn = "1.1"
|
||||||
|
|
||||||
[target.'cfg(asynchronix_grpc_codegen)'.build-dependencies]
|
[target.'cfg(asynchronix_grpc_codegen)'.build-dependencies]
|
||||||
@ -79,7 +78,3 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(asynchronix_loom)', 'cfg(a
|
|||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[[test]]
|
|
||||||
name = "integration"
|
|
||||||
path = "tests/tests.rs"
|
|
||||||
|
@ -128,7 +128,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn loom_cached_rw_lock_write() {
|
fn loom_cached_rw_lock_write() {
|
||||||
const DEFAULT_PREEMPTION_BOUND: usize = 4;
|
const DEFAULT_PREEMPTION_BOUND: usize = 3;
|
||||||
const ITERATIONS_NUMBER: usize = 5;
|
const ITERATIONS_NUMBER: usize = 5;
|
||||||
|
|
||||||
let mut builder = Builder::new();
|
let mut builder = Builder::new();
|
||||||
|
@ -7,8 +7,9 @@ use asynchronix::ports::{EventBuffer, Output};
|
|||||||
use asynchronix::simulation::{ActionKey, Mailbox, SimInit};
|
use asynchronix::simulation::{ActionKey, Mailbox, SimInit};
|
||||||
use asynchronix::time::MonotonicTime;
|
use asynchronix::time::MonotonicTime;
|
||||||
|
|
||||||
#[test]
|
const MT_NUM_THREADS: usize = 4;
|
||||||
fn model_schedule_event() {
|
|
||||||
|
fn model_schedule_event(num_threads: usize) {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TestModel {
|
struct TestModel {
|
||||||
output: Output<()>,
|
output: Output<()>,
|
||||||
@ -38,7 +39,10 @@ fn model_schedule_event() {
|
|||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new().add_model(model, mbox, "").init(t0).unwrap();
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
|
.add_model(model, mbox, "")
|
||||||
|
.init(t0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
||||||
simu.step().unwrap();
|
simu.step().unwrap();
|
||||||
@ -48,8 +52,7 @@ fn model_schedule_event() {
|
|||||||
assert!(output.next().is_none());
|
assert!(output.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn model_cancel_future_keyed_event(num_threads: usize) {
|
||||||
fn model_cancel_future_keyed_event() {
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TestModel {
|
struct TestModel {
|
||||||
output: Output<i32>,
|
output: Output<i32>,
|
||||||
@ -93,7 +96,10 @@ fn model_cancel_future_keyed_event() {
|
|||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new().add_model(model, mbox, "").init(t0).unwrap();
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
|
.add_model(model, mbox, "")
|
||||||
|
.init(t0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
||||||
simu.step().unwrap();
|
simu.step().unwrap();
|
||||||
@ -104,8 +110,7 @@ fn model_cancel_future_keyed_event() {
|
|||||||
assert!(output.next().is_none());
|
assert!(output.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn model_cancel_same_time_keyed_event(num_threads: usize) {
|
||||||
fn model_cancel_same_time_keyed_event() {
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TestModel {
|
struct TestModel {
|
||||||
output: Output<i32>,
|
output: Output<i32>,
|
||||||
@ -149,7 +154,10 @@ fn model_cancel_same_time_keyed_event() {
|
|||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new().add_model(model, mbox, "").init(t0).unwrap();
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
|
.add_model(model, mbox, "")
|
||||||
|
.init(t0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
||||||
simu.step().unwrap();
|
simu.step().unwrap();
|
||||||
@ -160,8 +168,7 @@ fn model_cancel_same_time_keyed_event() {
|
|||||||
assert!(output.next().is_none());
|
assert!(output.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn model_schedule_periodic_event(num_threads: usize) {
|
||||||
fn model_schedule_periodic_event() {
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TestModel {
|
struct TestModel {
|
||||||
output: Output<i32>,
|
output: Output<i32>,
|
||||||
@ -192,7 +199,10 @@ fn model_schedule_periodic_event() {
|
|||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new().add_model(model, mbox, "").init(t0).unwrap();
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
|
.add_model(model, mbox, "")
|
||||||
|
.init(t0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
||||||
|
|
||||||
@ -208,8 +218,7 @@ fn model_schedule_periodic_event() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn model_cancel_periodic_event(num_threads: usize) {
|
||||||
fn model_cancel_periodic_event() {
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TestModel {
|
struct TestModel {
|
||||||
output: Output<()>,
|
output: Output<()>,
|
||||||
@ -243,7 +252,10 @@ fn model_cancel_periodic_event() {
|
|||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new().add_model(model, mbox, "").init(t0).unwrap();
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
|
.add_model(model, mbox, "")
|
||||||
|
.init(t0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
simu.process_event(TestModel::trigger, (), addr).unwrap();
|
||||||
|
|
||||||
@ -256,3 +268,53 @@ fn model_cancel_periodic_event() {
|
|||||||
assert_eq!(simu.time(), t0 + Duration::from_secs(2));
|
assert_eq!(simu.time(), t0 + Duration::from_secs(2));
|
||||||
assert!(output.next().is_none());
|
assert!(output.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_schedule_event_st() {
|
||||||
|
model_schedule_event(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_schedule_event_mt() {
|
||||||
|
model_schedule_event(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_cancel_future_keyed_event_st() {
|
||||||
|
model_cancel_future_keyed_event(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_cancel_future_keyed_event_mt() {
|
||||||
|
model_cancel_future_keyed_event(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_cancel_same_time_keyed_event_st() {
|
||||||
|
model_cancel_same_time_keyed_event(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_cancel_same_time_keyed_event_mt() {
|
||||||
|
model_cancel_same_time_keyed_event(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_schedule_periodic_event_st() {
|
||||||
|
model_schedule_periodic_event(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_schedule_periodic_event_mt() {
|
||||||
|
model_schedule_periodic_event(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_cancel_periodic_event_st() {
|
||||||
|
model_cancel_periodic_event(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn model_cancel_periodic_event_mt() {
|
||||||
|
model_cancel_periodic_event(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
@ -5,6 +5,8 @@ use asynchronix::ports::{Output, Requestor};
|
|||||||
use asynchronix::simulation::{DeadlockInfo, ExecutionError, Mailbox, SimInit};
|
use asynchronix::simulation::{DeadlockInfo, ExecutionError, Mailbox, SimInit};
|
||||||
use asynchronix::time::MonotonicTime;
|
use asynchronix::time::MonotonicTime;
|
||||||
|
|
||||||
|
const MT_NUM_THREADS: usize = 4;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TestModel {
|
struct TestModel {
|
||||||
output: Output<()>,
|
output: Output<()>,
|
||||||
@ -22,8 +24,7 @@ impl Model for TestModel {}
|
|||||||
|
|
||||||
/// Overflows a mailbox by sending 2 messages in loopback for each incoming
|
/// Overflows a mailbox by sending 2 messages in loopback for each incoming
|
||||||
/// message.
|
/// message.
|
||||||
#[test]
|
fn deadlock_on_mailbox_overflow(num_threads: usize) {
|
||||||
fn deadlock_on_mailbox_overflow() {
|
|
||||||
const MODEL_NAME: &str = "testmodel";
|
const MODEL_NAME: &str = "testmodel";
|
||||||
const MAILBOX_SIZE: usize = 5;
|
const MAILBOX_SIZE: usize = 5;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ fn deadlock_on_mailbox_overflow() {
|
|||||||
.connect(TestModel::activate_output, addr.clone());
|
.connect(TestModel::activate_output, addr.clone());
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new()
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
.add_model(model, mbox, MODEL_NAME)
|
.add_model(model, mbox, MODEL_NAME)
|
||||||
.init(t0)
|
.init(t0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -64,8 +65,7 @@ fn deadlock_on_mailbox_overflow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a deadlock with a query loopback.
|
/// Generates a deadlock with a query loopback.
|
||||||
#[test]
|
fn deadlock_on_query_loopback(num_threads: usize) {
|
||||||
fn deadlock_on_query_loopback() {
|
|
||||||
const MODEL_NAME: &str = "testmodel";
|
const MODEL_NAME: &str = "testmodel";
|
||||||
|
|
||||||
let mut model = TestModel::default();
|
let mut model = TestModel::default();
|
||||||
@ -77,7 +77,7 @@ fn deadlock_on_query_loopback() {
|
|||||||
.connect(TestModel::activate_requestor, addr.clone());
|
.connect(TestModel::activate_requestor, addr.clone());
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new()
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
.add_model(model, mbox, MODEL_NAME)
|
.add_model(model, mbox, MODEL_NAME)
|
||||||
.init(t0)
|
.init(t0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -100,8 +100,7 @@ fn deadlock_on_query_loopback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a deadlock with a query loopback involving several models.
|
/// Generates a deadlock with a query loopback involving several models.
|
||||||
#[test]
|
fn deadlock_on_transitive_query_loopback(num_threads: usize) {
|
||||||
fn deadlock_on_transitive_query_loopback() {
|
|
||||||
const MODEL1_NAME: &str = "testmodel1";
|
const MODEL1_NAME: &str = "testmodel1";
|
||||||
const MODEL2_NAME: &str = "testmodel2";
|
const MODEL2_NAME: &str = "testmodel2";
|
||||||
|
|
||||||
@ -121,7 +120,7 @@ fn deadlock_on_transitive_query_loopback() {
|
|||||||
.connect(TestModel::activate_requestor, addr1.clone());
|
.connect(TestModel::activate_requestor, addr1.clone());
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new()
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
.add_model(model1, mbox1, MODEL1_NAME)
|
.add_model(model1, mbox1, MODEL1_NAME)
|
||||||
.add_model(model2, mbox2, MODEL2_NAME)
|
.add_model(model2, mbox2, MODEL2_NAME)
|
||||||
.init(t0)
|
.init(t0)
|
||||||
@ -145,8 +144,7 @@ fn deadlock_on_transitive_query_loopback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates deadlocks with query loopbacks on several models at the same time.
|
/// Generates deadlocks with query loopbacks on several models at the same time.
|
||||||
#[test]
|
fn deadlock_on_multiple_query_loopback(num_threads: usize) {
|
||||||
fn deadlock_on_multiple_query_loopback() {
|
|
||||||
const MODEL0_NAME: &str = "testmodel0";
|
const MODEL0_NAME: &str = "testmodel0";
|
||||||
const MODEL1_NAME: &str = "testmodel1";
|
const MODEL1_NAME: &str = "testmodel1";
|
||||||
const MODEL2_NAME: &str = "testmodel2";
|
const MODEL2_NAME: &str = "testmodel2";
|
||||||
@ -178,7 +176,7 @@ fn deadlock_on_multiple_query_loopback() {
|
|||||||
.connect(TestModel::activate_requestor, addr2);
|
.connect(TestModel::activate_requestor, addr2);
|
||||||
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let mut simu = SimInit::new()
|
let mut simu = SimInit::with_num_threads(num_threads)
|
||||||
.add_model(model0, mbox0, MODEL0_NAME)
|
.add_model(model0, mbox0, MODEL0_NAME)
|
||||||
.add_model(model1, mbox1, MODEL1_NAME)
|
.add_model(model1, mbox1, MODEL1_NAME)
|
||||||
.add_model(model2, mbox2, MODEL2_NAME)
|
.add_model(model2, mbox2, MODEL2_NAME)
|
||||||
@ -209,3 +207,43 @@ fn deadlock_on_multiple_query_loopback() {
|
|||||||
_ => panic!("deadlock not detected"),
|
_ => panic!("deadlock not detected"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_mailbox_overflow_st() {
|
||||||
|
deadlock_on_mailbox_overflow(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_mailbox_overflow_mt() {
|
||||||
|
deadlock_on_mailbox_overflow(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_query_loopback_st() {
|
||||||
|
deadlock_on_query_loopback(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_query_loopback_mt() {
|
||||||
|
deadlock_on_query_loopback(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_transitive_query_loopback_st() {
|
||||||
|
deadlock_on_transitive_query_loopback(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_transitive_query_loopback_mt() {
|
||||||
|
deadlock_on_transitive_query_loopback(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_multiple_query_loopback_st() {
|
||||||
|
deadlock_on_multiple_query_loopback(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deadlock_on_multiple_query_loopback_mt() {
|
||||||
|
deadlock_on_multiple_query_loopback(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
const MT_NUM_THREADS: usize = 4;
|
||||||
|
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
use asynchronix::model::Context;
|
use asynchronix::model::Context;
|
||||||
use asynchronix::model::Model;
|
use asynchronix::model::Model;
|
||||||
@ -28,6 +30,7 @@ impl<T: Clone + Send + 'static> Model for PassThroughModel<T> {}
|
|||||||
/// A simple bench containing a single pass-through model (input forwarded to
|
/// A simple bench containing a single pass-through model (input forwarded to
|
||||||
/// output) running as fast as possible.
|
/// output) running as fast as possible.
|
||||||
fn passthrough_bench<T: Clone + Send + 'static>(
|
fn passthrough_bench<T: Clone + Send + 'static>(
|
||||||
|
num_threads: usize,
|
||||||
t0: MonotonicTime,
|
t0: MonotonicTime,
|
||||||
) -> (Simulation, Address<PassThroughModel<T>>, EventBuffer<T>) {
|
) -> (Simulation, Address<PassThroughModel<T>>, EventBuffer<T>) {
|
||||||
// Bench assembly.
|
// Bench assembly.
|
||||||
@ -38,15 +41,17 @@ fn passthrough_bench<T: Clone + Send + 'static>(
|
|||||||
model.output.connect_sink(&out_stream);
|
model.output.connect_sink(&out_stream);
|
||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let simu = SimInit::new().add_model(model, mbox, "").init(t0).unwrap();
|
let simu = SimInit::with_num_threads(num_threads)
|
||||||
|
.add_model(model, mbox, "")
|
||||||
|
.init(t0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
(simu, addr, out_stream)
|
(simu, addr, out_stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn simulation_schedule_events(num_threads: usize) {
|
||||||
fn simulation_schedule_events() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let (mut simu, addr, mut output) = passthrough_bench(t0);
|
let (mut simu, addr, mut output) = passthrough_bench(num_threads, t0);
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
|
|
||||||
@ -85,10 +90,9 @@ fn simulation_schedule_events() {
|
|||||||
assert!(output.next().is_none());
|
assert!(output.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn simulation_schedule_keyed_events(num_threads: usize) {
|
||||||
fn simulation_schedule_keyed_events() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let (mut simu, addr, mut output) = passthrough_bench(t0);
|
let (mut simu, addr, mut output) = passthrough_bench(num_threads, t0);
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
|
|
||||||
@ -127,10 +131,9 @@ fn simulation_schedule_keyed_events() {
|
|||||||
assert!(output.next().is_none());
|
assert!(output.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn simulation_schedule_periodic_events(num_threads: usize) {
|
||||||
fn simulation_schedule_periodic_events() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let (mut simu, addr, mut output) = passthrough_bench(t0);
|
let (mut simu, addr, mut output) = passthrough_bench(num_threads, t0);
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
|
|
||||||
@ -167,10 +170,9 @@ fn simulation_schedule_periodic_events() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn simulation_schedule_periodic_keyed_events(num_threads: usize) {
|
||||||
fn simulation_schedule_periodic_keyed_events() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
let (mut simu, addr, mut output) = passthrough_bench(t0);
|
let (mut simu, addr, mut output) = passthrough_bench(num_threads, t0);
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
|
|
||||||
@ -216,6 +218,46 @@ fn simulation_schedule_periodic_keyed_events() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_events_st() {
|
||||||
|
simulation_schedule_events(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_events_mt() {
|
||||||
|
simulation_schedule_events(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_keyed_events_st() {
|
||||||
|
simulation_schedule_keyed_events(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_keyed_events_mt() {
|
||||||
|
simulation_schedule_keyed_events(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_periodic_events_st() {
|
||||||
|
simulation_schedule_periodic_events(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_periodic_events_mt() {
|
||||||
|
simulation_schedule_periodic_events(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_periodic_keyed_events_st() {
|
||||||
|
simulation_schedule_periodic_keyed_events(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simulation_schedule_periodic_keyed_events_mt() {
|
||||||
|
simulation_schedule_periodic_keyed_events(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
use std::time::{Instant, SystemTime};
|
use std::time::{Instant, SystemTime};
|
||||||
|
|
||||||
@ -245,6 +287,7 @@ impl Model for TimestampModel {
|
|||||||
/// A simple bench containing a single timestamping model with a custom clock.
|
/// A simple bench containing a single timestamping model with a custom clock.
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
fn timestamp_bench(
|
fn timestamp_bench(
|
||||||
|
num_threads: usize,
|
||||||
t0: MonotonicTime,
|
t0: MonotonicTime,
|
||||||
clock: impl Clock + 'static,
|
clock: impl Clock + 'static,
|
||||||
) -> (
|
) -> (
|
||||||
@ -260,7 +303,7 @@ fn timestamp_bench(
|
|||||||
model.stamp.connect_sink(&stamp_stream);
|
model.stamp.connect_sink(&stamp_stream);
|
||||||
let addr = mbox.address();
|
let addr = mbox.address();
|
||||||
|
|
||||||
let simu = SimInit::new()
|
let simu = SimInit::with_num_threads(num_threads)
|
||||||
.add_model(model, mbox, "")
|
.add_model(model, mbox, "")
|
||||||
.set_clock(clock)
|
.set_clock(clock)
|
||||||
.init(t0)
|
.init(t0)
|
||||||
@ -270,8 +313,7 @@ fn timestamp_bench(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
#[test]
|
fn simulation_system_clock_from_instant(num_threads: usize) {
|
||||||
fn simulation_system_clock_from_instant() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
const TOLERANCE: f64 = 0.005; // [s]
|
const TOLERANCE: f64 = 0.005; // [s]
|
||||||
|
|
||||||
@ -293,7 +335,7 @@ fn simulation_system_clock_from_instant() {
|
|||||||
|
|
||||||
let clock = SystemClock::from_instant(simulation_ref, wall_clock_ref);
|
let clock = SystemClock::from_instant(simulation_ref, wall_clock_ref);
|
||||||
|
|
||||||
let (mut simu, addr, mut stamp) = timestamp_bench(t0, clock);
|
let (mut simu, addr, mut stamp) = timestamp_bench(num_threads, t0, clock);
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
|
|
||||||
@ -327,8 +369,7 @@ fn simulation_system_clock_from_instant() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
#[test]
|
fn simulation_system_clock_from_system_time(num_threads: usize) {
|
||||||
fn simulation_system_clock_from_system_time() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
const TOLERANCE: f64 = 0.005; // [s]
|
const TOLERANCE: f64 = 0.005; // [s]
|
||||||
|
|
||||||
@ -350,7 +391,7 @@ fn simulation_system_clock_from_system_time() {
|
|||||||
|
|
||||||
let clock = SystemClock::from_system_time(simulation_ref, wall_clock_ref);
|
let clock = SystemClock::from_system_time(simulation_ref, wall_clock_ref);
|
||||||
|
|
||||||
let (mut simu, addr, mut stamp) = timestamp_bench(t0, clock);
|
let (mut simu, addr, mut stamp) = timestamp_bench(num_threads, t0, clock);
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
|
|
||||||
@ -390,12 +431,11 @@ fn simulation_system_clock_from_system_time() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
#[test]
|
fn simulation_auto_system_clock(num_threads: usize) {
|
||||||
fn simulation_auto_system_clock() {
|
|
||||||
let t0 = MonotonicTime::EPOCH;
|
let t0 = MonotonicTime::EPOCH;
|
||||||
const TOLERANCE: f64 = 0.005; // [s]
|
const TOLERANCE: f64 = 0.005; // [s]
|
||||||
|
|
||||||
let (mut simu, addr, mut stamp) = timestamp_bench(t0, AutoSystemClock::new());
|
let (mut simu, addr, mut stamp) = timestamp_bench(num_threads, t0, AutoSystemClock::new());
|
||||||
let instant_t0 = Instant::now();
|
let instant_t0 = Instant::now();
|
||||||
|
|
||||||
let scheduler = simu.scheduler();
|
let scheduler = simu.scheduler();
|
||||||
@ -435,3 +475,39 @@ fn simulation_auto_system_clock() {
|
|||||||
simu.step().unwrap();
|
simu.step().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn simulation_system_clock_from_instant_st() {
|
||||||
|
simulation_system_clock_from_instant(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn simulation_system_clock_from_instant_mt() {
|
||||||
|
simulation_system_clock_from_instant(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn simulation_system_clock_from_system_time_st() {
|
||||||
|
simulation_system_clock_from_system_time(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn simulation_system_clock_from_system_time_mt() {
|
||||||
|
simulation_system_clock_from_system_time(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn simulation_auto_system_clock_st() {
|
||||||
|
simulation_auto_system_clock(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(miri))]
|
||||||
|
#[test]
|
||||||
|
fn simulation_auto_system_clock_mt() {
|
||||||
|
simulation_auto_system_clock(MT_NUM_THREADS);
|
||||||
|
}
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#[cfg(not(asynchronix_loom))]
|
|
||||||
mod model_scheduling;
|
|
||||||
#[cfg(not(asynchronix_loom))]
|
|
||||||
mod simulation_deadlock;
|
|
||||||
#[cfg(not(asynchronix_loom))]
|
|
||||||
mod simulation_scheduling;
|
|
Loading…
x
Reference in New Issue
Block a user