minimult_cortex_m/
shared.rs1use core::marker::PhantomData;
2
3use crate::minimult::Minimult;
4use crate::kernel::{MTEvent, MTEventCond};
5use crate::bkptpanic::BKUnwrap;
6
7pub struct MTShared<'a, M>
9{
10 holder: M,
11 rw_cnt: MTEvent,
12 phantom: PhantomData<&'a ()>
13}
14
15impl<'a, M> MTShared<'a, M>
16{
17 pub(crate) fn new(holder: M) -> MTShared<'a, M> {
19 MTShared {
20 holder,
21 rw_cnt: MTEvent::new(1),
22 phantom: PhantomData
23 }
24 }
25
26 pub fn ch<'s>(&'s self) -> MTSharedCh<'a, 's, M>
29 {
30 MTSharedCh {
31 s: (self as *const Self) as *mut Self, phantom: PhantomData
33 }
34 }
35}
36
37pub struct MTSharedCh<'a, 's, M>
41{
42 s: *mut MTShared<'a, M>,
43 phantom: PhantomData<&'s ()>
44}
45
46unsafe impl<M: Send> Send for MTSharedCh<'_, '_, M> {}
47
48impl<M> MTSharedCh<'_, '_, M>
49{
50 pub fn look<'c>(&'c self) -> MTSharedLook<'c, M>
54 {
55 loop {
56 if let Some(v) = self.try_look() {
57 return v;
58 }
59 else {
60 let s = unsafe { self.s.as_mut().bk_unwrap() };
61 Minimult::wait(&s.rw_cnt, MTEventCond::GreaterThan(0));
62 }
63 }
64 }
65
66 pub fn try_look<'c>(&'c self) -> Option<MTSharedLook<'c, M>>
70 {
71 let s = unsafe { self.s.as_mut().bk_unwrap() };
72
73 if s.rw_cnt.incr_ifgt0() {
74 Some(MTSharedLook {
75 holder: &s.holder,
76 rw_cnt: &mut s.rw_cnt
77 })
78 }
79 else {
80 None
81 }
82 }
83
84 pub fn touch<'c>(&'c self) -> MTSharedTouch<'c, M>
88 {
89 loop {
90 if let Some(v) = self.try_touch() {
91 return v;
92 }
93 else {
94 let s = unsafe { self.s.as_mut().bk_unwrap() };
95 Minimult::wait(&s.rw_cnt, MTEventCond::Equal(1));
96 }
97 }
98 }
99
100 pub fn try_touch<'c>(&'c self) -> Option<MTSharedTouch<'c, M>>
104 {
105 let s = unsafe { self.s.as_mut().bk_unwrap() };
106
107 if s.rw_cnt.decr_if1() {
108 Some(MTSharedTouch {
109 holder: &mut s.holder,
110 rw_cnt: &mut s.rw_cnt
111 })
112 }
113 else {
114 None
115 }
116 }
117}
118
119pub struct MTSharedLook<'c, M>
123{
124 holder: &'c M,
125 rw_cnt: &'c mut MTEvent,
126}
127
128impl<M> core::ops::Deref for MTSharedLook<'_, M>
129{
130 type Target = M;
131
132 fn deref(&self) -> &Self::Target
133 {
134 self.holder
135 }
136}
137
138impl<M> Drop for MTSharedLook<'_, M>
139{
140 fn drop(&mut self)
141 {
142 self.rw_cnt.decr();
143 Minimult::signal(&self.rw_cnt);
144 }
145}
146
147pub struct MTSharedTouch<'c, M>
151{
152 holder: &'c mut M,
153 rw_cnt: &'c mut MTEvent,
154}
155
156impl<M> core::ops::Deref for MTSharedTouch<'_, M>
157{
158 type Target = M;
159
160 fn deref(&self) -> &Self::Target
161 {
162 self.holder
163 }
164}
165
166impl<M> core::ops::DerefMut for MTSharedTouch<'_, M>
167{
168 fn deref_mut(&mut self) -> &mut Self::Target
169 {
170 self.holder
171 }
172}
173
174impl<M> Drop for MTSharedTouch<'_, M>
175{
176 fn drop(&mut self)
177 {
178 self.rw_cnt.incr();
179 Minimult::signal(&self.rw_cnt);
180 }
181}