response_time_analysis/arrival/
sporadic.rs

1use std::iter;
2
3use super::{divide_with_ceil, ArrivalBound, Periodic};
4use crate::time::Duration;
5
6/// The classic sporadic arrival model (originally due to Mok) with release jitter.
7///
8/// A note on terminology: following standard convention, the
9/// *arrival time* of a job denotes the time at which (conceptually)
10/// the job is triggered, whereas its *release time* is the time at
11/// which it actually becomes ready for execution.
12#[derive(Copy, Clone, Debug)]
13pub struct Sporadic {
14    /// The minimum inter-arrival separation between any two job
15    /// *arrivals* of the task.
16    pub min_inter_arrival: Duration,
17    /// The maximum release jitter, i.e., the maximum time between
18    /// the *arrival* and the *release* of a job.
19    pub jitter: Duration,
20}
21
22impl Sporadic {
23    /// Construct a new sporadic arrival model with the given
24    /// inter-arrival time and jitter.
25    pub fn new(min_inter_arrival: Duration, jitter: Duration) -> Sporadic {
26        Sporadic {
27            min_inter_arrival,
28            jitter,
29        }
30    }
31
32    /// Construct a new sporadic arrival model with the given
33    /// inter-arrival time and no jitter.
34    pub fn new_zero_jitter(min_inter_arrival: Duration) -> Sporadic {
35        Sporadic {
36            min_inter_arrival,
37            jitter: Duration::zero(),
38        }
39    }
40}
41
42impl ArrivalBound for Sporadic {
43    fn number_arrivals(&self, delta: Duration) -> usize {
44        if delta.is_non_zero() {
45            divide_with_ceil(delta + self.jitter, self.min_inter_arrival) as usize
46        } else {
47            0
48        }
49    }
50
51    fn steps_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Duration> + 'a> {
52        Box::new(
53            iter::once(Duration::from(1)).chain(
54                (1..)
55                    .filter(move |j| self.min_inter_arrival * *j > self.jitter)
56                    .map(move |j| self.min_inter_arrival * j + Duration::epsilon() - self.jitter),
57            ),
58        )
59    }
60
61    fn clone_with_jitter(&self, added_jitter: Duration) -> Box<dyn ArrivalBound> {
62        let mut ab = Box::new(*self);
63        ab.jitter += added_jitter;
64        ab
65    }
66}
67
68impl From<Periodic> for Sporadic {
69    fn from(p: Periodic) -> Self {
70        Sporadic::new_zero_jitter(p.period)
71    }
72}