scirs2_linalg/parallel/work_stealing/
queue.rs1use std::collections::VecDeque;
7use std::time::Duration;
8
9use super::core::WorkItem;
10
11#[derive(Debug)]
13pub struct WorkQueue<T: Clone> {
14 pub items: VecDeque<WorkItem<T>>,
16 pub processed_count: usize,
18 pub total_time: Duration,
20 pub avg_time: Duration,
22}
23
24impl<T: Clone> Default for WorkQueue<T> {
25 fn default() -> Self {
26 Self {
27 items: VecDeque::new(),
28 processed_count: 0,
29 total_time: Duration::ZERO,
30 avg_time: Duration::ZERO,
31 }
32 }
33}
34
35impl<T: Clone> WorkQueue<T> {
36 pub fn push_front(&mut self, item: WorkItem<T>) {
38 self.items.push_front(item);
39 }
40
41 #[allow(dead_code)]
43 pub fn push_back(&mut self, item: WorkItem<T>) {
44 self.items.push_back(item);
45 }
46
47 pub fn pop_front(&mut self) -> Option<WorkItem<T>> {
49 self.items.pop_front()
50 }
51
52 pub fn steal_back(&mut self) -> Option<WorkItem<T>> {
54 if self.items.len() > 1 {
55 self.items.pop_back()
56 } else {
57 None
58 }
59 }
60
61 pub fn update_timing(&mut self, executiontime: Duration) {
63 self.processed_count += 1;
64 self.total_time += executiontime;
65 self.avg_time = self.total_time / self.processed_count as u32;
66 }
67
68 pub fn estimated_load(&self) -> Duration {
70 let base_time = if self.avg_time.is_zero() {
71 Duration::from_millis(1) } else {
73 self.avg_time
74 };
75
76 self.items
77 .iter()
78 .map(|item| item.estimated_time.unwrap_or(base_time))
79 .sum()
80 }
81}