DurationExt & Frequency
Ergonomic extension traits for creating Duration and Frequency values inline, designed for the HORUS scheduler API.
use horus::prelude::*; // Includes DurationExt, Frequency, and all helpers
If you're new to Rust: The 100_u64.hz() syntax may look unusual. In Rust, you can add methods to existing types using 'extension traits.' HORUS adds .hz(), .ms(), .us(), and .secs() to numbers. 100_u64.hz() means '100 Hertz.' 500_u64.ms() means '500 milliseconds.' The _u64 suffix tells Rust the number is a 64-bit unsigned integer.
DurationExt Trait
The DurationExt trait adds duration-creation methods to numeric types (u64, f64, i32). Each method returns a std::time::Duration.
| Method | Unit | Example |
|---|---|---|
.ns() | Nanoseconds | 500.ns() |
.us() | Microseconds | 200.us() |
.ms() | Milliseconds | 10.ms() |
.secs() | Seconds | 1.secs() |
use horus::prelude::*;
let budget = 500.us(); // 500 microseconds
let deadline = 1.ms(); // 1 millisecond
let timeout = 5.secs(); // 5 seconds
let precise = 100.ns(); // 100 nanoseconds
// Works on f64 for sub-unit precision
let half_ms = 0.5.ms(); // 500 microseconds
let rate_period = 10.0.ms(); // 10 milliseconds
Frequency Type
Frequency represents a rate in Hz. Created with the .hz() method on numeric types.
use horus::prelude::*;
let rate = 100.hz(); // 100 Hz
let slow = 10.hz(); // 10 Hz
let fast = 1000.hz(); // 1 kHz
// f64 for fractional rates
let precise = 33.33.hz(); // ~33.33 Hz
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
self | u64 / f64 | yes | Frequency value in Hz. Panics on zero, NaN, infinite, or negative values. |
Returns
Frequency — validated frequency value with .period(), .budget_default(), .deadline_default() methods.
Panics
0_u64.hz() panics. NaN, infinite, and negative values panic.
Methods
| Method | Return Type | Description |
|---|---|---|
value() | f64 | The frequency in Hz |
period() | Duration | Time between ticks (1 / hz) |
budget_default() | Duration | 80% of the period -- default compute budget |
deadline_default() | Duration | 95% of the period -- default deadline |
let rate = 100.hz();
assert_eq!(rate.value(), 100.0);
assert_eq!(rate.period(), 10.ms());
// Default budget = 80% of period = 8ms
assert_eq!(rate.budget_default(), 8.ms());
// Default deadline = 95% of period = 9.5ms
assert_eq!(rate.deadline_default(), Duration::from_micros(9500));
Validation
Frequency validates its input at construction time. The following values cause a panic:
- Zero -- a 0 Hz frequency has no meaningful period
- Negative -- frequencies must be positive
- NaN -- not a valid number
- Infinity -- not a finite rate
// These all panic:
// let bad = 0.hz(); // panic: zero frequency
// let bad = (-10.0).hz(); // panic: negative frequency
// let bad = f64::NAN.hz(); // panic: NaN
// let bad = f64::INFINITY.hz(); // panic: infinite frequency
Usage with the Scheduler
DurationExt and Frequency are designed for the scheduler's node builder API:
use horus::prelude::*;
let mut scheduler = Scheduler::new();
scheduler
.add(MyNode::new())
.rate(100.hz()) // 100 Hz tick rate
.budget(500.us()) // 500us compute budget
.deadline(1.ms()) // 1ms hard deadline
.on_miss(Miss::Skip) // Skip tick on deadline miss
.build()?;
scheduler
.add(SlowNode::new())
.rate(10.hz()) // 10 Hz
.budget(50.ms()) // 50ms budget (80ms period)
.deadline(80.ms()) // 80ms deadline
.build()?;
scheduler.run()?;
When you set .rate() with a Frequency, the scheduler automatically derives sensible defaults:
- Budget: 80% of the period (override with
.budget()) - Deadline: 95% of the period (override with
.deadline()) - RT auto-detection: Setting
.budget(),.deadline(), or.rate()automatically enables real-time scheduling for the node
// Minimal — budget and deadline are auto-derived from rate
scheduler
.add(SensorNode::new())
.rate(200.hz())
.build()?;
// budget = 4ms (80% of 5ms), deadline = 4.75ms (95% of 5ms), RT = auto