Expand description
§gwr-engine
gwr_engine is a single-threaded asynchronous simulation engine designed to run
models of asynchronous simulation components.
The engine can run purely event-driven models, clocked models, or simulations that combine both styles. Components are registered with the engine before execution, ports are connected before a run starts, and clocks provide modeled time for tasks that need deterministic delays.
§Features
-
global_allocator: When enabled, applications that depend ongwr-engineuse a global allocator selected to deliver strong runtime performance for the GWR engine. This is currently mimalloc.This feature is enabled by default. Applications that need a different global allocator must disable it explicitly.
§Developer Guide
The Developer Guide provides a directed explanation of the GWR engine and
related libraries. See the gwr-developer-guide/ folder for the source.
§Examples
The examples/ folder contains worked examples:
flaky-component: a simple two-port component.flaky-with-delay: a simple two-port component with subcomponents.scrambler: a component that registers a vector of subcomponents.sim-pipe: a flow-controlled pipeline.sim-restaurant: a fast food restaurant model used to explore staffing profitability.sim-ring: a device comprising a ring of nodes.sim-fabric: a device comprising a rectangular fabric.
§Example
The engine is created as a mutable object engine:
let mut engine = Engine::default();§Clocks
See the time module documentation for details on creating and using clocks.
§Spawner
A new asynchronous process is created using the spawner from the engine. For
example, creating a new process can be done with:
use gwr_engine::engine::Engine;
fn main() {
let mut engine = Engine::default();
let clock = engine.default_clock();
let spawner = engine.spawner();
spawner.spawn(async move {
for i in 0..10 {
clock.wait_ticks(1).await;
println!("Waiting {i}");
}
Ok(())
});
}[!Note] The
Enginemakes no guarantees about the order in which tasks are evaluated within the same clock tick.
§Simple Application
A very simple application connects a source to a sink and then runs the engine:
use gwr_components::sink::Sink;
use gwr_components::source::Source;
use gwr_components::{connect_port, option_box_repeat};
use gwr_engine::engine::Engine;
use gwr_engine::run_simulation;
let mut engine = Engine::default();
let clock = engine.default_clock();
let mut source = Source::new_and_register(&engine, engine.top(), "source", option_box_repeat!(0x123 ; 10));
let sink = Sink::new_and_register(&engine, &clock, engine.top(), "sink");
connect_port!(source, tx => sink, rx)
.expect("should be able to connect `Source` to `Sink`");
run_simulation!(engine);
assert_eq!(sink.num_sunk(), 10);Modules§
- engine
- events
- Different types of events.
- executor
- port
- Typed, back-pressure-aware ports used to compose components and models.
- test_
helpers - time
- Modules that model time within the simulations.
- traits
- A set of common traits used across GWR Engine.
- types
- Shared types.
Macros§
- run_
simulation - Spawn all component run() functions and then run the simulation.
- sim_
error - Build a SimError from a message that supports
to_string - spawn_
subcomponent - Spawn a sub-component that is stored in an
RefCell<Option<>>