spin_irq.rs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. use eonix_hal::traits::trap::IrqState as _;
  2. use eonix_hal::trap::{disable_irqs_save, IrqState};
  3. use eonix_spin::{ContextUnlock, Spin, SpinContext, SpinGuard, UnlockedContext};
  4. use eonix_sync_base::Relax;
  5. pub struct IrqContext(IrqState);
  6. pub struct UnlockedIrqContext(IrqState);
  7. pub trait SpinIrq {
  8. type Value: ?Sized;
  9. type Context: SpinContext;
  10. type Relax;
  11. fn lock_irq(&self) -> SpinGuard<'_, Self::Value, Self::Context, Self::Relax>;
  12. }
  13. impl SpinContext for IrqContext {
  14. fn save() -> Self {
  15. IrqContext(disable_irqs_save())
  16. }
  17. fn restore(self) {
  18. self.0.restore();
  19. }
  20. }
  21. impl ContextUnlock for IrqContext {
  22. type Unlocked = UnlockedIrqContext;
  23. fn unlock(self) -> Self::Unlocked {
  24. UnlockedIrqContext(self.0)
  25. }
  26. }
  27. impl UnlockedContext for UnlockedIrqContext {
  28. type Relocked = IrqContext;
  29. fn relock(self) -> Self::Relocked {
  30. IrqContext(self.0)
  31. }
  32. }
  33. impl<T, R> SpinIrq for Spin<T, R>
  34. where
  35. T: ?Sized,
  36. R: Relax,
  37. {
  38. type Value = T;
  39. type Context = IrqContext;
  40. type Relax = R;
  41. fn lock_irq(&self) -> SpinGuard<'_, Self::Value, Self::Context, Self::Relax> {
  42. self.lock_with_context(IrqContext::save())
  43. }
  44. }