minimult_cortex_m/
msgqueue.rs1use core::marker::PhantomData;
2
3use crate::minimult::Minimult;
4use crate::memory::MTRawArray;
5use crate::kernel::{MTEvent, MTEventCond};
6use crate::bkptpanic::BKUnwrap;
7
8fn wrap_inc(x: usize, bound: usize) -> usize
11{
12 let y = x + 1;
13 if y < bound {y} else {0}
14}
15
16pub struct MTMsgQueue<'a, M>
20{
21 mem: MTRawArray<M>,
22 wr_idx: usize,
23 rd_idx: usize,
24 msg_cnt: MTEvent,
25 phantom: PhantomData<&'a ()>
26}
27
28impl<'a, M> MTMsgQueue<'a, M>
29{
30 pub(crate) fn new(mem: MTRawArray<M>) -> MTMsgQueue<'a, M> {
32 MTMsgQueue {
33 mem,
34 wr_idx: 0,
35 rd_idx: 0,
36 msg_cnt: MTEvent::new(0),
37 phantom: PhantomData
38 }
39 }
40
41 pub fn ch<'q>(&'q mut self) -> (MTMsgSender<'a, 'q, M>, MTMsgReceiver<'a, 'q, M>)
44 {
45 (
46 MTMsgSender {
47 q: self,
48 phantom: PhantomData
49 },
50 MTMsgReceiver {
51 q: self,
52 phantom: PhantomData
53 }
54 )
55 }
56}
57
58pub struct MTMsgSender<'a, 'q, M>
62{
63 q: *mut MTMsgQueue<'a, M>,
64 phantom: PhantomData<&'q ()>
65}
66
67unsafe impl<M: Send> Send for MTMsgSender<'_, '_, M> {}
68
69impl<M> MTMsgSender<'_, '_, M>
70{
71 pub fn vacant(&self) -> usize
74 {
75 let q = unsafe { self.q.as_mut().bk_unwrap() };
76
77 q.mem.len() - q.msg_cnt.cnt()
78 }
79
80 pub fn send(&mut self, msg: M)
84 {
85 let q = unsafe { self.q.as_mut().bk_unwrap() };
86
87 loop {
88 if q.msg_cnt.cnt() < q.mem.len() {
89 break;
90 }
91
92 Minimult::wait(&q.msg_cnt, MTEventCond::LessThan(q.mem.len()));
93 }
94
95 let curr_wr_idx = q.wr_idx;
96 let next_wr_idx = wrap_inc(curr_wr_idx, q.mem.len());
97
98 q.mem.write_volatile(curr_wr_idx, msg);
99
100 q.wr_idx = next_wr_idx; q.msg_cnt.incr();
103 Minimult::signal(&q.msg_cnt);
104 }
105}
106
107pub struct MTMsgReceiver<'a, 'q, M>
111{
112 q: *mut MTMsgQueue<'a, M>,
113 phantom: PhantomData<&'q ()>
114}
115
116unsafe impl<M: Send> Send for MTMsgReceiver<'_, '_, M> {}
117
118impl<M> MTMsgReceiver<'_, '_, M>
119{
120 pub fn available(&self) -> usize
123 {
124 let q = unsafe { self.q.as_mut().bk_unwrap() };
125
126 q.msg_cnt.cnt()
127 }
128
129 pub fn receive(&mut self) -> M
133 {
134 let q = unsafe { self.q.as_mut().bk_unwrap() };
135
136 loop {
137 if q.msg_cnt.cnt() > 0 {
138 break;
139 }
140
141 Minimult::wait(&q.msg_cnt, MTEventCond::GreaterThan(0));
142 }
143
144 let curr_rd_idx = q.rd_idx;
145 let next_rd_idx = wrap_inc(curr_rd_idx, q.mem.len());
146
147 let msg = q.mem.read_volatile(curr_rd_idx);
148
149 q.rd_idx = next_rd_idx; q.msg_cnt.decr();
152 Minimult::signal(&q.msg_cnt);
153
154 msg
155 }
156}