mirror of
https://github.com/trussed-dev/ctaphid-dispatch.git
synced 2026-06-20 04:16:18 -07:00
Optimize stack usage of Dispatch::poll
Dispatch::poll has to copy the request so that the app can write the response to the interchange. Previously, we called Responder::take_request to obtain the message out of the interchange. This implementation had a stack usage of 15280 bytes while the message size is only 7609 bytes. With this patch, we only request a reference from the responder and manually copy the message to a buffer. This reduces the stack size to 7664 bytes. I have no idea why the take_request implementation creates an additional copy of the message. But as this function is the root for all CTAPHID commands, this means we can save around 7 kB stack virtually everywhere. Similar optimizations may be possible in other functions too.
This commit is contained in:
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
- Optimize stack usage of `Dispatch::poll`
|
||||
|
||||
## [0.1.1] - 2022-08-22
|
||||
- adjust to `interchange` API change
|
||||
|
||||
+7
-4
@@ -106,14 +106,17 @@ impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
|
||||
|
||||
#[inline(never)]
|
||||
pub fn poll(&mut self, apps: &mut [&mut dyn App<'interrupt>]) -> bool {
|
||||
let maybe_request = self.responder.take_request();
|
||||
if let Some((command, message)) = maybe_request {
|
||||
// We could call take_request directly, but for some reason this doubles stack usage.
|
||||
let mut message_buffer = Message::new();
|
||||
if let Ok((command, message)) = self.responder.request() {
|
||||
// info_now!("cmd: {}", u8::from(command));
|
||||
// info_now!("cmd: {:?}", command);
|
||||
|
||||
if let Some(app) = Self::find_app(command, apps) {
|
||||
message_buffer.extend_from_slice(message).unwrap();
|
||||
|
||||
if let Some(app) = Self::find_app(*command, apps) {
|
||||
// match app.call(command, self.responder.response_mut().unwrap()) {
|
||||
self.call_app(*app, command, &message);
|
||||
self.call_app(*app, *command, &message_buffer);
|
||||
} else {
|
||||
self.reply_with_error(Error::InvalidCommand);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user