lib.rs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #![no_std]
  2. use core::{
  3. ops::{Deref, DerefMut},
  4. sync::atomic::{compiler_fence, Ordering},
  5. };
  6. pub struct PreemptGuard<T>
  7. where
  8. T: ?Sized,
  9. {
  10. value: T,
  11. }
  12. #[eonix_percpu::define_percpu]
  13. static PREEMPT_COUNT: usize = 0;
  14. #[inline(always)]
  15. pub fn disable() {
  16. PREEMPT_COUNT.add(1);
  17. compiler_fence(Ordering::AcqRel);
  18. }
  19. #[inline(always)]
  20. pub fn enable() {
  21. compiler_fence(Ordering::AcqRel);
  22. PREEMPT_COUNT.sub(1);
  23. }
  24. #[inline(always)]
  25. pub fn count() -> usize {
  26. PREEMPT_COUNT.get()
  27. }
  28. #[macro_export]
  29. macro_rules! assert_preempt_enabled {
  30. () => {{
  31. assert_eq!($crate::count(), 0, "Preemption is not enabled",);
  32. }};
  33. ($msg:literal) => {{
  34. assert_eq!($crate::count(), 0, "{}: Preemption is not enabled", $msg,);
  35. }};
  36. }
  37. #[macro_export]
  38. macro_rules! assert_preempt_disabled {
  39. () => {{
  40. assert_ne!($crate::count(), 0, "Preemption is not disabled",);
  41. }};
  42. ($msg:literal) => {{
  43. assert_ne!($crate::count(), 0, "{}: Preemption is not disabled", $msg,);
  44. }};
  45. }
  46. #[macro_export]
  47. macro_rules! assert_preempt_count_eq {
  48. ($n:expr) => {{
  49. assert_eq!(
  50. $crate::count(),
  51. $n,
  52. "Preemption count does not equal to {}",
  53. $n,
  54. );
  55. }};
  56. ($n:expr, $msg:literal) => {{
  57. assert_eq!(
  58. $crate::count(),
  59. $n,
  60. "{}: Preemption count does not equal to {}",
  61. $msg,
  62. $n,
  63. );
  64. }};
  65. }
  66. impl<T> PreemptGuard<T> {
  67. pub fn new(value: T) -> Self {
  68. disable();
  69. Self { value }
  70. }
  71. }
  72. impl<T> Deref for PreemptGuard<T>
  73. where
  74. T: ?Sized,
  75. {
  76. type Target = T;
  77. fn deref(&self) -> &Self::Target {
  78. &self.value
  79. }
  80. }
  81. impl<T> DerefMut for PreemptGuard<T>
  82. where
  83. T: ?Sized,
  84. {
  85. fn deref_mut(&mut self) -> &mut Self::Target {
  86. &mut self.value
  87. }
  88. }
  89. impl<T> Drop for PreemptGuard<T>
  90. where
  91. T: ?Sized,
  92. {
  93. fn drop(&mut self) {
  94. enable();
  95. }
  96. }