Skip to main content

luaur_analyze_cli/records/
task_scheduler.rs

1use alloc::boxed::Box;
2use alloc::collections::VecDeque;
3use alloc::sync::Arc;
4use alloc::vec::Vec;
5use std::sync::{Condvar, Mutex};
6
7/// A `std::function<void()>` task. `None` models an empty `std::function` — the
8/// falsy sentinel the C++ pushes (`push({})`) to terminate a worker's loop.
9pub type Task = Option<Box<dyn FnOnce() + Send + 'static>>;
10
11/// Port of `struct TaskScheduler` (`CLI/src/Analyze.cpp:323-392`).
12///
13/// A thread pool scheduler for parallel task execution, mirroring the C++ design:
14/// `std::mutex` + `std::condition_variable` guarding a `std::queue<std::function<void()>>`,
15/// with one `std::thread` per worker. Native-only; not portable to wasm32-unknown-unknown.
16#[allow(non_camel_case_types)]
17#[derive(Debug)]
18pub struct TaskScheduler {
19    pub(crate) thread_count: u32,
20    pub(crate) workers: Vec<std::thread::JoinHandle<()>>,
21    pub(crate) tasks: Arc<TaskQueue>,
22}
23
24/// The shared `mtx` / `cv` / `tasks` triple from the C++ `TaskScheduler`.
25pub struct TaskQueue {
26    pub(crate) mtx: Mutex<VecDeque<Task>>,
27    pub(crate) cv: Condvar,
28}
29
30impl core::fmt::Debug for TaskQueue {
31    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32        f.debug_struct("TaskQueue").finish_non_exhaustive()
33    }
34}
35
36impl TaskQueue {
37    pub(crate) fn new() -> Self {
38        Self {
39            mtx: Mutex::new(VecDeque::new()),
40            cv: Condvar::new(),
41        }
42    }
43}
44
45impl TaskScheduler {
46    /// `static unsigned getThreadCount()` (`CLI/src/Analyze.cpp:375-378`):
47    /// `return std::max(std::thread::hardware_concurrency(), 1u);`
48    pub fn get_thread_count() -> u32 {
49        core::cmp::max(
50            std::thread::available_parallelism()
51                .map(|n| n.get() as u32)
52                .unwrap_or(1),
53            1,
54        )
55    }
56}
57
58impl Drop for TaskScheduler {
59    /// `~TaskScheduler()` (`CLI/src/Analyze.cpp:339-346`):
60    /// pushes one empty task per worker, then joins them.
61    fn drop(&mut self) {
62        crate::methods::task_scheduler_task_scheduler_analyze_alt_b::task_scheduler_destructor(
63            self,
64        );
65    }
66}