1
1
#![ no_std]
2
2
#![ no_main]
3
- #![ feature( core_intrinsics) ]
4
3
5
4
#[ macro_use]
6
5
extern crate user_lib;
7
6
extern crate alloc;
8
7
extern crate core;
9
8
10
9
use alloc:: vec:: Vec ;
11
- use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
10
+ use core:: {
11
+ ptr:: { addr_of, addr_of_mut, read_volatile, write_volatile} ,
12
+ sync:: atomic:: { AtomicUsize , Ordering } ,
13
+ } ;
12
14
use user_lib:: { exit, sleep, thread_create, waittid} ;
13
15
14
16
const N : usize = 2 ;
@@ -38,19 +40,19 @@ fn critical_test_exit() {
38
40
assert_eq ! ( GUARD . fetch_sub( 1 , Ordering :: SeqCst ) , 1 ) ;
39
41
}
40
42
41
- fn eisenberg_enter_critical ( id : usize ) {
43
+ unsafe fn eisenberg_enter_critical ( id : usize ) {
42
44
/* announce that we want to enter */
43
45
loop {
44
46
println ! ( "Thread[{}] try enter" , id) ;
45
- vstore ! ( & FLAG [ id] , FlagState :: Want ) ;
47
+ write_volatile ( addr_of_mut ! ( FLAG [ id] ) , FlagState :: Want ) ;
46
48
loop {
47
49
/* check if any with higher priority is `Want` or `In` */
48
50
let mut prior_thread: Option < usize > = None ;
49
- let turn = vload ! ( & TURN ) ;
51
+ let turn = read_volatile ( addr_of ! ( TURN ) ) ;
50
52
let ring_id = if id < turn { id + THREAD_NUM } else { id } ;
51
53
// FLAG.iter() may lead to some errors, use for-loop instead
52
54
for i in turn..ring_id {
53
- if vload ! ( & FLAG [ i % THREAD_NUM ] ) != FlagState :: Out {
55
+ if read_volatile ( addr_of ! ( FLAG [ i % THREAD_NUM ] ) ) != FlagState :: Out {
54
56
prior_thread = Some ( i % THREAD_NUM ) ;
55
57
break ;
56
58
}
@@ -66,13 +68,13 @@ fn eisenberg_enter_critical(id: usize) {
66
68
sleep ( 1 ) ;
67
69
}
68
70
/* now tentatively claim the resource */
69
- vstore ! ( & FLAG [ id] , FlagState :: In ) ;
71
+ write_volatile ( addr_of_mut ! ( FLAG [ id] ) , FlagState :: In ) ;
70
72
/* enforce the order of `claim` and `conflict check`*/
71
73
memory_fence ! ( ) ;
72
74
/* check if anthor thread is also `In`, which imply a conflict*/
73
75
let mut conflict = false ;
74
76
for i in 0 ..THREAD_NUM {
75
- if i != id && vload ! ( & FLAG [ i] ) == FlagState :: In {
77
+ if i != id && read_volatile ( addr_of ! ( FLAG [ i] ) ) == FlagState :: In {
76
78
conflict = true ;
77
79
}
78
80
}
@@ -83,28 +85,28 @@ fn eisenberg_enter_critical(id: usize) {
83
85
/* no need to sleep */
84
86
}
85
87
/* clain the trun */
86
- vstore ! ( & TURN , id) ;
88
+ write_volatile ( addr_of_mut ! ( TURN ) , id) ;
87
89
println ! ( "Thread[{}] enter" , id) ;
88
90
}
89
91
90
- fn eisenberg_exit_critical ( id : usize ) {
92
+ unsafe fn eisenberg_exit_critical ( id : usize ) {
91
93
/* find next one who wants to enter and give the turn to it*/
92
94
let mut next = id;
93
95
let ring_id = id + THREAD_NUM ;
94
96
for i in ( id + 1 ) ..ring_id {
95
97
let idx = i % THREAD_NUM ;
96
- if vload ! ( & FLAG [ idx] ) == FlagState :: Want {
98
+ if read_volatile ( addr_of ! ( FLAG [ idx] ) ) == FlagState :: Want {
97
99
next = idx;
98
100
break ;
99
101
}
100
102
}
101
- vstore ! ( & TURN , next) ;
103
+ write_volatile ( addr_of_mut ! ( TURN ) , next) ;
102
104
/* All done */
103
- vstore ! ( & FLAG [ id] , FlagState :: Out ) ;
105
+ write_volatile ( addr_of_mut ! ( FLAG [ id] ) , FlagState :: Out ) ;
104
106
println ! ( "Thread[{}] exit, give turn to {}" , id, next) ;
105
107
}
106
108
107
- pub fn thread_fn ( id : usize ) -> ! {
109
+ pub unsafe fn thread_fn ( id : usize ) -> ! {
108
110
println ! ( "Thread[{}] init." , id) ;
109
111
for _ in 0 ..N {
110
112
eisenberg_enter_critical ( id) ;
0 commit comments