diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-03-27 01:43:38 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-03-29 00:58:58 +0200 |
| commit | 4ce46df1603697b14f2446b33663a122dda4a468 (patch) | |
| tree | 6fa5baf46d53f25aed4b7b810a9f82d0cf924088 | |
| parent | 7a41541ab279e200b7bda93704e8ba66df52f5b4 (diff) | |
Code size optimizations.
| -rw-r--r-- | embassy-extras/src/peripheral.rs | 8 | ||||
| -rw-r--r-- | embassy-extras/src/peripheral_shared.rs | 5 | ||||
| -rw-r--r-- | embassy-macros/src/lib.rs | 10 | ||||
| -rw-r--r-- | embassy/src/executor/raw.rs | 6 | ||||
| -rw-r--r-- | embassy/src/interrupt.rs | 14 | ||||
| -rw-r--r-- | embassy/src/util/forever.rs | 23 |
6 files changed, 41 insertions, 25 deletions
diff --git a/embassy-extras/src/peripheral.rs b/embassy-extras/src/peripheral.rs index e2435d63f..68972c543 100644 --- a/embassy-extras/src/peripheral.rs +++ b/embassy-extras/src/peripheral.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | use core::cell::UnsafeCell; | 1 | use core::cell::UnsafeCell; |
| 2 | use core::marker::{PhantomData, PhantomPinned}; | 2 | use core::marker::{PhantomData, PhantomPinned}; |
| 3 | use core::pin::Pin; | 3 | use core::pin::Pin; |
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | ||
| 5 | 4 | ||
| 6 | use embassy::interrupt::{Interrupt, InterruptExt}; | 5 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 7 | 6 | ||
| @@ -39,8 +38,6 @@ impl<S: PeripheralState> PeripheralMutex<S> { | |||
| 39 | } | 38 | } |
| 40 | 39 | ||
| 41 | this.irq.disable(); | 40 | this.irq.disable(); |
| 42 | compiler_fence(Ordering::SeqCst); | ||
| 43 | |||
| 44 | this.irq.set_handler(|p| { | 41 | this.irq.set_handler(|p| { |
| 45 | // Safety: it's OK to get a &mut to the state, since | 42 | // Safety: it's OK to get a &mut to the state, since |
| 46 | // - We're in the IRQ, no one else can't preempt us | 43 | // - We're in the IRQ, no one else can't preempt us |
| @@ -50,8 +47,6 @@ impl<S: PeripheralState> PeripheralMutex<S> { | |||
| 50 | }); | 47 | }); |
| 51 | this.irq | 48 | this.irq |
| 52 | .set_handler_context((&mut this.state) as *mut _ as *mut ()); | 49 | .set_handler_context((&mut this.state) as *mut _ as *mut ()); |
| 53 | |||
| 54 | compiler_fence(Ordering::SeqCst); | ||
| 55 | this.irq.enable(); | 50 | this.irq.enable(); |
| 56 | 51 | ||
| 57 | this.irq_setup_done = true; | 52 | this.irq_setup_done = true; |
| @@ -61,14 +56,11 @@ impl<S: PeripheralState> PeripheralMutex<S> { | |||
| 61 | let this = unsafe { self.get_unchecked_mut() }; | 56 | let this = unsafe { self.get_unchecked_mut() }; |
| 62 | 57 | ||
| 63 | this.irq.disable(); | 58 | this.irq.disable(); |
| 64 | compiler_fence(Ordering::SeqCst); | ||
| 65 | 59 | ||
| 66 | // Safety: it's OK to get a &mut to the state, since the irq is disabled. | 60 | // Safety: it's OK to get a &mut to the state, since the irq is disabled. |
| 67 | let state = unsafe { &mut *this.state.get() }; | 61 | let state = unsafe { &mut *this.state.get() }; |
| 68 | |||
| 69 | let r = f(state, &mut this.irq); | 62 | let r = f(state, &mut this.irq); |
| 70 | 63 | ||
| 71 | compiler_fence(Ordering::SeqCst); | ||
| 72 | this.irq.enable(); | 64 | this.irq.enable(); |
| 73 | 65 | ||
| 74 | r | 66 | r |
diff --git a/embassy-extras/src/peripheral_shared.rs b/embassy-extras/src/peripheral_shared.rs index 73906698e..c62113396 100644 --- a/embassy-extras/src/peripheral_shared.rs +++ b/embassy-extras/src/peripheral_shared.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | use core::cell::UnsafeCell; | 1 | use core::cell::UnsafeCell; |
| 2 | use core::marker::{PhantomData, PhantomPinned}; | 2 | use core::marker::{PhantomData, PhantomPinned}; |
| 3 | use core::pin::Pin; | 3 | use core::pin::Pin; |
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | ||
| 5 | 4 | ||
| 6 | use embassy::interrupt::{Interrupt, InterruptExt}; | 5 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 7 | 6 | ||
| @@ -39,16 +38,12 @@ impl<S: PeripheralState> Peripheral<S> { | |||
| 39 | } | 38 | } |
| 40 | 39 | ||
| 41 | this.irq.disable(); | 40 | this.irq.disable(); |
| 42 | compiler_fence(Ordering::SeqCst); | ||
| 43 | |||
| 44 | this.irq.set_handler(|p| { | 41 | this.irq.set_handler(|p| { |
| 45 | let state = unsafe { &*(p as *const S) }; | 42 | let state = unsafe { &*(p as *const S) }; |
| 46 | state.on_interrupt(); | 43 | state.on_interrupt(); |
| 47 | }); | 44 | }); |
| 48 | this.irq | 45 | this.irq |
| 49 | .set_handler_context((&this.state) as *const _ as *mut ()); | 46 | .set_handler_context((&this.state) as *const _ as *mut ()); |
| 50 | |||
| 51 | compiler_fence(Ordering::SeqCst); | ||
| 52 | this.irq.enable(); | 47 | this.irq.enable(); |
| 53 | 48 | ||
| 54 | this.irq_setup_done = true; | 49 | this.irq_setup_done = true; |
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs index bcf9dd4ed..a14c374fa 100644 --- a/embassy-macros/src/lib.rs +++ b/embassy-macros/src/lib.rs | |||
| @@ -172,12 +172,10 @@ pub fn interrupt_take(item: TokenStream) -> TokenStream { | |||
| 172 | static HANDLER: ::embassy::interrupt::Handler; | 172 | static HANDLER: ::embassy::interrupt::Handler; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | let func = HANDLER.func.load(::embassy::export::atomic::Ordering::Acquire); | 175 | let func = HANDLER.func.load(::embassy::export::atomic::Ordering::Relaxed); |
| 176 | let ctx = HANDLER.ctx.load(::embassy::export::atomic::Ordering::Acquire); | 176 | let ctx = HANDLER.ctx.load(::embassy::export::atomic::Ordering::Relaxed); |
| 177 | if !func.is_null() { | 177 | let func: fn(*mut ()) = ::core::mem::transmute(func); |
| 178 | let func: fn(*mut ()) = ::core::mem::transmute(func); | 178 | func(ctx) |
| 179 | func(ctx) | ||
| 180 | } | ||
| 181 | } | 179 | } |
| 182 | 180 | ||
| 183 | static TAKEN: ::embassy::export::atomic::AtomicBool = ::embassy::export::atomic::AtomicBool::new(false); | 181 | static TAKEN: ::embassy::export::atomic::AtomicBool = ::embassy::export::atomic::AtomicBool::new(false); |
diff --git a/embassy/src/executor/raw.rs b/embassy/src/executor/raw.rs index 7e981b084..52512c533 100644 --- a/embassy/src/executor/raw.rs +++ b/embassy/src/executor/raw.rs | |||
| @@ -4,9 +4,9 @@ use core::cmp::min; | |||
| 4 | use core::future::Future; | 4 | use core::future::Future; |
| 5 | use core::marker::PhantomData; | 5 | use core::marker::PhantomData; |
| 6 | use core::pin::Pin; | 6 | use core::pin::Pin; |
| 7 | use core::ptr; | ||
| 8 | use core::ptr::NonNull; | 7 | use core::ptr::NonNull; |
| 9 | use core::task::{Context, Poll, Waker}; | 8 | use core::task::{Context, Poll, Waker}; |
| 9 | use core::{mem, ptr}; | ||
| 10 | 10 | ||
| 11 | use super::run_queue::{RunQueue, RunQueueItem}; | 11 | use super::run_queue::{RunQueue, RunQueueItem}; |
| 12 | use super::timer_queue::{TimerQueue, TimerQueueItem}; | 12 | use super::timer_queue::{TimerQueue, TimerQueueItem}; |
| @@ -143,6 +143,10 @@ impl<F: Future + 'static> Task<F> { | |||
| 143 | } | 143 | } |
| 144 | Poll::Pending => {} | 144 | Poll::Pending => {} |
| 145 | } | 145 | } |
| 146 | |||
| 147 | // the compiler is emitting a virtual call for waker drop, but we know | ||
| 148 | // it's a noop for our waker. | ||
| 149 | mem::forget(waker); | ||
| 146 | } | 150 | } |
| 147 | } | 151 | } |
| 148 | 152 | ||
diff --git a/embassy/src/interrupt.rs b/embassy/src/interrupt.rs index a4285a9fe..99d7af753 100644 --- a/embassy/src/interrupt.rs +++ b/embassy/src/interrupt.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::ptr; | 1 | use core::ptr; |
| 2 | use cortex_m::peripheral::NVIC; | 2 | use cortex_m::peripheral::NVIC; |
| 3 | 3 | ||
| 4 | use atomic_polyfill::{AtomicPtr, Ordering}; | 4 | use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering}; |
| 5 | 5 | ||
| 6 | pub use embassy_macros::interrupt_declare as declare; | 6 | pub use embassy_macros::interrupt_declare as declare; |
| 7 | pub use embassy_macros::interrupt_take as take; | 7 | pub use embassy_macros::interrupt_take as take; |
| @@ -58,22 +58,27 @@ pub trait InterruptExt: Interrupt { | |||
| 58 | 58 | ||
| 59 | impl<T: Interrupt + ?Sized> InterruptExt for T { | 59 | impl<T: Interrupt + ?Sized> InterruptExt for T { |
| 60 | fn set_handler(&self, func: unsafe fn(*mut ())) { | 60 | fn set_handler(&self, func: unsafe fn(*mut ())) { |
| 61 | compiler_fence(Ordering::SeqCst); | ||
| 61 | let handler = unsafe { self.__handler() }; | 62 | let handler = unsafe { self.__handler() }; |
| 62 | handler.func.store(func as *mut (), Ordering::Release); | 63 | handler.func.store(func as *mut (), Ordering::Relaxed); |
| 64 | compiler_fence(Ordering::SeqCst); | ||
| 63 | } | 65 | } |
| 64 | 66 | ||
| 65 | fn remove_handler(&self) { | 67 | fn remove_handler(&self) { |
| 68 | compiler_fence(Ordering::SeqCst); | ||
| 66 | let handler = unsafe { self.__handler() }; | 69 | let handler = unsafe { self.__handler() }; |
| 67 | handler.func.store(ptr::null_mut(), Ordering::Release); | 70 | handler.func.store(ptr::null_mut(), Ordering::Relaxed); |
| 71 | compiler_fence(Ordering::SeqCst); | ||
| 68 | } | 72 | } |
| 69 | 73 | ||
| 70 | fn set_handler_context(&self, ctx: *mut ()) { | 74 | fn set_handler_context(&self, ctx: *mut ()) { |
| 71 | let handler = unsafe { self.__handler() }; | 75 | let handler = unsafe { self.__handler() }; |
| 72 | handler.ctx.store(ctx, Ordering::Release); | 76 | handler.ctx.store(ctx, Ordering::Relaxed); |
| 73 | } | 77 | } |
| 74 | 78 | ||
| 75 | #[inline] | 79 | #[inline] |
| 76 | fn enable(&self) { | 80 | fn enable(&self) { |
| 81 | compiler_fence(Ordering::SeqCst); | ||
| 77 | unsafe { | 82 | unsafe { |
| 78 | NVIC::unmask(NrWrap(self.number())); | 83 | NVIC::unmask(NrWrap(self.number())); |
| 79 | } | 84 | } |
| @@ -82,6 +87,7 @@ impl<T: Interrupt + ?Sized> InterruptExt for T { | |||
| 82 | #[inline] | 87 | #[inline] |
| 83 | fn disable(&self) { | 88 | fn disable(&self) { |
| 84 | NVIC::mask(NrWrap(self.number())); | 89 | NVIC::mask(NrWrap(self.number())); |
| 90 | compiler_fence(Ordering::SeqCst); | ||
| 85 | } | 91 | } |
| 86 | 92 | ||
| 87 | #[inline] | 93 | #[inline] |
diff --git a/embassy/src/util/forever.rs b/embassy/src/util/forever.rs index efa96f30e..0432fa51e 100644 --- a/embassy/src/util/forever.rs +++ b/embassy/src/util/forever.rs | |||
| @@ -31,6 +31,7 @@ unsafe impl<T> Send for Forever<T> {} | |||
| 31 | unsafe impl<T> Sync for Forever<T> {} | 31 | unsafe impl<T> Sync for Forever<T> {} |
| 32 | 32 | ||
| 33 | impl<T> Forever<T> { | 33 | impl<T> Forever<T> { |
| 34 | #[inline(always)] | ||
| 34 | pub const fn new() -> Self { | 35 | pub const fn new() -> Self { |
| 35 | Self { | 36 | Self { |
| 36 | used: AtomicBool::new(false), | 37 | used: AtomicBool::new(false), |
| @@ -43,10 +44,11 @@ impl<T> Forever<T> { | |||
| 43 | /// Panics if this `Forever` already has a value. | 44 | /// Panics if this `Forever` already has a value. |
| 44 | /// | 45 | /// |
| 45 | /// Returns a mutable reference to the stored value. | 46 | /// Returns a mutable reference to the stored value. |
| 47 | #[inline(always)] | ||
| 46 | pub fn put(&'static self, val: T) -> &'static mut T { | 48 | pub fn put(&'static self, val: T) -> &'static mut T { |
| 47 | if self | 49 | if self |
| 48 | .used | 50 | .used |
| 49 | .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire) | 51 | .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) |
| 50 | .is_err() | 52 | .is_err() |
| 51 | { | 53 | { |
| 52 | panic!("Forever.put() called multiple times"); | 54 | panic!("Forever.put() called multiple times"); |
| @@ -60,6 +62,25 @@ impl<T> Forever<T> { | |||
| 60 | } | 62 | } |
| 61 | } | 63 | } |
| 62 | 64 | ||
| 65 | #[inline(always)] | ||
| 66 | pub fn put_with(&'static self, val: impl FnOnce() -> T) -> &'static mut T { | ||
| 67 | if self | ||
| 68 | .used | ||
| 69 | .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) | ||
| 70 | .is_err() | ||
| 71 | { | ||
| 72 | panic!("Forever.put() called multiple times"); | ||
| 73 | } | ||
| 74 | |||
| 75 | unsafe { | ||
| 76 | let p = self.t.get(); | ||
| 77 | let p = (&mut *p).as_mut_ptr(); | ||
| 78 | p.write(val()); | ||
| 79 | &mut *p | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | #[inline(always)] | ||
| 63 | pub unsafe fn steal(&'static self) -> &'static mut T { | 84 | pub unsafe fn steal(&'static self) -> &'static mut T { |
| 64 | let p = self.t.get(); | 85 | let p = self.t.get(); |
| 65 | let p = (&mut *p).as_mut_ptr(); | 86 | let p = (&mut *p).as_mut_ptr(); |
