Commit 7b75d479 authored by Marco Perronet's avatar Marco Perronet
Browse files

First match-model tool prototype

parent b9f0ff0d
Pipeline #57679 failed with stages
in 46 seconds
......@@ -47,7 +47,7 @@ pub struct Opt {
/// Maximal busy window for all curves
#[structopt(short = "w", long)]
pub max_window: Option<usize>,
pub window_size: Option<usize>,
/// Timeout for the SuspensionTimeout heuristic
#[structopt(short = "t", long)]
......
use structopt::StructOpt;
use serde_yaml;
use std::fs;
use std::collections::HashMap;
use rbf_trace::util::helpers::*;
use rbf_trace::event_generation::evg::{
EventsGenerator,
TraceEvent,
};
use rbf_trace::event_processing::invocation_cycle::*;
use rbf_trace::real_time::arrival_sequence::*;
use rbf_trace::real_time::model_matching::mm::{
ScalarMM,
CurveMM,
......@@ -14,15 +17,52 @@ use rbf_trace::real_time::model_matching::mm::{
fn main() {
let args = Opt::from_args();
let source: YamlSource;
// let mut trace_acycles: HashMap<Pid, InvocationCycle> = HashMap::new();
/* Raw events ("TraceEvent") */
let mut trace_source = YamlSource::new(&args.source_path);
/* Automaton that produces arrivals form raw events */
let mut trace_cycles: HashMap<Pid, InvocationCycle> = HashMap::new();
/* Processed events ("Arrival") */
let mut new_arrivals: HashMap<Pid, ArrivalSequence> = HashMap::new();
let mut last_update_time = 0;
/* Model matcher instances */
let mut scalar_mm = ScalarMM::new(
args.jitter_bound,
args.complexity,
args.sparsify,
args.bufsize,
args.window_size,
);
let mut curve_mm = CurveMM::new(args.window_size);
/* Process event */
while let Some(event) = trace_source.next_event() {
/* Add new arrival if this event closes an invocation cycle */
let acycle = trace_cycles.entry(event.pid).or_insert(InvocationCycle::new(event.pid, rbf_trace::params::ic_heuristic(), rbf_trace::params::ic_timeout()));
if let Some(arrival) = acycle.update_activation_cycle(event) {
let arrivals_of_pid = new_arrivals.entry(event.pid).or_insert(ArrivalSequence::new(event.pid, true, args.window_size));
arrivals_of_pid.add_arrival(arrival);
}
/* Perform model matching every update_interval seconds */
if last_update_time == 0 {
last_update_time = event.instant;
}
let last_update_elapsed = ns_to_s(event.instant - last_update_time);
if last_update_elapsed > args.update_interval {
let scalar_models = scalar_mm.update_and_match(&new_arrivals);
let curve_models = curve_mm.update_rbfs(&new_arrivals);
// if is_json_file(&args.source_path) {
// source = YamlSource::new(&args.source_path);
/* Append to output */
// TODO
// if !crate::params::rbf_model_only() {
// }
/* Reset */
last_update_time = event.instant;
new_arrivals.clear();
}
}
}
#[derive(Debug)]
......@@ -77,24 +117,28 @@ pub struct Opt {
#[structopt(short = "o", long)]
pub output_path: String,
/// Update interval
#[structopt(short = "i", long="interval", default_value="5.")]
pub update_interval: f32,
// TUNABLES
/// Jitter bound
#[structopt(short = "J", long)]
pub jitter_bound: Option<Jitter>,
#[structopt(short = "J", long, default_value="1_500_000")]
pub jitter_bound: Jitter,
/// Complexity threshold
#[structopt(short = "C", long)]
pub complexity: Option<u128>,
#[structopt(short = "C", long, default_value="1_000_000")]
pub complexity: u128,
/// Sparsify factor
#[structopt(short = "S", long)]
pub sparsify: Option<u64>,
#[structopt(short = "S", long, default_value="5")]
pub sparsify: u64,
/// Arrivals buffer size
#[structopt(short = "B", long)]
pub bufsize: Option<usize>,
#[structopt(short = "B", long, default_value="1_000")]
pub bufsize: usize,
/// Maximal busy window for all curves
#[structopt(short = "w", long)]
pub max_window: Option<usize>,
#[structopt(short = "w", long, default_value="1_000")]
pub window_size: usize,
}
......@@ -38,16 +38,16 @@ pub fn trace(evg: &mut dyn evg::EventsGenerator, target_pids: &Vec<Pid>, tx_evp:
let acycle = trace_acycles.entry(event.pid).or_insert(InvocationCycle::new(event.pid, crate::params::ic_heuristic(), crate::params::ic_timeout()));
if let Some(arrival) = acycle.update_activation_cycle(event) {
let arrivals_of_pid = arrival_seqs_updates.entry(event.pid).or_insert(ArrivalSequence::new(event.pid, true));
let arrivals_of_pid = arrival_seqs_updates.entry(event.pid).or_insert(ArrivalSequence::new(event.pid, true, crate::params::window_size()));
arrivals_of_pid.add_arrival(arrival);
new_arrivals_cnt += 1;
if crate::params::extract_arr_curve() {
let arrival_curve_of_pid = arrival_curves.entry(event.pid).or_insert(ArrivalCurve::new(event.pid));
let arrival_curve_of_pid = arrival_curves.entry(event.pid).or_insert(ArrivalCurve::new(event.pid, crate::params::window_size()));
arrival_curve_of_pid.add_arrival(arrival);
}
if crate::params::logger_replay() {
let arrivals_of_pid_whole = arrival_seqs_whole.entry(event.pid).or_insert(ArrivalSequence::new(event.pid, true));
let arrivals_of_pid_whole = arrival_seqs_whole.entry(event.pid).or_insert(ArrivalSequence::new(event.pid, true, crate::params::window_size()));
arrivals_of_pid_whole.add_arrival(arrival);
}
}
......@@ -98,8 +98,8 @@ pub fn trace(evg: &mut dyn evg::EventsGenerator, target_pids: &Vec<Pid>, tx_evp:
// Output the results
let dir_name: String = export::generate_run_name(&target_pids);
for pid in target_pids {
let arrivals_of_pid_whole = arrival_seqs_whole.entry(*pid).or_insert(ArrivalSequence::new(*pid, true));
let arrival_curve_of_pid = arrival_curves.entry(*pid).or_insert(ArrivalCurve::new(*pid));
let arrivals_of_pid_whole = arrival_seqs_whole.entry(*pid).or_insert(ArrivalSequence::new(*pid, true, crate::params::window_size()));
let arrival_curve_of_pid = arrival_curves.entry(*pid).or_insert(ArrivalCurve::new(*pid, crate::params::window_size()));
let trace_logger_of_pid = trace_loggers.entry(*pid).or_insert(trace_logger::TraceLogger::new(pid.to_string()));
// Export curves for plotting
......
......@@ -43,7 +43,7 @@ impl IcHeuristic {
}
impl InvocationCycle {
pub fn new (pid: Pid, heuristic: IcHeuristic, timeout: Time) -> InvocationCycle {
pub fn new(pid: Pid, heuristic: IcHeuristic, timeout: Time) -> InvocationCycle {
InvocationCycle {
pid : pid,
activation : 0,
......
......@@ -100,7 +100,7 @@ pub static mut RESIDUAL_SUPPLY: bool = true;
/* Curves */
// Maximum busy window for all curves
pub static mut MAX_WINDOW : usize = 1_000;
pub static mut WINDOW_SIZE : usize = 1_000;
// Maximum buffer size for the buffer containing the most relevant arrivals
pub static mut ARR_BUF_SIZE : usize = 1_000;
......@@ -146,8 +146,8 @@ pub fn set_from_args(args: Opt) {
if args.bufsize.is_some() {
ARR_BUF_SIZE = args.bufsize.unwrap();
}
if args.max_window.is_some() {
MAX_WINDOW = args.max_window.unwrap();
if args.window_size.is_some() {
WINDOW_SIZE = args.window_size.unwrap();
}
if args.suspension_timeout.is_some() {
IC_TIMEOUT = args.suspension_timeout.unwrap();
......@@ -297,8 +297,8 @@ pub fn rbf_model_only() -> bool {
pub fn residual_supply() -> bool {
unsafe { return RESIDUAL_SUPPLY; }
}
pub fn max_window() -> usize {
unsafe { return MAX_WINDOW; }
pub fn window_size() -> usize {
unsafe { return WINDOW_SIZE; }
}
pub fn arr_buf_size() -> usize {
unsafe { return ARR_BUF_SIZE; }
......
......@@ -51,5 +51,5 @@ impl PartialOrd for Arrival {
pub trait Curve {
fn add_arrival(&mut self, arrival : Arrival);
fn new(pid: Pid) -> Self;
fn new(pid: Pid, window_size: usize) -> Self;
}
......@@ -8,7 +8,7 @@ The index 0 of the array is considered to represent 2 arrivals. */
#[derive(Debug)]
pub struct ArrivalCurve {
pub last_arrivals_window: VecDeque<Arrival>,
pub max_window: usize,
pub window_size: usize,
pub curve: Vec<Duration>,
pub wcet: Cost,
pub pid: Pid,
......@@ -42,7 +42,7 @@ impl Curve for ArrivalCurve
self.last_arrivals_window.push_back(arrival);
// trim sliding window if necessary
if self.last_arrivals_window.len() > self.max_window {
if self.last_arrivals_window.len() > self.window_size {
self.last_arrivals_window.pop_front();
}
......@@ -50,12 +50,12 @@ impl Curve for ArrivalCurve
self.wcet = self.wcet.max(arrival.cost);
}
fn new (pid: Pid) -> Self
fn new (pid: Pid, window_size: usize) -> Self
{
ArrivalCurve {
last_arrivals_window : VecDeque::with_capacity(crate::params::max_window()+1),
max_window : crate::params::max_window(),
curve : Vec::with_capacity(crate::params::max_window()),
last_arrivals_window : VecDeque::with_capacity(window_size+1),
window_size : window_size,
curve : Vec::with_capacity(window_size),
wcet: 0,
pid: pid,
}
......
......@@ -3,7 +3,7 @@ use crate::util::helpers::*;
use std::collections::VecDeque;
/* A simple buffer that keep tracks of the arrivals, disregarding the cost. */
/* Only the last MAX_WINDOW arrivals are considered */
/* Only the last window_size arrivals are considered */
#[derive(Debug, Clone)]
pub struct ArrivalSequence {
pub arrivals: VecDeque<Arrival>,
......@@ -12,7 +12,7 @@ pub struct ArrivalSequence {
pub min_interarrival: Duration,
pub max_interarrival: Duration,
pub sum_interarrival: Duration,
pub max_window: usize,
pub window_size: usize,
pub wcet: Cost,
pub tot_observations: u64, // Number of observed arrivals, accounting also the ones before window got trimmed, or the arrivals were reset through clear_arrivals()
}
......@@ -32,7 +32,7 @@ impl ArrivalSequence {
self.interarrivals.push_back(new_interarrival);
/* Trim sliding window if necessary */
if self.arrivals.len() > self.max_window && self.max_window > 0 {
if self.arrivals.len() > self.window_size && self.window_size > 0 {
self.arrivals.pop_front();
popped_interarr = self.interarrivals.pop_front().unwrap();
trimmed = true;
......@@ -81,23 +81,23 @@ impl ArrivalSequence {
self.interarrivals.clear();
}
pub fn new(pid: Pid, record_all: bool) -> Self {
let max_window = if record_all { 0 } else { crate::params::max_window() };
pub fn new(pid: Pid, record_all: bool, window_size: usize) -> Self {
let w = if record_all { 0 } else { window_size };
ArrivalSequence {
arrivals: VecDeque::with_capacity(crate::params::max_window()+1),
interarrivals: VecDeque::with_capacity(crate::params::max_window()),
arrivals: VecDeque::with_capacity(window_size+1),
interarrivals: VecDeque::with_capacity(window_size),
pid: pid,
min_interarrival: 0,
max_interarrival: 0,
sum_interarrival: 0,
max_window: max_window,
window_size: w,
wcet: 0,
tot_observations: 0,
}
}
pub fn new_dummy(arrivals_t : Vec<Time>) -> Self {
let mut r = ArrivalSequence::new(123, true);
let mut r = ArrivalSequence::new(123, true, crate::params::window_size());
for a in arrivals_t {
r.add_arrival(Arrival::new(a, 0, 0, 0));
}
......@@ -107,7 +107,7 @@ impl ArrivalSequence {
}
/* A buffer that contains only the most relevant arrivals from another arrival sequence. */
/* Only the last ARR_BUF_SIZE arrivals are considered */
/* Only the last buf_size arrivals are considered */
#[derive(Debug, Clone)]
pub struct ArrivalSequenceSubset {
pub arrivals: Vec<Arrival>,
......@@ -193,11 +193,11 @@ impl ArrivalSequenceSubset {
Some(self.t_interval)
}
pub fn new(pid: Pid) -> Self {
pub fn new(pid: Pid, buf_size: usize) -> Self {
ArrivalSequenceSubset {
arrivals: Vec::with_capacity(crate::params::arr_buf_size()),
arrivals: Vec::with_capacity(buf_size),
pid: pid,
buf_size: crate::params::arr_buf_size(),
buf_size: buf_size,
wcet: 0,
t_interval: PeriodRange::default(),
}
......
......@@ -7,11 +7,16 @@ pub fn start_matching_thread(rx_matcher: Receiver<EventUpdate>, tx_matcher: Send
matching_loop(rx_matcher, tx_matcher);
}
// TODO update me
pub fn matching_loop(rx_matcher: Receiver<EventUpdate>, tx_matcher: Sender<ModelUpdate>) {
let mut scalar_mm = ScalarMM::new();
let mut curve_mm = CurveMM::new();
let mut scalar_mm = ScalarMM::new(
crate::params::jitter_bound(),
crate::params::complexity_threshold(),
crate::params::sparsify_factor(),
crate::params::arr_buf_size(),
crate::params::window_size(),
);
let mut curve_mm = CurveMM::new(crate::params::window_size());
let mut curr_update_id = 0;
if crate::params::unit_test_matcher() {
......
......@@ -9,12 +9,15 @@ use crate::util::helpers::*;
pub struct CurveMM {
/* Output */
rbfs: HashMap<Pid, RbfCurve>,
/* Tunables */
window_size: usize,
}
impl CurveMM {
pub fn update_rbfs(&mut self, new_arrivals: &HashMap<Pid, ArrivalSequence>) -> &HashMap<Pid, RbfCurve> {
for (pid, arrivals) in new_arrivals {
let rbf_of_pid = self.rbfs.entry(*pid).or_insert(RbfCurve::new(*pid));
let rbf_of_pid = self.rbfs.entry(*pid).or_insert(RbfCurve::new(*pid, self.window_size));
rbf_of_pid.add_arrivals(&arrivals);
}
......@@ -25,9 +28,10 @@ impl CurveMM {
&self.rbfs
}
pub fn new() -> Self {
pub fn new(window_size: usize) -> Self {
CurveMM {
rbfs: HashMap::new()
rbfs: HashMap::new(),
window_size: window_size,
}
}
}
......@@ -40,6 +44,13 @@ pub struct ScalarMM {
/* Output */
matched_models: HashMap<Pid, MatchedModels>,
chosen_models: HashMap<Pid, Model>,
/* Tunables */
jitter_bound: Jitter,
complexity: u128,
sparsify: u64,
bufsize: usize,
window_size: usize,
}
impl ScalarMM {
......@@ -50,17 +61,15 @@ impl ScalarMM {
self.matched_models.clear();
self.chosen_models.clear();
for (pid, arrivals) in new_arrivals {
let arrival_seq_of_pid = self.arrival_seqs.entry(*pid).or_insert(ArrivalSequence::new(*pid, false));
let arrival_buf_of_pid = self.arrival_buffers.entry(*pid).or_insert(ArrivalSequenceSubset::new(*pid));
let arrival_seq_of_pid = self.arrival_seqs.entry(*pid).or_insert(ArrivalSequence::new(*pid, false, self.window_size));
let arrival_buf_of_pid = self.arrival_buffers.entry(*pid).or_insert(ArrivalSequenceSubset::new(*pid, self.bufsize));
arrival_seq_of_pid.add_arrivals(&arrivals);
arrival_buf_of_pid.add_arrivals(&arrivals);
}
/* Match */
if !crate::params::rbf_model_only() {
self.match_pjitter_all();
self.match_sporadic_all();
}
self.match_sporadic_all();
self.match_pjitter_all();
self.disambiguate_model_all();
&self.chosen_models
......@@ -96,7 +105,7 @@ impl ScalarMM {
/* Pick nice periods based on hyperperiod minimization */
fn match_pjitter_all(&mut self) {
let pjitter_offset_models = match_pjitter_offset(&self.arrival_buffers);
let pjitter_offset_models = match_pjitter_offset(&self.arrival_buffers, self.jitter_bound, self.complexity, self.sparsify);
for (pid, model) in pjitter_offset_models {
let models_of_pid = self.matched_models.entry(pid).or_insert(MatchedModels::default());
if let Some(Model::PJitterOffset(p, j, c, o)) = model {
......@@ -109,7 +118,7 @@ impl ScalarMM {
fn disambiguate_model_all(&mut self) {
for (pid, models) in &self.matched_models {
let chosen_model_of_pid = self.chosen_models.entry(*pid).or_insert(Model::NoMatch);
let arrivals_of_pid = self.arrival_seqs.entry(*pid).or_insert(ArrivalSequence::new(*pid, false));
let arrivals_of_pid = self.arrival_seqs.entry(*pid).or_insert(ArrivalSequence::new(*pid, false, self.window_size));
/* Perform this check only now, after the arrival buffers have been updated */
if arrivals_of_pid.tot_observations >= crate::params::min_observations() {
......@@ -121,12 +130,18 @@ impl ScalarMM {
}
}
pub fn new() -> Self {
pub fn new(jitter_bound: Jitter, complexity: u128, sparsify: u64, bufsize: usize, window_size: usize,) -> Self {
ScalarMM {
arrival_seqs: HashMap::new(),
arrival_buffers: HashMap::new(),
matched_models: HashMap::new(),
chosen_models: HashMap::new(),
jitter_bound: jitter_bound,
complexity: complexity,
sparsify: sparsify,
bufsize: bufsize,
window_size: window_size,
}
}
}
......@@ -145,7 +160,7 @@ pub fn match_sporadic(arr_seq: &ArrivalSequence) -> Option<Model> {
}
/* It doesn't make sense to match pjitter on a single tasks: the picked period depends on every task in the taskset due to hyperperiod minimization. */
pub fn match_pjitter_offset(arr_buf: &HashMap<Pid, ArrivalSequenceSubset>) -> HashMap<Pid, Option<Model>> {
pub fn match_pjitter_offset(arr_buf: &HashMap<Pid, ArrivalSequenceSubset>, j_bound: Jitter, complexity: u128, sparsify: u64) -> HashMap<Pid, Option<Model>> {
let mut period_ranges: Vec<(Pid, PeriodRange)> = Vec::new();
let mut models: HashMap<Pid, Option<Model>> = HashMap::new();
......@@ -160,7 +175,7 @@ pub fn match_pjitter_offset(arr_buf: &HashMap<Pid, ArrivalSequenceSubset>) -> Ha
}
/* For the remaining pids, pick a period for each range based on hyperperiod minimization */
let periods: Vec<(Pid, Period)> = minimize_hyperperiod(&period_ranges);
let periods: Vec<(Pid, Period)> = minimize_hyperperiod(&period_ranges, complexity, sparsify);
if crate::params::print_period_ranges() {
eprintln!("Picked periods: {:#?}", periods);
}
......@@ -169,7 +184,7 @@ pub fn match_pjitter_offset(arr_buf: &HashMap<Pid, ArrivalSequenceSubset>) -> Ha
for (pid, t) in periods {
let arr_buf_of_pid = arr_buf.get(&pid).unwrap();
let (jitter, offset) = match fit_period(&arr_buf_of_pid.arrivals, t) {
let (jitter, offset) = match fit_period(&arr_buf_of_pid.arrivals, t, j_bound) {
Some(x) => { x },
// The period will fit for sure with J < JITTER_BOUND because the period ranges calculation already took care of that
None => { panic!(); },
......@@ -183,7 +198,7 @@ pub fn match_pjitter_offset(arr_buf: &HashMap<Pid, ArrivalSequenceSubset>) -> Ha
// Given an arrival sequence, returns the range of feasible periods.
pub fn get_period_range(arr_seq: &ArrivalSequence) -> Option<PeriodRange> {
let mut arr_buffer = ArrivalSequenceSubset::new(0);
let mut arr_buffer = ArrivalSequenceSubset::new(0, crate::params::arr_buf_size());
return arr_buffer.add_arrivals(arr_seq);
}
......@@ -207,7 +222,7 @@ pub fn disambiguate_model(models: &MatchedModels) -> Model {
/* Picks the periods from a set of intervals such that the hyperperiod is small */
/* Uses an heuristic: the hyperperiod is not always the minimal one */
pub fn minimize_hyperperiod(period_ranges: &Vec<(Pid, PeriodRange)>) -> Vec<(Pid, Period)> {
pub fn minimize_hyperperiod(period_ranges: &Vec<(Pid, PeriodRange)>, complexity: u128, sparsify: u64) -> Vec<(Pid, Period)> {
let mut periods = Vec::new();
let mut layers: Vec<Layer> = Vec::new();
let mut layers_c: Vec<LayerConnections> = Vec::new();
......@@ -226,8 +241,8 @@ pub fn minimize_hyperperiod(period_ranges: &Vec<(Pid, PeriodRange)>) -> Vec<(Pid
layers.push(dummy_last);
// Sparsify to make the problem tractable
while dag_complexity(&layers) > crate::params::complexity_threshold() {
sparsify_one_layer(&mut layers);
while dag_complexity(&layers) > complexity {
sparsify_one_layer(&mut layers, sparsify);
}
// Keeping connections separate from struct Layer so that it borrow checks. Indexes are the same.
......@@ -281,7 +296,7 @@ pub fn dag_complexity(layers: &Vec<Layer>) -> u128 {
}
// Take the biggest interval and shrink it such that only multiples of SPARSIFY_FACTOR are preserved
pub fn sparsify_one_layer(layers: &mut Vec<Layer>) {
pub fn sparsify_one_layer(layers: &mut Vec<Layer>, sparsify: u64) {
let mut chosen_layer_idx = 0;
let mut longest_size = 0;
......@@ -292,7 +307,7 @@ pub fn sparsify_one_layer(layers: &mut Vec<Layer>) {
}
}
let s = crate::params::sparsify_factor();
let s = sparsify;
let round_up_min = s * ((layers[chosen_layer_idx].interval.t_min as f64 / s as f64).ceil()) as Period;
let round_down_max = s * ((layers[chosen_layer_idx].interval.t_max as f64 / s as f64).floor()) as Period;
let new_min = (round_up_min / s) as u64;
......@@ -304,7 +319,7 @@ pub fn sparsify_one_layer(layers: &mut Vec<Layer>) {
}
/* Checks if the period fits in the trace, returns the jitter and offset for the best fit */
pub fn fit_period(arrivals: &Vec<Arrival>, p: Duration) -> Option<(Jitter, Offset)> {
pub fn fit_period(arrivals: &Vec<Arrival>, p: Duration, j_bound: Jitter) -> Option<(Jitter, Offset)> {
let mut jitter: i64; // Can be negative, in which case the period doesn't fit
let mut max_jitter: Jitter = 0;
let mut max_error: u64 = 0;
......@@ -327,7 +342,7 @@ pub fn fit_period(arrivals: &Vec<Arrival>, p: Duration) -> Option<(Jitter, Offse
jitter = arr.instant as i64 - t;
// If the jitter was negative, this will prevent us from trying again with first_arr_jitter > JITTER_BOUND
if jitter.abs() as u64 > crate::params::jitter_bound() { // Too much jitter
if jitter.abs() as u64 > j_bound { // Too much jitter
return None;
}
if n_tries > 1 && jitter < 0 { // Period is too big
......@@ -353,7 +368,7 @@ pub fn fit_period(arrivals: &Vec<Arrival>, p: Duration) -> Option<(Jitter, Offse
}
if fit_found {
assert!(max_jitter <= crate::params::jitter_bound());
assert!(max_jitter <= j_bound);
assert!(first_arr_jitter <= max_jitter);
let offset = first_arr as i64 - first_arr_jitter as i64;
......
......@@ -12,7 +12,7 @@ The distance is *exclusive*, meaning that:
#[derive(Debug, Clone)]
pub struct RbfCurve {
pub last_arrivals_window: VecDeque <Arrival>,
pub max_window: usize,
pub window_size: usize,
pub curve: SparseMap,
pub wcet: Cost,
pub pid: Pid,
......@@ -47,7 +47,7 @@ impl RbfCurve {
}
// trim sliding window if necessary
if self.last_arrivals_window.len() > self.max_window {
if self.last_arrivals_window.len() > self.window_size {
self.last_arrivals_window.pop_front();
}
......@@ -121,12 +121,12 @@ impl RbfCurve {
print!("\n");
}
pub fn new(pid: Pid) -> Self {
let mut curve = SparseMap::new(crate::params::max_window());
pub fn new(pid: Pid, window_size: usize) -> Self {
let mut curve = SparseMap::new(window_size);
curve.add(Point::new(0, 0));
RbfCurve {
last_arrivals_window: VecDeque::with_capacity(crate::params::max_window()+1),
max_window: crate::params::max_window(),
last_arrivals_window: VecDeque::with_capacity(window_size+1),
window_size: window_size,
curve: curve,
wcet: 0,
pid: pid,
......
......@@ -4,7 +4,6 @@ use crate::util::helpers::*;
/* This curve represents how long it takes in the worst case to receive a certain amount of service. */
#[derive(Debug, Clone)]
pub struct RtbCurve {
pub max_window: usize, // TODO use me for assertions
pub curve: Vec<RtbRange>,
pub pid: Pid,
pub prio: Priority,
......@@ -106,7 +105,6 @@ impl RtbCurve {
pub fn new(pid: Pid) -> Self {
let curve = Vec::new();
RtbCurve {
max_window: crate::params::max_window(),
curve: curve,
pid: pid,
prio: 0,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment