response_time_analysis/supply/
periodic.rs

1use super::SupplyBound;
2use crate::time::{Duration, Service};
3
4/// The classic periodic resource model.
5///
6/// The client(s) of this supply is/are guaranteed (at least)
7/// `budget` time units of processor service every `period` time
8/// units.
9#[derive(Debug, Clone, Copy)]
10pub struct Periodic {
11    pub period: Duration,
12    pub budget: Service,
13}
14
15impl Periodic {
16    /// Construct a new periodic supply, where `budget <= period`.
17    pub fn new(budget: Service, period: Duration) -> Self {
18        assert!(Duration::from(budget) <= period);
19        Periodic { period, budget }
20    }
21}
22
23impl SupplyBound for Periodic {
24    fn provided_service(&self, delta: Duration) -> Service {
25        // Supply bound function of the periodic resource model,
26        // as given by Shin & Lee (RTSS 2003).
27
28        let budget = Duration::from(self.budget);
29
30        let slack = self.period - budget;
31        if slack > delta {
32            return Service::none();
33        }
34        // implicit floor due to integer division
35        let full_periods = (delta - slack) / self.period;
36        let x = slack + slack + self.period * full_periods;
37        let fractional_period = if x < delta {
38            Service::from(delta - x)
39        } else {
40            Service::none()
41        };
42
43        self.budget * full_periods + fractional_period
44    }
45
46    fn service_time(&self, demand: Service) -> Duration {
47        if demand.is_none() {
48            return Duration::zero();
49        }
50
51        let demand = Duration::from(demand);
52        let budget = Duration::from(self.budget);
53        let slack = self.period - budget;
54
55        // implicit floor due to integer division
56        let full_periods = demand / budget;
57        let full_budget = budget * full_periods;
58        let fractional_budget = if full_budget < demand {
59            slack + demand - full_budget
60        } else {
61            Duration::zero()
62        };
63
64        slack + self.period * full_periods + fractional_budget
65    }
66}