1use core::mem::MaybeUninit;
13
14use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
15use kernel::component::Component;
16use kernel::hil::time;
17use kernel::process::Process;
18use kernel::scheduler::mlfq::{MLFQProcessNode, MLFQSched};
19
20#[macro_export]
21macro_rules! mlfq_component_static {
22 ($A:ty, $N:expr $(,)?) => {{
23 let alarm = kernel::static_buf!(
24 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
25 );
26 let mlfq_sched = kernel::static_buf!(
27 kernel::scheduler::mlfq::MLFQSched<
28 'static,
29 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
30 >
31 );
32 let mlfq_node = kernel::static_buf!(
33 [core::mem::MaybeUninit<kernel::scheduler::mlfq::MLFQProcessNode<'static>>; $N]
34 );
35
36 (alarm, mlfq_sched, mlfq_node)
37 };};
38}
39
40pub struct MLFQComponent<A: 'static + time::Alarm<'static>, const NUM_PROCS: usize> {
41 alarm_mux: &'static MuxAlarm<'static, A>,
42 processes: &'static [Option<&'static dyn Process>],
43}
44
45impl<A: 'static + time::Alarm<'static>, const NUM_PROCS: usize> MLFQComponent<A, NUM_PROCS> {
46 pub fn new(
47 alarm_mux: &'static MuxAlarm<'static, A>,
48 processes: &'static [Option<&'static dyn Process>],
49 ) -> MLFQComponent<A, NUM_PROCS> {
50 MLFQComponent {
51 alarm_mux,
52 processes,
53 }
54 }
55}
56
57impl<A: 'static + time::Alarm<'static>, const NUM_PROCS: usize> Component
58 for MLFQComponent<A, NUM_PROCS>
59{
60 type StaticInput = (
61 &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
62 &'static mut MaybeUninit<MLFQSched<'static, VirtualMuxAlarm<'static, A>>>,
63 &'static mut MaybeUninit<[MaybeUninit<MLFQProcessNode<'static>>; NUM_PROCS]>,
64 );
65 type Output = &'static mut MLFQSched<'static, VirtualMuxAlarm<'static, A>>;
66
67 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
68 let scheduler_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux));
69 scheduler_alarm.setup();
70
71 let scheduler = static_buffer.1.write(MLFQSched::new(scheduler_alarm));
72
73 const UNINIT: MaybeUninit<MLFQProcessNode<'static>> = MaybeUninit::uninit();
74 let nodes = static_buffer.2.write([UNINIT; NUM_PROCS]);
75
76 for (i, node) in nodes.iter_mut().enumerate() {
77 let init_node = node.write(MLFQProcessNode::new(&self.processes[i]));
78 scheduler.processes[0].push_head(init_node);
79 }
80 scheduler
81 }
82}