Skip to content

Commit 823ad67

Browse files
committed
rust: allow state to be saved in lock guards.
No functional changes are expected. This is in preparation for adding spinlocks that disable interrupts when locking and restore interrupt state when unlocking. We need to save the interrupt state to be stored. Signed-off-by: Wedson Almeida Filho <[email protected]>
1 parent 1ce1631 commit 823ad67

File tree

4 files changed

+22
-14
lines changed

4 files changed

+22
-14
lines changed

rust/kernel/sync/condvar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ impl CondVar {
8181
}
8282

8383
// SAFETY: The guard is evidence that the caller owns the lock.
84-
unsafe { lock.unlock() };
84+
unsafe { lock.unlock(&mut guard.context) };
8585

8686
// SAFETY: No arguments, switches to another thread.
8787
unsafe { bindings::schedule() };
8888

89-
lock.lock_noguard();
89+
guard.context = lock.lock_noguard();
9090

9191
// SAFETY: Both `wait` and `wait_list` point to valid memory.
9292
unsafe { bindings::finish_wait(self.wait_list.get(), wait.as_mut_ptr()) };

rust/kernel/sync/guard.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#[must_use = "the lock unlocks immediately when the guard is unused"]
1313
pub struct Guard<'a, L: Lock + ?Sized> {
1414
pub(crate) lock: &'a L,
15+
pub(crate) context: L::GuardContext,
1516
}
1617

1718
// SAFETY: `Guard` is sync when the data protected by the lock is also sync. This is more
@@ -44,7 +45,7 @@ impl<L: Lock + ?Sized> core::ops::DerefMut for Guard<'_, L> {
4445
impl<L: Lock + ?Sized> Drop for Guard<'_, L> {
4546
fn drop(&mut self) {
4647
// SAFETY: The caller owns the lock, so it is safe to unlock it.
47-
unsafe { self.lock.unlock() };
48+
unsafe { self.lock.unlock(&mut self.context) };
4849
}
4950
}
5051

@@ -54,8 +55,8 @@ impl<'a, L: Lock + ?Sized> Guard<'a, L> {
5455
/// # Safety
5556
///
5657
/// The caller must ensure that it owns the lock.
57-
pub(crate) unsafe fn new(lock: &'a L) -> Self {
58-
Self { lock }
58+
pub(crate) unsafe fn new(lock: &'a L, context: L::GuardContext) -> Self {
59+
Self { lock, context }
5960
}
6061
}
6162

@@ -67,15 +68,18 @@ pub trait Lock {
6768
/// The type of the data protected by the lock.
6869
type Inner: ?Sized;
6970

71+
/// The type of context, if any, that needs to be stored in the guard.
72+
type GuardContext;
73+
7074
/// Acquires the lock, making the caller its owner.
71-
fn lock_noguard(&self);
75+
fn lock_noguard(&self) -> Self::GuardContext;
7276

7377
/// Releases the lock, giving up ownership of the lock.
7478
///
7579
/// # Safety
7680
///
7781
/// It must only be called by the current owner of the lock.
78-
unsafe fn unlock(&self);
82+
unsafe fn unlock(&self, context: &mut Self::GuardContext);
7983

8084
/// Returns the data protected by the lock.
8185
fn locked_data(&self) -> &core::cell::UnsafeCell<Self::Inner>;

rust/kernel/sync/mutex.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<T: ?Sized> Mutex<T> {
6767
pub fn lock(&self) -> Guard<'_, Self> {
6868
self.lock_noguard();
6969
// SAFETY: The mutex was just acquired.
70-
unsafe { Guard::new(self) }
70+
unsafe { Guard::new(self, ()) }
7171
}
7272
}
7373

@@ -83,15 +83,16 @@ extern "C" {
8383

8484
impl<T: ?Sized> Lock for Mutex<T> {
8585
type Inner = T;
86+
type GuardContext = ();
8687

8788
fn lock_noguard(&self) {
8889
// SAFETY: `mutex` points to valid memory.
89-
unsafe {
90-
rust_helper_mutex_lock(self.mutex.get());
91-
}
90+
unsafe { rust_helper_mutex_lock(self.mutex.get()) };
9291
}
9392

94-
unsafe fn unlock(&self) {
93+
unsafe fn unlock(&self, _: &mut ()) {
94+
// SAFETY: The safety requirements of the function ensure that the mutex is owned by the
95+
// caller.
9596
unsafe { bindings::mutex_unlock(self.mutex.get()) };
9697
}
9798

rust/kernel/sync/spinlock.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<T: ?Sized> SpinLock<T> {
8181
pub fn lock(&self) -> Guard<'_, Self> {
8282
self.lock_noguard();
8383
// SAFETY: The spinlock was just acquired.
84-
unsafe { Guard::new(self) }
84+
unsafe { Guard::new(self, ()) }
8585
}
8686
}
8787

@@ -93,13 +93,16 @@ impl<T: ?Sized> NeedsLockClass for SpinLock<T> {
9393

9494
impl<T: ?Sized> Lock for SpinLock<T> {
9595
type Inner = T;
96+
type GuardContext = ();
9697

9798
fn lock_noguard(&self) {
9899
// SAFETY: `spin_lock` points to valid memory.
99100
unsafe { rust_helper_spin_lock(self.spin_lock.get()) };
100101
}
101102

102-
unsafe fn unlock(&self) {
103+
unsafe fn unlock(&self, _: &mut ()) {
104+
// SAFETY: The safety requirements of the function ensure that the spinlock is owned by the
105+
// caller.
103106
unsafe { rust_helper_spin_unlock(self.spin_lock.get()) };
104107
}
105108

0 commit comments

Comments
 (0)