Expand description
Chapter 4: Shared resources — queuing for limited capacity.
Real systems have contention: two charging spots, one doctor, three beds.
A Resource models a pool of identical units.
request() resolves immediately if a unit is
free, otherwise the process suspends in a FIFO queue. The resolved value is
an RAII ResourceGuard: the unit is released when
the guard drops — no explicit release() call, and no way to forget it.
Sharing works by cloning the handle — every clone is the same pool.
(No Arc, no Mutex: the whole simulation is single-threaded by design.)
Four cars arrive, staggered, at a two-spot battery charging station:
use simu::{SimEnv, Resource};
let mut env = SimEnv::with_seed(42);
let bcs = Resource::new(2); // battery charging station, 2 spots
for i in 0..4u32 {
let h = env.handle();
let station = bcs.clone(); // same pool, cheap Rc clone
env.spawn(async move {
h.timeout(f64::from(i) * 2.0).await; // drive to the station
println!("Car {i} arriving at {}", h.now());
let _spot = station.request().await; // queue for a spot (FIFO)
println!("Car {i} starting to charge at {}", h.now());
h.timeout(5.0).await; // charge
println!("Car {i} leaving at {}", h.now());
}); // _spot drops here → spot handed to the next car in line
}
env.run();
assert_eq!(env.now(), 12.0); // last car: arrives t=6, waits, charges 7→12Output:
Car 0 arriving at 0
Car 0 starting to charge at 0
Car 1 arriving at 2
Car 1 starting to charge at 2
Car 2 arriving at 4
Car 0 leaving at 5
Car 2 starting to charge at 5
Car 3 arriving at 6
Car 1 leaving at 7
Car 3 starting to charge at 7
Car 2 leaving at 10
Car 3 leaving at 12Cars 0 and 1 charge immediately; cars 2 and 3 queue and take over spots the moment earlier cars leave. Release-to-next-waiter is a direct handoff: a freshly released unit can never be stolen by a same-instant new request jumping the queue.