Still a lot of bugs :(

This commit is contained in:
Yifan Wu 2022-03-04 09:02:32 -08:00
parent 704eae3bb0
commit 26f44233f6
27 changed files with 308 additions and 95 deletions

View file

@ -1,9 +1,9 @@
use crate::sync::{Mutex, UPSafeCell};
use crate::task::{add_task, block_current_and_run_next, current_task, TaskControlBlock};
use crate::sync::{Mutex, UPIntrFreeCell};
use crate::task::{add_task, block_current_task, block_current_and_run_next, current_task, TaskControlBlock, TaskContext};
use alloc::{collections::VecDeque, sync::Arc};
pub struct Condvar {
pub inner: UPSafeCell<CondvarInner>,
pub inner: UPIntrFreeCell<CondvarInner>,
}
pub struct CondvarInner {
@ -14,7 +14,7 @@ impl Condvar {
pub fn new() -> Self {
Self {
inner: unsafe {
UPSafeCell::new(CondvarInner {
UPIntrFreeCell::new(CondvarInner {
wait_queue: VecDeque::new(),
})
},
@ -35,6 +35,13 @@ impl Condvar {
block_current_and_run_next();
}
pub fn wait_no_sched(&self) -> *mut TaskContext {
self.inner.exclusive_session(|inner| {
inner.wait_queue.push_back(current_task().unwrap());
});
block_current_task()
}
pub fn wait_with_mutex(&self, mutex: Arc<dyn Mutex>) {
mutex.unlock();
let mut inner = self.inner.exclusive_access();

View file

@ -6,4 +6,4 @@ mod up;
pub use condvar::Condvar;
pub use mutex::{Mutex, MutexBlocking, MutexSpin};
pub use semaphore::Semaphore;
pub use up::UPSafeCell;
pub use up::{UPIntrFreeCell, UPIntrRefMut};

View file

@ -1,4 +1,4 @@
use super::UPSafeCell;
use super::UPIntrFreeCell;
use crate::task::TaskControlBlock;
use crate::task::{add_task, current_task};
use crate::task::{block_current_and_run_next, suspend_current_and_run_next};
@ -10,13 +10,13 @@ pub trait Mutex: Sync + Send {
}
pub struct MutexSpin {
locked: UPSafeCell<bool>,
locked: UPIntrFreeCell<bool>,
}
impl MutexSpin {
pub fn new() -> Self {
Self {
locked: unsafe { UPSafeCell::new(false) },
locked: unsafe { UPIntrFreeCell::new(false) },
}
}
}
@ -43,7 +43,7 @@ impl Mutex for MutexSpin {
}
pub struct MutexBlocking {
inner: UPSafeCell<MutexBlockingInner>,
inner: UPIntrFreeCell<MutexBlockingInner>,
}
pub struct MutexBlockingInner {
@ -55,7 +55,7 @@ impl MutexBlocking {
pub fn new() -> Self {
Self {
inner: unsafe {
UPSafeCell::new(MutexBlockingInner {
UPIntrFreeCell::new(MutexBlockingInner {
locked: false,
wait_queue: VecDeque::new(),
})

View file

@ -1,9 +1,9 @@
use crate::sync::UPSafeCell;
use crate::sync::UPIntrFreeCell;
use crate::task::{add_task, block_current_and_run_next, current_task, TaskControlBlock};
use alloc::{collections::VecDeque, sync::Arc};
pub struct Semaphore {
pub inner: UPSafeCell<SemaphoreInner>,
pub inner: UPIntrFreeCell<SemaphoreInner>,
}
pub struct SemaphoreInner {
@ -15,7 +15,7 @@ impl Semaphore {
pub fn new(res_count: usize) -> Self {
Self {
inner: unsafe {
UPSafeCell::new(SemaphoreInner {
UPIntrFreeCell::new(SemaphoreInner {
count: res_count as isize,
wait_queue: VecDeque::new(),
})

View file

@ -1,4 +1,7 @@
use core::cell::{RefCell, RefMut};
use core::cell::{RefCell, RefMut, UnsafeCell};
use core::ops::{Deref, DerefMut};
use riscv::register::sstatus;
use lazy_static::*;
/// Wrap a static data structure inside it so that we are
/// able to access it without any `unsafe`.
@ -27,3 +30,103 @@ impl<T> UPSafeCell<T> {
self.inner.borrow_mut()
}
}
pub struct UPSafeCellRaw<T> {
inner: UnsafeCell<T>,
}
unsafe impl<T> Sync for UPSafeCellRaw<T> {}
impl<T> UPSafeCellRaw<T> {
pub unsafe fn new(value: T) -> Self {
Self {
inner: UnsafeCell::new(value),
}
}
pub fn get_mut(&self) -> &mut T {
unsafe { &mut (*self.inner.get()) }
}
}
pub struct IntrMaskingInfo {
nested_level: usize,
sie_before_masking: bool,
}
lazy_static! {
static ref INTR_MASKING_INFO: UPSafeCellRaw<IntrMaskingInfo> = unsafe {
UPSafeCellRaw::new(IntrMaskingInfo::new())
};
}
impl IntrMaskingInfo {
pub fn new() -> Self {
Self {
nested_level: 0,
sie_before_masking: false,
}
}
pub fn enter(&mut self) {
let sie = sstatus::read().sie();
unsafe { sstatus::clear_sie(); }
if self.nested_level == 0 {
self.sie_before_masking = sie;
}
self.nested_level += 1;
}
pub fn exit(&mut self) {
self.nested_level -= 1;
if self.nested_level == 0 && self.sie_before_masking {
unsafe { sstatus::set_sie(); }
}
}
}
pub struct UPIntrFreeCell<T> {
/// inner data
inner: RefCell<T>,
}
unsafe impl<T> Sync for UPIntrFreeCell<T> {}
pub struct UPIntrRefMut<'a, T>(Option<RefMut<'a, T>>);
impl<T> UPIntrFreeCell<T> {
pub unsafe fn new(value: T) -> Self {
Self {
inner: RefCell::new(value),
}
}
/// Panic if the data has been borrowed.
pub fn exclusive_access(&self) -> UPIntrRefMut<'_, T> {
INTR_MASKING_INFO.get_mut().enter();
UPIntrRefMut(Some(self.inner.borrow_mut()))
}
pub fn exclusive_session<F, V>(&self, f: F) -> V where F: FnOnce(&mut T) -> V {
let mut inner = self.exclusive_access();
f(inner.deref_mut())
}
}
impl<'a, T> Drop for UPIntrRefMut<'a, T> {
fn drop(&mut self) {
self.0 = None;
INTR_MASKING_INFO.get_mut().exit();
}
}
impl<'a, T> Deref for UPIntrRefMut<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.as_ref().unwrap().deref()
}
}
impl<'a, T> DerefMut for UPIntrRefMut<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.as_mut().unwrap().deref_mut()
}
}