From 66b94538461516f4e6fb136ec1f2751d921c484b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 12 Feb 2024 09:50:19 -0800 Subject: [PATCH] gimlet-seq: Die more politely (#1611) Sleeping for 100ms in a loop is not a particularly efficient way for a task to die permanently. Thanks to suggestions from @labbott and @cbiffle, I've changed this so that the sequencer task now dies by waiting for a notification with an empty notification mask, essentially waiting forever for a notification that should never happen. This is much more respectful of other tasks that might still be trying to do stuff, and would like to be scheduled to do that stuff. Also, I've cleaned up a couple other things based on some of Cliff's suggestions. Because we no longer set the state when dying, we can pass the `jefe` handle into `init` by value, which is a bit nicer. --- drv/gimlet-seq-server/src/main.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drv/gimlet-seq-server/src/main.rs b/drv/gimlet-seq-server/src/main.rs index 1b65033e8..0be4fe694 100644 --- a/drv/gimlet-seq-server/src/main.rs +++ b/drv/gimlet-seq-server/src/main.rs @@ -120,7 +120,7 @@ fn main() -> ! { let jefe = Jefe::from(JEFE.get_task_id()); let spi = drv_spi_api::Spi::from(SPI.get_task_id()); let hf = hf_api::HostFlash::from(HF.get_task_id()); - match ServerImpl::init(&sys, &jefe, spi, hf) { + match ServerImpl::init(&sys, jefe, spi, hf) { // Set up everything nicely, time to start serving incoming messages. Ok(mut server) => { let mut buffer = [0; idl::INCOMING_SIZE]; @@ -138,7 +138,16 @@ fn main() -> ! { // All these moments will be lost in time, like tears in rain... // Time to die. loop { - hl::sleep_for(100); + // Sleeping with all bits in the notification mask clear means + // we should never be notified --- and if one never wakes up, + // the difference between sleeping and dying seems kind of + // irrelevant. But, `rustc` doesn't realize that this should + // never return, we'll stick it in a `loop` anyway so the main + // function can return `!` + // + // We don't care if this returns an error, because we're just + // doing it to die as politely as possible. + let _ = sys_recv_closed(&mut [], 0, TaskId::KERNEL); } } } @@ -158,7 +167,7 @@ const TIMER_INTERVAL: u64 = 10; impl ServerImpl { fn init( sys: &sys_api::Sys, - jefe: &Jefe, + jefe: Jefe, spi: S, hf: hf_api::HostFlash, ) -> Result { @@ -435,7 +444,7 @@ impl ServerImpl { state: PowerState::A2, sys: sys.clone(), seq, - jefe: jefe.clone(), + jefe, hf, deadline: 0, };