forked from M-Labs/zynq-rs
1
0
Fork 0

cortex_a9::mutex: use AtomU32, remove powersaving behavior

Mutex works properly now.
This commit is contained in:
Astro 2019-11-18 02:37:59 +01:00
parent 4e4ff512d9
commit d89f594ba4
1 changed files with 8 additions and 22 deletions

View File

@ -1,21 +1,13 @@
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicU32, Ordering};
use core::cell::UnsafeCell; use core::cell::UnsafeCell;
use super::asm::*; use super::asm::*;
#[inline] const LOCKED: u32 = 1;
fn wait_for_update() { const UNLOCKED: u32 = 0;
wfe();
}
#[inline]
fn signal_update() {
dsb();
sev();
}
pub struct Mutex<T> { pub struct Mutex<T> {
locked: AtomicBool, locked: AtomicU32,
inner: UnsafeCell<T>, inner: UnsafeCell<T>,
} }
@ -25,27 +17,21 @@ unsafe impl<T: Send> Send for Mutex<T> {}
impl<T> Mutex<T> { impl<T> Mutex<T> {
pub const fn new(inner: T) -> Self { pub const fn new(inner: T) -> Self {
Mutex{ Mutex{
locked: AtomicBool::new(false), locked: AtomicU32::new(UNLOCKED),
inner: UnsafeCell::new(inner), inner: UnsafeCell::new(inner),
} }
} }
pub fn lock(&self) -> MutexGuard<T> { pub fn lock(&self) -> MutexGuard<T> {
while self.locked.compare_and_swap(false, true, Ordering::Acquire) { while self.locked.compare_and_swap(UNLOCKED, LOCKED, Ordering::Acquire) != UNLOCKED {}
while self.locked.load(Ordering::Relaxed) {
wait_for_update();
}
}
dmb(); dmb();
MutexGuard { mutex: self } MutexGuard { mutex: self }
} }
fn unlock(&self) { fn unlock(&self) {
dmb(); dmb();
self.locked.store(false, Ordering::Release); self.locked.store(UNLOCKED, Ordering::Release);
signal_update(); dsb();
} }
} }