53 lines
1.5 KiB
Rust
53 lines
1.5 KiB
Rust
static HYDROGEN_BONDED: AtomicU32 = AtomicU32::new(0);
|
|
static OXYGEN_BONDED: AtomicU32 = AtomicU32::new(0);
|
|
static WATER_FORMED: AtomicU32 = AtomicU32::new(0);
|
|
|
|
fn make_water() {
|
|
WATER_FORMED.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
fn timeout() {
|
|
rt::task::drop_privilege();
|
|
rt::task::sleep(1000);
|
|
|
|
let w = WATER_FORMED.load(Ordering::Relaxed);
|
|
let h = HYDROGEN_BONDED.load(Ordering::Relaxed);
|
|
let o = OXYGEN_BONDED.load(Ordering::Relaxed);
|
|
|
|
/* The oxygen or hydrogen may not have bonded by the time rt::trap is called
|
|
* after making a water molecule, so allow for o and h to be one molecule's
|
|
* worth below expected value or exactly equal to it. */
|
|
let o_lo = w - 1;
|
|
let o_hi = w;
|
|
let h_lo = (w - 1) * 2;
|
|
let h_hi = w * 2;
|
|
|
|
assert!(o >= o_lo, "not enough oxygen was bonded");
|
|
assert!(o <= o_hi, "too much oxygen was bonded");
|
|
assert!(h >= h_lo, "not enough hydrogen was bonded");
|
|
assert!(h <= h_hi, "too much hydrogen was bonded");
|
|
|
|
rt::trap();
|
|
}
|
|
|
|
fn oxygen_loop() {
|
|
rt::task::drop_privilege();
|
|
loop {
|
|
oxygen();
|
|
OXYGEN_BONDED.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
}
|
|
|
|
fn hydrogen_loop() {
|
|
rt::task::drop_privilege();
|
|
loop {
|
|
hydrogen();
|
|
HYDROGEN_BONDED.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
}
|
|
|
|
rt::task!(timeout, rt::task::STACK_MIN, 3);
|
|
rt::task!(hydrogen_loop, rt::task::STACK_MIN, 1);
|
|
rt::task!(hydrogen_loop, rt::task::STACK_MIN, 1);
|
|
rt::task!(oxygen_loop, rt::task::STACK_MIN, 2);
|