Skip to main content

Module ch04_shared_resources

Module ch04_shared_resources 

Source
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→12

Output:

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 12

Cars 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.