1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use core::marker::PhantomData;
use crate::minimult::Minimult;
use crate::kernel::{MTEvent, MTEventCond};
pub struct MTShared<'a, M>
{
holder: M,
rw_cnt: MTEvent,
phantom: PhantomData<&'a ()>
}
impl<'a, M> MTShared<'a, M>
{
pub(crate) fn new(holder: M) -> MTShared<'a, M>
{
MTShared {
holder,
rw_cnt: MTEvent::new(1),
phantom: PhantomData
}
}
pub fn ch<'s>(&'s self) -> MTSharedCh<'a, 's, M>
{
MTSharedCh {
s: (self as *const Self) as *mut Self,
phantom: PhantomData
}
}
}
pub struct MTSharedCh<'a, 's, M>
{
s: *mut MTShared<'a, M>,
phantom: PhantomData<&'s ()>
}
unsafe impl<M: Send> Send for MTSharedCh<'_, '_, M> {}
impl<M> MTSharedCh<'_, '_, M>
{
pub fn look<F>(&self, f: F)
where F: FnOnce(&M)
{
let s = unsafe { self.s.as_mut().unwrap() };
loop {
if s.rw_cnt.incr_ifgt0() {
break;
}
Minimult::wait(&s.rw_cnt, MTEventCond::GreaterThan(0));
}
f(&s.holder);
s.rw_cnt.decr();
Minimult::signal(&s.rw_cnt);
}
pub fn touch<F>(&self, f: F)
where F: FnOnce(&mut M)
{
let s = unsafe { self.s.as_mut().unwrap() };
loop {
if s.rw_cnt.decr_if1() {
break;
}
Minimult::wait(&s.rw_cnt, MTEventCond::Equal(1));
}
f(&mut s.holder);
s.rw_cnt.incr();
Minimult::signal(&s.rw_cnt);
}
}