components/sched/
cooperative.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 cooperative scheduler.
6//!
7//! This provides one Component, CooperativeComponent.
8//!
9//! Usage
10//! -----
11//! ```rust
12//! let scheduler = components::cooperative::CooperativeComponent::new(&PROCESSES)
13//!     .finalize(components::cooperative_component_static!(NUM_PROCS));
14//! ```
15
16// Author: Hudson Ayers <hayers@stanford.edu>
17
18use core::mem::MaybeUninit;
19use kernel::component::Component;
20use kernel::process::ProcessArray;
21use kernel::scheduler::cooperative::{CoopProcessNode, CooperativeSched};
22
23#[macro_export]
24macro_rules! cooperative_component_static {
25    ($N:expr $(,)?) => {{
26        let coop_sched =
27            kernel::static_buf!(kernel::scheduler::cooperative::CooperativeSched<'static>);
28        let coop_nodes = kernel::static_buf!(
29            [core::mem::MaybeUninit<kernel::scheduler::cooperative::CoopProcessNode<'static>>; $N]
30        );
31
32        (coop_sched, coop_nodes)
33    };};
34}
35
36pub struct CooperativeComponent<const NUM_PROCS: usize> {
37    processes: &'static ProcessArray<NUM_PROCS>,
38}
39
40impl<const NUM_PROCS: usize> CooperativeComponent<NUM_PROCS> {
41    pub fn new(processes: &'static ProcessArray<NUM_PROCS>) -> CooperativeComponent<NUM_PROCS> {
42        CooperativeComponent { processes }
43    }
44}
45
46impl<const NUM_PROCS: usize> Component for CooperativeComponent<NUM_PROCS> {
47    type StaticInput = (
48        &'static mut MaybeUninit<CooperativeSched<'static>>,
49        &'static mut MaybeUninit<[MaybeUninit<CoopProcessNode<'static>>; NUM_PROCS]>,
50    );
51    type Output = &'static mut CooperativeSched<'static>;
52
53    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
54        let scheduler = static_buffer.0.write(CooperativeSched::new());
55
56        let nodes = static_buffer
57            .1
58            .write([const { MaybeUninit::uninit() }; NUM_PROCS]);
59
60        for (i, node) in nodes.iter_mut().enumerate() {
61            let init_node = node.write(CoopProcessNode::new(&self.processes[i]));
62            scheduler.processes.push_head(init_node);
63        }
64        scheduler
65    }
66}