aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-27 01:43:38 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:58 +0200
commit4ce46df1603697b14f2446b33663a122dda4a468 (patch)
tree6fa5baf46d53f25aed4b7b810a9f82d0cf924088
parent7a41541ab279e200b7bda93704e8ba66df52f5b4 (diff)
Code size optimizations.
-rw-r--r--embassy-extras/src/peripheral.rs8
-rw-r--r--embassy-extras/src/peripheral_shared.rs5
-rw-r--r--embassy-macros/src/lib.rs10
-rw-r--r--embassy/src/executor/raw.rs6
-rw-r--r--embassy/src/interrupt.rs14
-rw-r--r--embassy/src/util/forever.rs23
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 @@
1use core::cell::UnsafeCell; 1use core::cell::UnsafeCell;
2use core::marker::{PhantomData, PhantomPinned}; 2use core::marker::{PhantomData, PhantomPinned};
3use core::pin::Pin; 3use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering};
5 4
6use embassy::interrupt::{Interrupt, InterruptExt}; 5use 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 @@
1use core::cell::UnsafeCell; 1use core::cell::UnsafeCell;
2use core::marker::{PhantomData, PhantomPinned}; 2use core::marker::{PhantomData, PhantomPinned};
3use core::pin::Pin; 3use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering};
5 4
6use embassy::interrupt::{Interrupt, InterruptExt}; 5use 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;
4use core::future::Future; 4use core::future::Future;
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6use core::pin::Pin; 6use core::pin::Pin;
7use core::ptr;
8use core::ptr::NonNull; 7use core::ptr::NonNull;
9use core::task::{Context, Poll, Waker}; 8use core::task::{Context, Poll, Waker};
9use core::{mem, ptr};
10 10
11use super::run_queue::{RunQueue, RunQueueItem}; 11use super::run_queue::{RunQueue, RunQueueItem};
12use super::timer_queue::{TimerQueue, TimerQueueItem}; 12use 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 @@
1use core::ptr; 1use core::ptr;
2use cortex_m::peripheral::NVIC; 2use cortex_m::peripheral::NVIC;
3 3
4use atomic_polyfill::{AtomicPtr, Ordering}; 4use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
5 5
6pub use embassy_macros::interrupt_declare as declare; 6pub use embassy_macros::interrupt_declare as declare;
7pub use embassy_macros::interrupt_take as take; 7pub use embassy_macros::interrupt_take as take;
@@ -58,22 +58,27 @@ pub trait InterruptExt: Interrupt {
58 58
59impl<T: Interrupt + ?Sized> InterruptExt for T { 59impl<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> {}
31unsafe impl<T> Sync for Forever<T> {} 31unsafe impl<T> Sync for Forever<T> {}
32 32
33impl<T> Forever<T> { 33impl<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();