Skip to main content

bb_ops/syscalls/coordination/
deadline_check.rs

1//! `DeadlineCheck` syscall op - a clock-driven gate that passes a
2//! trigger through if the current time is before its `deadline_ns`
3//! attribute, fails with `"deadline exceeded"` otherwise.
4//!
5//! Authors don't typically record this op directly; the compiler
6//! pass `bb-compiler/src/insert_async_deadlines.rs` inserts one
7//! upstream of every Async-shaped op that carries a `deadline_ns`
8//! attribute (Pattern C in the
9//! design). This is the pre-suspension gate; the engine's
10//! Phase-5 scan over `PendingAsync.deadline_ns` is the
11//! post-suspension timer.
12
13use bb_ir::proto::onnx::NodeProto;
14use bb_runtime::atomic::DispatchResult;
15use bb_runtime::bus::OpError;
16use bb_runtime::runtime::RuntimeResourceRef;
17use bb_runtime::slot_value::SlotValue;
18use bb_runtime::syscall::values::TriggerValue;
19
20/// Marker struct for `register_syscall::<DeadlineCheckOp>`.
21pub struct DeadlineCheckOp;
22
23/// `(domain, op_type)` registration key.
24pub const DOMAIN: &str = "ai.bytesandbrains.syscall";
25/// Op type name.
26pub const OP_TYPE: &str = "DeadlineCheck";
27/// Attribute name carrying the absolute deadline in nanoseconds on
28/// the engine's `scheduler.now_ns()` clock.
29pub const ATTR_DEADLINE_NS: &str = "deadline_ns";
30
31/// Invoke fn - if `now_ns < deadline_ns`, emit a `TriggerValue`;
32/// otherwise return `OpError("deadline exceeded")` which surfaces
33/// as `EngineStep::OpFailed`.
34pub fn invoke(
35    node: &NodeProto,
36    _inputs: &[(&str, &dyn SlotValue)],
37    ctx: &mut RuntimeResourceRef<'_>,
38) -> Result<DispatchResult, OpError> {
39    let deadline_ns = node
40        .attribute
41        .iter()
42        .find(|a| a.name == ATTR_DEADLINE_NS)
43        .map(|a| a.i as u64)
44        .ok_or_else(|| OpError {
45            detail: format!("DeadlineCheck missing required `{ATTR_DEADLINE_NS}` attribute"),
46            ..Default::default()
47        })?;
48    let now_ns = ctx.time.scheduler.now_ns();
49    if now_ns >= deadline_ns {
50        return Err(OpError {
51            detail: "deadline exceeded".to_string(),
52            ..Default::default()
53        });
54    }
55    Ok(DispatchResult::Immediate(vec![(
56        "trigger".to_string(),
57        Box::new(TriggerValue),
58    )]))
59}
60
61
62use bb_runtime::registry::OpRegistration as _BbOpsSyscallReg;
63
64inventory::submit! {
65    _BbOpsSyscallReg {
66        domain: DOMAIN,
67        op_type: OP_TYPE,
68        invoke,
69        kind: bb_runtime::registry::RegistrationKind::Syscall,
70    }
71}