From 4edd99fd13d04431247b873053c773a6970a8edd Mon Sep 17 00:00:00 2001 From: Klim Tsoutsman Date: Sun, 25 Dec 2022 23:46:13 +1100 Subject: [PATCH] Modify `test_task_cancel` to generate LSDA for `guard_holder` Signed-off-by: Klim Tsoutsman --- applications/test_task_cancel/src/lib.rs | 31 ++++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/applications/test_task_cancel/src/lib.rs b/applications/test_task_cancel/src/lib.rs index 5f135d3d25..64b6fce4ce 100644 --- a/applications/test_task_cancel/src/lib.rs +++ b/applications/test_task_cancel/src/lib.rs @@ -5,12 +5,12 @@ extern crate alloc; use alloc::{string::String, sync::Arc, vec::Vec}; -use core::sync::atomic::{AtomicUsize, Ordering}; +use core::sync::atomic::{AtomicBool, Ordering::Relaxed}; use spin::Mutex; pub fn main(_: Vec) -> isize { let lock = Arc::new(Mutex::new(())); - let task = spawn::new_task_builder(other, lock.clone()) + let task = spawn::new_task_builder(guard_hog, lock.clone()) .spawn() .expect("failed to spawn task"); @@ -29,21 +29,26 @@ pub fn main(_: Vec) -> isize { } #[inline(never)] -fn other(lock: Arc>) { +fn guard_hog(lock: Arc>) { let _guard = lock.lock(); loop { - // In order to properly unwind the task we need to reach an instruction that is - // covered by the unwind tables. Rust generates an unwind row for all call - // sites so by placing a call site in the loop we ensure that the task will - // reach an instruction from which it can unwind when it is told to cancel. - unwind_row_generator(); + // We cannot inline the load of FALSE into this function as then LLVM will + // generate an unwind row that covers the entire function, but a call site table + // that only covers the instructions associated with the panic, which we would + // never reach. + lsda_generator(); } } #[inline(never)] -fn unwind_row_generator() { - static __COUNTER: AtomicUsize = AtomicUsize::new(0); - - // Prevents unwind_row_generator from being optimised away. - __COUNTER.fetch_add(1, Ordering::Relaxed); +fn lsda_generator() { + static FALSE: AtomicBool = AtomicBool::new(false); + + // We need to give LLVM false hope that lsda_generator may unwind. Otherwise, + // LLVM will generate an unwind row, but no LSDA for guard_holder. + // + // The potential panic also prevents lsda_generator from being optimised away. + if FALSE.load(Relaxed) { + panic!(); + } }