Skip to content

Commit 926503b

Browse files
committed
Remove Waitable::get_raw() and add raw_release(), raw_acquire().
1 parent ddecffe commit 926503b

File tree

3 files changed

+49
-22
lines changed

3 files changed

+49
-22
lines changed

kernel-rs/src/proc.rs

+33-13
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,22 @@ pub enum Procstate {
209209

210210
/// Represents lock guards that can be slept in a `WaitChannel`.
211211
pub trait Waitable {
212-
/// Returns a reference to the inner `RawSpinlock`.
212+
/// Releases the inner `RawSpinlock`.
213213
///
214214
/// # Safety
215215
///
216-
/// You should manually prove the correctness when directly accessing
217-
/// the inner `RawSpinlock` instead of using the lock's API.
218-
unsafe fn get_raw(&self) -> &RawSpinlock;
216+
/// `raw_release()` and `raw_acquire` must always be used as a pair.
217+
/// Use these only for temporarily releasing (and then acquiring) the lock.
218+
/// Also, do not access `self` until re-acquiring the lock with `raw_acquire()`.
219+
unsafe fn raw_release(&self);
220+
221+
/// Acquires the inner `RawSpinlock`.
222+
///
223+
/// # Safety
224+
///
225+
/// `raw_release()` and `raw_acquire` must always be used as a pair.
226+
/// Use these only for temporarily releasing (and then acquiring) the lock.
227+
unsafe fn raw_acquire(&self);
219228
}
220229

221230
pub struct WaitChannel {
@@ -231,12 +240,11 @@ impl WaitChannel {
231240

232241
/// Atomically release lock and sleep on waitchannel.
233242
/// Reacquires lock when awakened.
234-
///
235-
/// # Safety
236-
///
237-
/// Make sure `lk` is the only lock we currently hold.
238-
pub unsafe fn sleep<T: Waitable>(&self, lk: &mut T) {
239-
let p = &*myproc();
243+
pub fn sleep<T: Waitable>(&self, lk: &mut T) {
244+
let p = unsafe {
245+
// TODO: Remove this unsafe part after resolving #258
246+
&*myproc()
247+
};
240248

241249
// Must acquire p->lock in order to
242250
// change p->state and then call sched.
@@ -247,19 +255,31 @@ impl WaitChannel {
247255

248256
//DOC: sleeplock1
249257
let mut guard = p.lock();
250-
lk.get_raw().release();
258+
unsafe {
259+
// Temporarily release the inner `RawSpinlock`.
260+
// This is safe, since we don't access `lk` until re-acquiring the lock
261+
// at `lk.raw_acquire()`.
262+
lk.raw_release();
263+
}
251264

252265
// Go to sleep.
253266
guard.deref_mut_info().waitchannel = self;
254267
guard.deref_mut_info().state = Procstate::SLEEPING;
255-
guard.sched();
268+
unsafe {
269+
// Safe since we hold `p.lock()`, changed the process's state,
270+
// and device interrupts are disabled by `push_off()` in `p.lock()`.
271+
guard.sched();
272+
}
256273

257274
// Tidy up.
258275
guard.deref_mut_info().waitchannel = ptr::null();
259276

260277
// Reacquire original lock.
261278
drop(guard);
262-
lk.get_raw().acquire();
279+
unsafe {
280+
// Safe since this is paired with a previous `lk.raw_release()`.
281+
lk.raw_acquire();
282+
}
263283
}
264284

265285
/// Wake up all processes sleeping on waitchannel.

kernel-rs/src/sleepablelock.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ impl<T> Sleepablelock<T> {
6161

6262
impl<T> SleepablelockGuard<'_, T> {
6363
pub fn sleep(&mut self) {
64-
unsafe {
65-
self.lock.waitchannel.sleep(self);
66-
}
64+
self.lock.waitchannel.sleep(self);
6765
}
6866

6967
pub fn wakeup(&self) {
@@ -72,8 +70,11 @@ impl<T> SleepablelockGuard<'_, T> {
7270
}
7371

7472
impl<T> Waitable for SleepablelockGuard<'_, T> {
75-
unsafe fn get_raw(&self) -> &RawSpinlock {
76-
&self.lock.lock
73+
unsafe fn raw_release(&self) {
74+
self.lock.lock.release();
75+
}
76+
unsafe fn raw_acquire(&self) {
77+
self.lock.lock.acquire();
7778
}
7879
}
7980

kernel-rs/src/spinlock.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,11 @@ impl<T> SpinlockGuard<'_, T> {
199199
}
200200

201201
impl<T> Waitable for SpinlockGuard<'_, T> {
202-
unsafe fn get_raw(&self) -> &RawSpinlock {
203-
&self.lock.lock
202+
unsafe fn raw_release(&self) {
203+
self.lock.lock.release();
204+
}
205+
unsafe fn raw_acquire(&self) {
206+
self.lock.lock.acquire();
204207
}
205208
}
206209

@@ -265,8 +268,11 @@ impl<T> SpinlockProtected<T> {
265268
}
266269

267270
impl Waitable for SpinlockProtectedGuard<'_> {
268-
unsafe fn get_raw(&self) -> &RawSpinlock {
269-
&self.lock
271+
unsafe fn raw_release(&self) {
272+
self.lock.release();
273+
}
274+
unsafe fn raw_acquire(&self) {
275+
self.lock.acquire();
270276
}
271277
}
272278

0 commit comments

Comments
 (0)