From 605c8f73a60cf41a6e2d535c5850933d3154e935 Mon Sep 17 00:00:00 2001 From: mwojcik Date: Tue, 24 May 2022 16:59:01 +0800 Subject: [PATCH] mutex: add async version of lock --- libcortex_a9/src/mutex.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libcortex_a9/src/mutex.rs b/libcortex_a9/src/mutex.rs index de0d705..5253367 100644 --- a/libcortex_a9/src/mutex.rs +++ b/libcortex_a9/src/mutex.rs @@ -1,6 +1,9 @@ use core::ops::{Deref, DerefMut}; use core::sync::atomic::{AtomicU32, Ordering}; use core::cell::UnsafeCell; +use core::task::{Context, Poll}; +use core::pin::Pin; +use core::future::Future; use super::{ spin_lock_yield, notify_spin_lock, asm::{enter_critical, exit_critical} @@ -20,6 +23,23 @@ pub struct Mutex { unsafe impl Sync for Mutex {} unsafe impl Send for Mutex {} +struct Fut<'a, T>(&'a Mutex); + +impl<'a, T> Future for Fut<'a, T> { + type Output = MutexGuard<'a, T>; + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let irq = unsafe { enter_critical() }; + if self.0.locked.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::AcqRel, Ordering::Relaxed).is_err() { + unsafe { exit_critical(irq) }; + cx.waker().wake_by_ref(); + Poll::Pending + } + else { + Poll::Ready(MutexGuard { mutex: self.0, irq }) + } + } +} + impl Mutex { /// Constructor, const-fn pub const fn new(inner: T) -> Self { @@ -42,6 +62,10 @@ impl Mutex { MutexGuard { mutex: self, irq } } + pub async fn async_lock(&self) -> MutexGuard<'_, T> { + Fut(&self).await + } + pub fn try_lock(&self) -> Option> { let irq = unsafe { enter_critical() }; if self.locked.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::AcqRel, Ordering::Relaxed).is_err() {