moved exec scheduler into lib

This commit is contained in:
Robin Müller 2022-05-26 19:23:31 +02:00
parent 35aa7c450c
commit e9567e3872
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
2 changed files with 48 additions and 44 deletions

View File

@ -1,3 +1,8 @@
use std::error::Error;
use std::thread;
use std::thread::JoinHandle;
use std::time::Duration;
pub enum OpResult { pub enum OpResult {
Ok, Ok,
} }
@ -15,3 +20,45 @@ pub trait Executable: Send {
fn task_name(&self) -> &'static str; fn task_name(&self) -> &'static str;
fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, Self::Error>; fn periodic_op(&mut self, op_code: i32) -> Result<OpResult, Self::Error>;
} }
pub fn executable_scheduler<
T: Executable<Error = E> + Send + 'static + ?Sized,
E: Error + Send + 'static,
>(
mut executable_vec: Vec<Box<T>>,
task_freq: Option<Duration>,
op_code: i32,
) -> JoinHandle<Result<OpResult, E>> {
let mut cycle_counts = vec![0; executable_vec.len()];
let mut removal_flags = vec![false; executable_vec.len()];
thread::spawn(move || loop {
for (idx, executable) in executable_vec.iter_mut().enumerate() {
match executable.exec_type() {
ExecutionType::OneShot => {
executable.periodic_op(op_code)?;
removal_flags[idx] = true;
}
ExecutionType::Infinite => {
executable.periodic_op(op_code)?;
}
ExecutionType::Cycles(cycles) => {
executable.periodic_op(op_code)?;
cycle_counts[idx] += 1;
if cycle_counts[idx] == cycles {
removal_flags[idx] = true;
}
}
}
}
let mut removal_iter = removal_flags.iter();
executable_vec.retain(|_| !*removal_iter.next().unwrap());
removal_iter = removal_flags.iter();
cycle_counts.retain(|_| !*removal_iter.next().unwrap());
removal_flags.retain(|&i| !i);
if executable_vec.is_empty() {
return Ok(OpResult::Ok);
}
let freq = task_freq.unwrap_or_else(|| panic!("No task frequency specified"));
thread::sleep(freq);
})
}

View File

@ -1,8 +1,7 @@
use launchpad::core::executable::{Executable, ExecutionType, OpResult}; use launchpad::core::executable::{executable_scheduler, Executable, ExecutionType, OpResult};
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::thread; use std::thread;
use std::thread::JoinHandle;
use std::time::Duration; use std::time::Duration;
struct OneShotTask {} struct OneShotTask {}
@ -135,45 +134,3 @@ fn main() {
thread::sleep(Duration::from_millis(1000)); thread::sleep(Duration::from_millis(1000));
test1(); test1();
} }
fn executable_scheduler<
T: Executable<Error = E> + Send + 'static + ?Sized,
E: Error + Send + 'static,
>(
mut executable_vec: Vec<Box<T>>,
task_freq: Option<Duration>,
op_code: i32,
) -> JoinHandle<Result<OpResult, E>> {
let mut cycle_counts = vec![0; executable_vec.len()];
let mut removal_flags = vec![false; executable_vec.len()];
thread::spawn(move || loop {
for (idx, executable) in executable_vec.iter_mut().enumerate() {
match executable.exec_type() {
ExecutionType::OneShot => {
executable.periodic_op(op_code)?;
removal_flags[idx] = true;
}
ExecutionType::Infinite => {
executable.periodic_op(op_code)?;
}
ExecutionType::Cycles(cycles) => {
executable.periodic_op(op_code)?;
cycle_counts[idx] += 1;
if cycle_counts[idx] == cycles {
removal_flags[idx] = true;
}
}
}
}
let mut removal_iter = removal_flags.iter();
executable_vec.retain(|_| !*removal_iter.next().unwrap());
removal_iter = removal_flags.iter();
cycle_counts.retain(|_| !*removal_iter.next().unwrap());
removal_flags.retain(|&i| !i);
if executable_vec.is_empty() {
return Ok(OpResult::Ok);
}
let freq = task_freq.unwrap_or_else(|| panic!("No task frequency specified"));
thread::sleep(freq);
})
}