components/sched/
round_robin.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component for a round robin scheduler.
6//!
7//! This provides one Component, RoundRobinComponent.
8//!
9//! Usage
10//! -----
11//! ```rust
12//! let scheduler = components::round_robin::RoundRobinComponent::new(&PROCESSES)
13//!     .finalize(components::round_robin_component_static!(NUM_PROCS));
14//! ```
15
16// Author: Hudson Ayers <hayers@stanford.edu>
17// Last modified: 03/31/2020
18
19use core::mem::MaybeUninit;
20use kernel::component::Component;
21use kernel::process::ProcessArray;
22use kernel::scheduler::round_robin::{RoundRobinProcessNode, RoundRobinSched};
23
24#[macro_export]
25macro_rules! round_robin_component_static {
26    ($N:expr $(,)?) => {{
27        let rr_sched =
28            kernel::static_buf!(kernel::scheduler::round_robin::RoundRobinSched<'static>);
29        let rr_nodes = kernel::static_buf!(
30            [core::mem::MaybeUninit<kernel::scheduler::round_robin::RoundRobinProcessNode<'static>>;
31                $N]
32        );
33
34        (rr_sched, rr_nodes)
35    };};
36}
37
38pub struct RoundRobinComponent<const NUM_PROCS: usize> {
39    processes: &'static ProcessArray<NUM_PROCS>,
40}
41
42impl<const NUM_PROCS: usize> RoundRobinComponent<NUM_PROCS> {
43    pub fn new(processes: &'static ProcessArray<NUM_PROCS>) -> RoundRobinComponent<NUM_PROCS> {
44        RoundRobinComponent { processes }
45    }
46}
47
48impl<const NUM_PROCS: usize> Component for RoundRobinComponent<NUM_PROCS> {
49    type StaticInput = (
50        &'static mut MaybeUninit<RoundRobinSched<'static>>,
51        &'static mut MaybeUninit<[MaybeUninit<RoundRobinProcessNode<'static>>; NUM_PROCS]>,
52    );
53    type Output = &'static mut RoundRobinSched<'static>;
54
55    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
56        let scheduler = static_buffer.0.write(RoundRobinSched::new());
57
58        let nodes = static_buffer
59            .1
60            .write([const { MaybeUninit::uninit() }; NUM_PROCS]);
61
62        for (i, node) in nodes.iter_mut().enumerate() {
63            let init_node = node.write(RoundRobinProcessNode::new(&self.processes[i]));
64            scheduler.processes.push_head(init_node);
65        }
66        scheduler
67    }
68}