From 87f729e1e048672fab6b0b4e3780586605e83412 Mon Sep 17 00:00:00 2001 From: Shaw Drastin <168159404+showier-drastic@users.noreply.github.com> Date: Thu, 12 Dec 2024 20:09:57 +0800 Subject: [PATCH] receive_any: Use trailing_zeros to improve performance In current code, `receive_any` needs to do loop operation to iterate over memory buffer to check whether there's new data which can consume a lot of CPU time. This code changes this operation to use `trailing_zeros` to get the first available message directly from NDAT register without any loops. --- mcan/CHANGELOG.md | 1 + mcan/src/rx_dedicated_buffers.rs | 17 ++++++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/mcan/CHANGELOG.md b/mcan/CHANGELOG.md index 4210429..2a221ea 100644 --- a/mcan/CHANGELOG.md +++ b/mcan/CHANGELOG.md @@ -3,6 +3,7 @@ Tagging in git follows a pattern: `mcan/`. ## [Unreleased] +- Improve performance of RxDedicatedBuffer::receive_any (#50) ## [0.5.0] - 2024-03-04 diff --git a/mcan/src/rx_dedicated_buffers.rs b/mcan/src/rx_dedicated_buffers.rs index 0970ef2..f17ff79 100644 --- a/mcan/src/rx_dedicated_buffers.rs +++ b/mcan/src/rx_dedicated_buffers.rs @@ -124,17 +124,12 @@ impl<'a, P: mcan_core::CanId, M: rx::AnyMessage> DynRxDedicatedBuffer } fn receive_any(&mut self) -> nb::Result { - self.memory - .iter() - .enumerate() - .filter(|&(i, _)| self.has_new_data(i)) - .map(|(i, m)| (i, m.get())) - .min_by_key(|(_, m)| m.id()) - .map(|(i, m)| { - self.mark_buffer_read(i); - m - }) - .ok_or(nb::Error::WouldBlock) + let ndat = + (self.ndat1().read().bits() as u64) | ((self.ndat2().read().bits() as u64) << 32); + let idx = ndat.trailing_zeros() as usize; + let m = self.memory.get(idx).ok_or(nb::Error::WouldBlock)?; + self.mark_buffer_read(idx); + Ok(m.get()) } }