10
10
#![ no_std]
11
11
#![ no_main]
12
12
13
- use core:: cell:: UnsafeCell ;
14
- use core:: sync:: atomic:: { AtomicU32 , Ordering } ;
13
+ use core:: cell:: { RefCell , UnsafeCell } ;
14
+ use core:: sync:: atomic:: { AtomicBool , AtomicU32 , Ordering } ;
15
15
16
16
// pull in our start-up code
17
17
use mps3_an536 as _;
@@ -40,8 +40,22 @@ unsafe impl<const LEN_BYTES: usize> Sync for Stack<LEN_BYTES> {}
40
40
41
41
static CORE1_STACK : Stack < 65536 > = Stack :: new ( ) ;
42
42
43
+ static CORE1_BOOTED : AtomicBool = AtomicBool :: new ( false ) ;
44
+
43
45
static SHARED_VARIABLE : AtomicU32 = AtomicU32 :: new ( 0 ) ;
44
46
47
+ static SHARED_VARIABLE_2 : critical_section:: Mutex < RefCell < u32 > > =
48
+ critical_section:: Mutex :: new ( RefCell :: new ( 0 ) ) ;
49
+
50
+ /// How long core 0 waits for core 1
51
+ const CORE0_WILL_WAIT : usize = 1_000_000 ;
52
+
53
+ /// How many CAS loops to run?
54
+ const CAS_LOOPS : u32 = 1000 ;
55
+
56
+ /// How many CS Mutex loops to run?
57
+ const CS_MUTEX_LOOPS : u32 = 1000 ;
58
+
45
59
/// The entry-point to the Rust application.
46
60
///
47
61
/// It is called by the start-up code in `cortex-m-rt`.
@@ -62,25 +76,50 @@ pub extern "C" fn kmain() {
62
76
}
63
77
64
78
// wait some time for core 1 to start
65
- for counter in 0 ..1000 {
66
- if SHARED_VARIABLE . load ( Ordering :: SeqCst ) != 0 {
79
+ for counter in 0 ..= CORE0_WILL_WAIT {
80
+ if CORE1_BOOTED . load ( Ordering :: SeqCst ) {
67
81
break ;
68
82
}
69
- if counter == 999 {
83
+ if counter == CORE0_WILL_WAIT {
70
84
println ! ( "CPU 1 is missing?!" ) ;
71
85
72
86
semihosting:: process:: exit ( 0 ) ;
73
87
}
74
88
}
75
89
76
- for _ in 0 ..1000 {
90
+ for _ in 0 ..CAS_LOOPS {
77
91
SHARED_VARIABLE . fetch_add ( 1 , Ordering :: Relaxed ) ;
78
92
}
79
93
80
- println ! (
81
- "Total is {} (is it 2001?)" ,
82
- SHARED_VARIABLE . load( Ordering :: Relaxed )
83
- ) ;
94
+ for _ in 0 ..CS_MUTEX_LOOPS {
95
+ critical_section:: with ( |cs| {
96
+ let mut value_ref = SHARED_VARIABLE_2 . borrow_ref_mut ( cs) ;
97
+ * value_ref += 1 ;
98
+ } )
99
+ }
100
+
101
+ // let the other core finish
102
+ for _ in 0 ..CORE0_WILL_WAIT {
103
+ cortex_ar:: asm:: nop ( ) ;
104
+ }
105
+
106
+ let total_a = SHARED_VARIABLE . load ( Ordering :: Relaxed ) ;
107
+ if total_a == CAS_LOOPS * 2 {
108
+ println ! ( "CAS test passed" ) ;
109
+ } else {
110
+ println ! ( "CAS test failed, got {} not 2000" , total_a) ;
111
+ }
112
+
113
+ let total_b = critical_section:: with ( |cs| {
114
+ let value_ref = SHARED_VARIABLE_2 . borrow_ref ( cs) ;
115
+ * value_ref
116
+ } ) ;
117
+
118
+ if total_b == CS_MUTEX_LOOPS * 2 {
119
+ println ! ( "CS Mutex test passed" ) ;
120
+ } else {
121
+ println ! ( "CS Mutex test failed, got {} not 2000" , total_b) ;
122
+ }
84
123
85
124
semihosting:: process:: exit ( 0 ) ;
86
125
}
@@ -90,10 +129,19 @@ pub extern "C" fn kmain() {
90
129
/// It is called by the start-up code below, on Core 1.
91
130
#[ no_mangle]
92
131
pub extern "C" fn kmain2 ( ) {
93
- SHARED_VARIABLE . store ( 1 , Ordering :: SeqCst ) ;
94
- for _ in 0 ..1000 {
132
+ CORE1_BOOTED . store ( true , Ordering :: SeqCst ) ;
133
+
134
+ for _ in 0 ..CAS_LOOPS {
95
135
SHARED_VARIABLE . fetch_add ( 1 , Ordering :: Relaxed ) ;
96
136
}
137
+
138
+ for _ in 0 ..CS_MUTEX_LOOPS {
139
+ critical_section:: with ( |cs| {
140
+ let mut value_ref = SHARED_VARIABLE_2 . borrow_ref_mut ( cs) ;
141
+ * value_ref += 1 ;
142
+ } )
143
+ }
144
+
97
145
loop {
98
146
core:: hint:: spin_loop ( ) ;
99
147
}
0 commit comments