1010#![ no_std]
1111#![ no_main]
1212
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 } ;
1515
1616// pull in our start-up code
1717use mps3_an536 as _;
@@ -40,8 +40,22 @@ unsafe impl<const LEN_BYTES: usize> Sync for Stack<LEN_BYTES> {}
4040
4141static CORE1_STACK : Stack < 65536 > = Stack :: new ( ) ;
4242
43+ static CORE1_BOOTED : AtomicBool = AtomicBool :: new ( false ) ;
44+
4345static SHARED_VARIABLE : AtomicU32 = AtomicU32 :: new ( 0 ) ;
4446
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+
4559/// The entry-point to the Rust application.
4660///
4761/// It is called by the start-up code in `cortex-m-rt`.
@@ -62,25 +76,50 @@ pub extern "C" fn kmain() {
6276 }
6377
6478 // 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 ) {
6781 break ;
6882 }
69- if counter == 999 {
83+ if counter == CORE0_WILL_WAIT {
7084 println ! ( "CPU 1 is missing?!" ) ;
7185
7286 semihosting:: process:: exit ( 0 ) ;
7387 }
7488 }
7589
76- for _ in 0 ..1000 {
90+ for _ in 0 ..CAS_LOOPS {
7791 SHARED_VARIABLE . fetch_add ( 1 , Ordering :: Relaxed ) ;
7892 }
7993
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+ }
84123
85124 semihosting:: process:: exit ( 0 ) ;
86125}
@@ -90,10 +129,19 @@ pub extern "C" fn kmain() {
90129/// It is called by the start-up code below, on Core 1.
91130#[ no_mangle]
92131pub 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 {
95135 SHARED_VARIABLE . fetch_add ( 1 , Ordering :: Relaxed ) ;
96136 }
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+
97145 loop {
98146 core:: hint:: spin_loop ( ) ;
99147 }
0 commit comments