makepad/libs/relax/compiler/tests/modules/deadline.rs
Admin b22a714840 makepad run: the Rust JIT (libs/relax) and makepad-remote
The JIT that runs makepad apps from source: lexer, front end, type checker,
lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and
warm/cold caches keyed by compiler stamp, provided crates bound late,
startup images, live patching. User-facing name is `makepad run` (binary
`makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal
library name. `makepad check` reports rustc-style diagnostics with rustc
error codes and checks a whole workspace (`--workspace`). Runs on macOS,
Linux, Windows and Android. makepad-remote: one tool schema for apps and the
WM (app/1): grabs, captures, traces, frame profiles and tweaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

39 lines
2.1 KiB
Rust

// The deadline worker must retain outer and concurrent guards and cancel returned
// calls. Fuel is disabled for this test so only the wall-clock limit can stop spin.
use std::relax::{guard, Module};
use std::time::{Duration, Instant};
#[test]
fn deadlines() {
let m = Module::load_source("deadline_spin", "deadline_spin.rs", "pub fn spin(n: u64) -> u64 { let mut x = 1u64; for i in 0..n { x = x.wrapping_mul(6364136223846793005).wrapping_add(i); } x }", &[]).unwrap();
let spin: fn(u64) -> u64 = m.get("spin").unwrap();
// Warm the body so the deadline never measures its first lazy compile.
for _ in 0..10000 { assert_ne!(spin(10), 0); }
std::thread::sleep(Duration::from_millis(800));
let start = Instant::now();
let outer = guard(30, || guard(1000, || spin(u64::MAX)));
assert!(outer.is_err() || outer.unwrap().is_err());
assert!(start.elapsed() < Duration::from_millis(800));
// Returning an inner guard must restore the still-active outer deadline.
let start = Instant::now();
let outer = guard(30, || { guard(1000, || spin(10)).unwrap(); spin(u64::MAX) });
assert!(outer.is_err());
assert!(start.elapsed() < Duration::from_millis(800));
// A newer guard on another thread must not cancel this thread's deadline.
let ready = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let flag = ready.clone();
let other = std::thread::spawn(move || {
while !flag.load(std::sync::atomic::Ordering::SeqCst) { std::thread::yield_now(); }
guard(1000, || std::thread::sleep(Duration::from_millis(150))).unwrap();
});
let start = Instant::now();
let r = guard(30, || { ready.store(true, std::sync::atomic::Ordering::SeqCst); spin(u64::MAX) });
assert!(r.is_err());
assert!(start.elapsed() < Duration::from_millis(800));
other.join().unwrap();
// Canceled deadlines must not interrupt a later call.
for _ in 0..100 { guard(1, || spin(10)).unwrap(); }
std::thread::sleep(Duration::from_millis(20));
assert!(guard(1000, || spin(10000)).is_ok());
println!("out deadlines: true");
}