Skip to main content

bb_ops/syscalls/triggers/
interval.rs

1//! `Interval` syscall - periodic Trigger source.
2//!
3//! Reads `period_ns` attribute, schedules a `TimerKind::Interval`
4//! on `ctx.time.scheduler`. Returns immediate Trigger output; the
5//! engine's scheduler maturity drain re-arms the next firing.
6
7use bb_ir::proto::onnx::NodeProto;
8use bb_runtime::atomic::DispatchResult;
9use bb_runtime::bus::OpError;
10use bb_runtime::framework::TimerKind;
11use bb_runtime::runtime::RuntimeResourceRef;
12use bb_runtime::slot_value::SlotValue;
13use bb_runtime::syscall::values::TimestampValue;
14
15/// Marker struct.
16pub struct IntervalOp;
17
18/// Op domain.
19pub const DOMAIN: &str = "ai.bytesandbrains.syscall";
20/// Op type name.
21pub const OP_TYPE: &str = "Interval";
22
23/// Invoke fn - schedules the next firing and emits the current
24/// trigger.
25pub fn invoke(
26    node: &NodeProto,
27    _inputs: &[(&str, &dyn SlotValue)],
28    ctx: &mut RuntimeResourceRef<'_>,
29) -> Result<DispatchResult, OpError> {
30    let period_ns = node
31        .attribute
32        .iter()
33        .find(|a| a.name == "period_ns")
34        .map(|a| a.i as u64)
35        .unwrap_or(1_000_000_000);
36    let now = ctx.time.scheduler.now_ns();
37    let op_key = ctx.current.op_ref.as_u64();
38    ctx.time.scheduler.schedule(
39        now.saturating_add(period_ns),
40        TimerKind::Interval {
41            period_ns,
42            key: op_key,
43        },
44    );
45    // Emit the current timestamp; `tick` is declared as `Timestamp`.
46    Ok(DispatchResult::Immediate(vec![(
47        "tick".to_string(),
48        Box::new(TimestampValue(now)),
49    )]))
50}
51
52use bb_runtime::registry::OpRegistration as _BbOpsSyscallReg;
53
54inventory::submit! {
55    _BbOpsSyscallReg {
56        domain: DOMAIN,
57        op_type: OP_TYPE,
58        invoke,
59        kind: bb_runtime::registry::RegistrationKind::Syscall,
60    }
61}