Merge pull request #137 from lulf/generic-critical-section
Allow signals to be used when building for std
This commit is contained in:
		| @@ -26,3 +26,5 @@ embassy-macros  = { version = "0.1.0", path = "../embassy-macros"} | ||||
| embassy-traits  = { version = "0.1.0", path = "../embassy-traits"} | ||||
| atomic-polyfill  = { version = "0.1.1" } | ||||
|  | ||||
| # Workaround https://github.com/japaric/cast.rs/pull/27 | ||||
| cast = { version = "=0.2.3", default-features = false } | ||||
|   | ||||
							
								
								
									
										30
									
								
								embassy/src/util/critical_section.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								embassy/src/util/critical_section.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| pub use cs::{critical_section, CriticalSection}; | ||||
|  | ||||
| #[cfg(feature = "std")] | ||||
| mod cs { | ||||
|     static INIT: std::sync::Once = std::sync::Once::new(); | ||||
|     static mut BKL: Option<std::sync::Mutex<()>> = None; | ||||
|  | ||||
|     pub type CriticalSection = std::sync::MutexGuard<'static, ()>; | ||||
|     pub fn critical_section<F, R>(f: F) -> R | ||||
|     where | ||||
|         F: FnOnce(&CriticalSection) -> R, | ||||
|     { | ||||
|         INIT.call_once(|| unsafe { | ||||
|             BKL.replace(std::sync::Mutex::new(())); | ||||
|         }); | ||||
|         let guard = unsafe { BKL.as_ref().unwrap().lock().unwrap() }; | ||||
|         f(&guard) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(not(feature = "std"))] | ||||
| mod cs { | ||||
|     pub use cortex_m::interrupt::CriticalSection; | ||||
|     pub fn critical_section<F, R>(f: F) -> R | ||||
|     where | ||||
|         F: FnOnce(&CriticalSection) -> R, | ||||
|     { | ||||
|         cortex_m::interrupt::free(f) | ||||
|     } | ||||
| } | ||||
| @@ -5,6 +5,7 @@ mod mutex; | ||||
| mod on_drop; | ||||
| mod portal; | ||||
| mod signal; | ||||
| mod critical_section; | ||||
|  | ||||
| #[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")] | ||||
| mod waker; | ||||
| @@ -16,6 +17,7 @@ pub use on_drop::*; | ||||
| pub use portal::*; | ||||
| pub use signal::*; | ||||
| pub use waker::*; | ||||
| pub use critical_section::*; | ||||
|  | ||||
| pub trait PeripheralBorrow { | ||||
|     type Target; | ||||
|   | ||||
| @@ -11,6 +11,7 @@ use ptr::NonNull; | ||||
| use crate::executor; | ||||
| use crate::fmt::panic; | ||||
| use crate::interrupt::{Interrupt, InterruptExt}; | ||||
| use crate::util::critical_section::critical_section; | ||||
|  | ||||
| /// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks. | ||||
| /// | ||||
| @@ -37,7 +38,7 @@ impl<T: Send> Signal<T> { | ||||
|  | ||||
|     /// Mark this Signal as completed. | ||||
|     pub fn signal(&self, val: T) { | ||||
|         cortex_m::interrupt::free(|_| unsafe { | ||||
|         critical_section(|_| unsafe { | ||||
|             let state = &mut *self.state.get(); | ||||
|             if let State::Waiting(waker) = mem::replace(state, State::Signaled(val)) { | ||||
|                 waker.wake(); | ||||
| @@ -46,14 +47,14 @@ impl<T: Send> Signal<T> { | ||||
|     } | ||||
|  | ||||
|     pub fn reset(&self) { | ||||
|         cortex_m::interrupt::free(|_| unsafe { | ||||
|         critical_section(|_| unsafe { | ||||
|             let state = &mut *self.state.get(); | ||||
|             *state = State::None | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> { | ||||
|         cortex_m::interrupt::free(|_| unsafe { | ||||
|         critical_section(|_| unsafe { | ||||
|             let state = &mut *self.state.get(); | ||||
|             match state { | ||||
|                 State::None => { | ||||
| @@ -77,7 +78,7 @@ impl<T: Send> Signal<T> { | ||||
|  | ||||
|     /// non-blocking method to check whether this signal has been signaled. | ||||
|     pub fn signaled(&self) -> bool { | ||||
|         cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) | ||||
|         critical_section(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user