Refactor sleeplock to remove raw pointers

This commit is contained in:
Garen Tyler 2023-10-29 14:12:17 -06:00
parent 36d7724fb8
commit 9f23b68c00
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
7 changed files with 34 additions and 67 deletions

View File

@ -106,8 +106,6 @@ bread(uint dev, uint blockno)
void
bwrite(struct buf *b)
{
if(!holdingsleep(&b->lock))
panic("bwrite");
virtio_disk_rw(b, 1);
}
@ -116,9 +114,6 @@ bwrite(struct buf *b)
void
brelse(struct buf *b)
{
if(!holdingsleep(&b->lock))
panic("brelse");
releasesleep(&b->lock);
acquire(&bcache.lock);

View File

@ -125,8 +125,7 @@ void pop_off(void);
// sleeplock.c
void acquiresleep(struct sleeplock*);
void releasesleep(struct sleeplock*);
int holdingsleep(struct sleeplock*);
void releasesleep(struct sleeplock *);
void initsleeplock(struct sleeplock*, char*);
// string.c

View File

@ -317,10 +317,11 @@ ilock(struct inode *ip)
}
// Unlock the given inode.
// Caller should hold ip->lock
void
iunlock(struct inode *ip)
{
if(ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1)
if (ip == 0 || ip->ref < 1)
panic("iunlock");
releasesleep(&ip->lock);

View File

@ -16,11 +16,10 @@ void ramdiskinit(void);
// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
// Else if B_VALID is not set, read buf from disk, set B_VALID.
// Caller should hold b->lock
void
ramdiskrw(struct buf *b)
{
if(!holdingsleep(&b->lock))
panic("ramdiskrw: buf not locked");
if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
panic("ramdiskrw: nothing to do");

View File

@ -391,6 +391,21 @@ pub unsafe fn sleep_mutex<T>(chan: *mut c_void, mutex: &mut SpinMutexGuard<T>) {
core::mem::forget(guard);
}
/// Sleep until `wakeup(chan)` is called somewhere else.
pub unsafe fn sleep(chan: *mut c_void) {
let p = myproc();
let _guard = (*p).lock.lock();
// Go to sleep.
(*p).chan = chan;
(*p).state = ProcState::Sleeping;
sched();
// Tidy up.
(*p).chan = null_mut();
}
/// Kill the process with the given pid.
/// The victim won't exit until it tries to return
/// to user space (see usertrap() in trap.c).

View File

@ -1,53 +1,27 @@
use crate::{
proc::{myproc, sleep_lock, wakeup},
sync::spinlock::Spinlock,
};
use crate::proc::{wakeup, sleep};
use core::{
ffi::c_char,
ptr::{addr_of, null_mut},
ptr::addr_of,
sync::atomic::{AtomicBool, Ordering},
};
#[repr(C)]
#[derive(Default)]
pub struct Sleeplock {
pub locked: u32,
pub inner: Spinlock,
pub name: *mut c_char,
pub pid: i32,
pub locked: AtomicBool,
}
impl Sleeplock {
pub const unsafe fn uninitialized() -> Sleeplock {
pub const fn new() -> Sleeplock {
Sleeplock {
locked: 0,
inner: Spinlock::new(),
name: null_mut(),
pid: 0,
locked: AtomicBool::new(false),
}
}
/// Initializes a `Sleeplock`.
pub const fn new(name: *mut c_char) -> Sleeplock {
Sleeplock {
locked: 0,
inner: Spinlock::new(),
name,
pid: 0,
}
}
/// Check whether this proc is holding the lock.
pub fn held_by_current_proc(&self) -> bool {
self.locked > 0 && self.pid == unsafe { (*myproc()).pid }
}
#[allow(clippy::while_immutable_condition)]
pub unsafe fn lock_unguarded(&self) {
let _guard = self.inner.lock();
while self.locked > 0 {
sleep_lock(
addr_of!(*self).cast_mut().cast(),
addr_of!(self.inner).cast_mut().cast(),
);
while self.locked.swap(true, Ordering::Acquire) {
// Put the process to sleep until it gets released.
sleep(addr_of!(*self).cast_mut().cast());
}
let this: &mut Self = &mut *addr_of!(*self).cast_mut();
this.locked = 1;
this.pid = (*myproc()).pid;
}
pub fn lock(&self) -> SleeplockGuard<'_> {
unsafe {
@ -56,10 +30,7 @@ impl Sleeplock {
SleeplockGuard { lock: self }
}
pub unsafe fn unlock(&self) {
let _guard = self.inner.lock();
let this: &mut Self = &mut *addr_of!(*self).cast_mut();
this.locked = 0;
this.pid = 0;
self.locked.store(false, Ordering::Release);
wakeup(addr_of!(*self).cast_mut().cast());
}
}
@ -74,8 +45,8 @@ impl<'l> Drop for SleeplockGuard<'l> {
}
#[no_mangle]
pub unsafe extern "C" fn initsleeplock(lock: *mut Sleeplock, name: *mut c_char) {
(*lock) = Sleeplock::new(name);
pub unsafe extern "C" fn initsleeplock(lock: *mut Sleeplock, _name: *mut c_char) {
(*lock) = Sleeplock::new();
}
#[no_mangle]
@ -87,12 +58,3 @@ pub unsafe extern "C" fn acquiresleep(lock: *mut Sleeplock) {
pub unsafe extern "C" fn releasesleep(lock: *mut Sleeplock) {
(*lock).unlock();
}
#[no_mangle]
pub unsafe extern "C" fn holdingsleep(lock: *mut Sleeplock) -> i32 {
if (*lock).held_by_current_proc() {
1
} else {
0
}
}

View File

@ -4,11 +4,7 @@
// Long-term locks for processes
struct sleeplock {
uint locked; // Is the lock held?
struct spinlock lk; // spinlock protecting this sleep lock
// For debugging:
char *name; // Name of lock.
int pid; // Process holding lock
// Is the lock held?
uint8 locked;
};