context.rs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #[doc(notable_trait)]
  2. pub trait RawTaskContext: Sized {
  3. /// Creates a new instance of the task context with interrupt enabled and the program
  4. /// counter and stack pointer set to zero (a.k.a. some invalid state).
  5. ///
  6. /// Using the created context without setting the program counter and stack pointer
  7. /// will result in undefined behavior.
  8. fn new() -> Self;
  9. fn set_program_counter(&mut self, pc: usize);
  10. fn set_stack_pointer(&mut self, sp: usize);
  11. fn is_interrupt_enabled(&self) -> bool;
  12. fn set_interrupt_enabled(&mut self, is_enabled: bool);
  13. /// Sets the instruction pointer to the given function and prepares the context
  14. /// to call it with the given argument.
  15. fn call(&mut self, func: unsafe extern "C" fn(usize) -> !, arg: usize);
  16. /// Switch the execution context from `from` to `to`.
  17. ///
  18. /// # Safety
  19. /// This function is unsafe because it performs a context switch, which can lead to
  20. /// undefined behavior if the contexts are not properly set up.
  21. unsafe extern "C" fn switch(from: &mut Self, to: &mut Self);
  22. /// Switches the execution context to `to` where we will not return.
  23. ///
  24. /// # Safety
  25. /// This function is unsafe because it performs a context switch that does not return.
  26. /// The caller must ensure that the `to` context is properly set up and that it will not
  27. /// return to the caller.
  28. unsafe extern "C" fn switch_to_noreturn(to: &mut Self) -> ! {
  29. let mut from_ctx = Self::new();
  30. unsafe {
  31. Self::switch(&mut from_ctx, to);
  32. }
  33. unreachable!("We should never return from `switch_to_noreturn()`");
  34. }
  35. }