Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc4000a165 | ||
|
|
156dcca496 |
@@ -151,6 +151,14 @@ sizes, append-only) once the cap is actually hit. Do not let it calcify.
|
||||
hardware. Build + run full test suite on an aarch64 device; check
|
||||
`chained_spawn` / `yield_many` bench medians; merge and update README.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Look into
|
||||
|
||||
### app actors block AllDone; no external stop path
|
||||
Agent working on urus (see same git server as smarm) reported a lazily spawned actor never returning, blocking program shutdown. Maybe we should do something about it. Agent worked around it by giving the actor an atomic bool to spin on. See urus example crud for exact impl.
|
||||
|
||||
---
|
||||
|
||||
## Invariants & gotchas (respect these across all cycles)
|
||||
|
||||
+16
-14
@@ -6,22 +6,22 @@
|
||||
|
||||
use smarm::{channel, run, select, spawn};
|
||||
use std::sync::atomic::{AtomicI64, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
static OUT: AtomicI64 = AtomicI64::new(0);
|
||||
|
||||
#[test]
|
||||
fn ready_arm_returns_immediately_without_parking() {
|
||||
OUT.store(0, Ordering::SeqCst);
|
||||
run(|| {
|
||||
let out = Arc::new(AtomicI64::new(0));
|
||||
let out2 = out.clone();
|
||||
run(move || {
|
||||
let (txa, rxa) = channel::<i64>();
|
||||
let (_txb, rxb) = channel::<i64>();
|
||||
txa.send(42).unwrap();
|
||||
let i = select(&[&rxb, &rxa]);
|
||||
assert_eq!(i, 1);
|
||||
OUT.store(rxa.try_recv().unwrap().expect("ready arm must hold a message"), Ordering::SeqCst);
|
||||
out2.store(rxa.try_recv().unwrap().expect("ready arm must hold a message"), Ordering::SeqCst);
|
||||
});
|
||||
assert_eq!(OUT.load(Ordering::SeqCst), 42);
|
||||
assert_eq!(out.load(Ordering::SeqCst), 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -39,8 +39,9 @@ fn lower_index_wins_when_several_arms_are_ready() {
|
||||
|
||||
#[test]
|
||||
fn parks_until_any_arm_fires() {
|
||||
OUT.store(0, Ordering::SeqCst);
|
||||
run(|| {
|
||||
let out = Arc::new(AtomicI64::new(0));
|
||||
let out2 = out.clone();
|
||||
run(move || {
|
||||
let (txa, _rxa_keepalive) = (channel::<i64>().0, ());
|
||||
let _hold = txa; // arm a: sender alive, never sends
|
||||
let (txa, rxa) = channel::<i64>();
|
||||
@@ -52,10 +53,10 @@ fn parks_until_any_arm_fires() {
|
||||
});
|
||||
let i = select(&[&rxa, &rxb]);
|
||||
assert_eq!(i, 1);
|
||||
OUT.store(rxb.try_recv().unwrap().unwrap(), Ordering::SeqCst);
|
||||
out2.store(rxb.try_recv().unwrap().unwrap(), Ordering::SeqCst);
|
||||
h.join().unwrap();
|
||||
});
|
||||
assert_eq!(OUT.load(Ordering::SeqCst), 7);
|
||||
assert_eq!(out.load(Ordering::SeqCst), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -164,8 +165,9 @@ fn select_then_plain_recv_on_a_loser_arm() {
|
||||
#[test]
|
||||
fn select_loop_drains_two_producers_completely() {
|
||||
const N: i64 = 200;
|
||||
OUT.store(0, Ordering::SeqCst);
|
||||
run(|| {
|
||||
let out = Arc::new(AtomicI64::new(0));
|
||||
let out2 = out.clone();
|
||||
run(move || {
|
||||
let (txa, rxa) = channel::<i64>();
|
||||
let (txb, rxb) = channel::<i64>();
|
||||
let ha = spawn(move || {
|
||||
@@ -204,11 +206,11 @@ fn select_loop_drains_two_producers_completely() {
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
OUT.store(sum, Ordering::SeqCst);
|
||||
out2.store(sum, Ordering::SeqCst);
|
||||
ha.join().unwrap();
|
||||
hb.join().unwrap();
|
||||
});
|
||||
assert_eq!(OUT.load(Ordering::SeqCst), 2 * (0..200i64).sum::<i64>());
|
||||
assert_eq!(out.load(Ordering::SeqCst), 2 * (0..200i64).sum::<i64>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user